1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/media/history/media_history_store.h"
6
7 #include "base/optional.h"
8 #include "base/run_loop.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/task/post_task.h"
12 #include "base/test/bind.h"
13 #include "base/test/scoped_feature_list.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/media/feeds/media_feeds_service.h"
16 #include "chrome/browser/media/feeds/media_feeds_service_factory.h"
17 #include "chrome/browser/media/history/media_history_feed_items_table.h"
18 #include "chrome/browser/media/history/media_history_feeds_table.h"
19 #include "chrome/browser/media/history/media_history_images_table.h"
20 #include "chrome/browser/media/history/media_history_keyed_service.h"
21 #include "chrome/browser/media/history/media_history_keyed_service_factory.h"
22 #include "chrome/browser/media/history/media_history_origin_table.h"
23 #include "chrome/browser/media/history/media_history_session_images_table.h"
24 #include "chrome/browser/media/history/media_history_session_table.h"
25 #include "chrome/browser/media/history/media_history_test_utils.h"
26 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/ui/browser.h"
28 #include "chrome/test/base/in_process_browser_test.h"
29 #include "chrome/test/base/ui_test_utils.h"
30 #include "components/history/core/common/pref_names.h"
31 #include "components/prefs/pref_service.h"
32 #include "content/public/browser/browsing_data_filter_builder.h"
33 #include "content/public/browser/context_menu_params.h"
34 #include "content/public/browser/media_session.h"
35 #include "content/public/test/browser_test.h"
36 #include "content/public/test/browsing_data_remover_test_util.h"
37 #include "content/public/test/test_utils.h"
38 #include "media/base/media_switches.h"
39 #include "net/dns/mock_host_resolver.h"
40 #include "services/media_session/public/cpp/media_metadata.h"
41 #include "services/media_session/public/cpp/test/mock_media_session.h"
42
43 namespace media_history {
44
45 namespace {
46
47 constexpr base::TimeDelta kTestClipDuration =
48 base::TimeDelta::FromMilliseconds(26771);
49
50 enum class TestState {
51 kNormal,
52
53 // Runs the test in incognito mode.
54 kIncognito,
55
56 // Runs the test with the "SavingBrowserHistoryDisabled" policy enabled.
57 kSavingBrowserHistoryDisabled,
58 };
59
60 } // namespace
61
62 // Runs the test with a param to signify the profile being incognito if true.
63 class MediaHistoryBrowserTest : public InProcessBrowserTest,
64 public testing::WithParamInterface<TestState> {
65 public:
66 MediaHistoryBrowserTest() = default;
67 ~MediaHistoryBrowserTest() override = default;
68
SetUp()69 void SetUp() override {
70 scoped_feature_list_.InitWithFeatures(
71 {media::kUseMediaHistoryStore, media::kMediaFeeds}, {});
72
73 InProcessBrowserTest::SetUp();
74 }
75
SetUpOnMainThread()76 void SetUpOnMainThread() override {
77 host_resolver()->AddRule("*", "127.0.0.1");
78 ASSERT_TRUE(embedded_test_server()->Start());
79
80 InProcessBrowserTest::SetUpOnMainThread();
81 }
82
SetupPageAndStartPlaying(Browser * browser,const GURL & url)83 static bool SetupPageAndStartPlaying(Browser* browser, const GURL& url) {
84 ui_test_utils::NavigateToURL(browser, url);
85
86 bool played = false;
87 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
88 browser->tab_strip_model()->GetActiveWebContents(),
89 "attemptPlayVideo();", &played));
90 return played;
91 }
92
SetupPageAndStartPlayingAudioOnly(Browser * browser,const GURL & url)93 static bool SetupPageAndStartPlayingAudioOnly(Browser* browser,
94 const GURL& url) {
95 ui_test_utils::NavigateToURL(browser, url);
96
97 bool played = false;
98 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
99 browser->tab_strip_model()->GetActiveWebContents(),
100 "attemptPlayAudioOnly();", &played));
101 return played;
102 }
103
SetupPageAndStartPlayingVideoOnly(Browser * browser,const GURL & url)104 static bool SetupPageAndStartPlayingVideoOnly(Browser* browser,
105 const GURL& url) {
106 ui_test_utils::NavigateToURL(browser, url);
107
108 bool played = false;
109 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
110 browser->tab_strip_model()->GetActiveWebContents(),
111 "attemptPlayVideoOnly();", &played));
112 return played;
113 }
114
SetMediaMetadata(Browser * browser)115 static bool SetMediaMetadata(Browser* browser) {
116 return content::ExecuteScript(
117 browser->tab_strip_model()->GetActiveWebContents(),
118 "setMediaMetadata();");
119 }
120
SetMediaMetadataWithArtwork(Browser * browser)121 static bool SetMediaMetadataWithArtwork(Browser* browser) {
122 return content::ExecuteScript(
123 browser->tab_strip_model()->GetActiveWebContents(),
124 "setMediaMetadataWithArtwork();");
125 }
126
FinishPlaying(Browser * browser)127 static bool FinishPlaying(Browser* browser) {
128 return content::ExecuteScript(
129 browser->tab_strip_model()->GetActiveWebContents(), "finishPlaying();");
130 }
131
WaitForSignificantPlayback(Browser * browser)132 static bool WaitForSignificantPlayback(Browser* browser) {
133 bool seeked = false;
134 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
135 browser->tab_strip_model()->GetActiveWebContents(),
136 "waitForSignificantPlayback();", &seeked));
137 return seeked;
138 }
139
140 static std::vector<mojom::MediaHistoryPlaybackSessionRowPtr>
GetPlaybackSessionsSync(MediaHistoryKeyedService * service,int max_sessions)141 GetPlaybackSessionsSync(MediaHistoryKeyedService* service, int max_sessions) {
142 return GetPlaybackSessionsSync(
143 service, max_sessions,
144 base::BindRepeating([](const base::TimeDelta& duration,
145 const base::TimeDelta& position) {
146 return duration.InSeconds() != position.InSeconds();
147 }));
148 }
149
150 static std::vector<mojom::MediaHistoryPlaybackSessionRowPtr>
GetPlaybackSessionsSync(MediaHistoryKeyedService * service,int max_sessions,MediaHistoryStore::GetPlaybackSessionsFilter filter)151 GetPlaybackSessionsSync(MediaHistoryKeyedService* service,
152 int max_sessions,
153 MediaHistoryStore::GetPlaybackSessionsFilter filter) {
154 base::RunLoop run_loop;
155 std::vector<mojom::MediaHistoryPlaybackSessionRowPtr> out;
156
157 service->GetPlaybackSessions(
158 max_sessions, std::move(filter),
159 base::BindLambdaForTesting(
160 [&](std::vector<mojom::MediaHistoryPlaybackSessionRowPtr>
161 sessions) {
162 out = std::move(sessions);
163 run_loop.Quit();
164 }));
165
166 run_loop.Run();
167 return out;
168 }
169
GetStatsSync(MediaHistoryKeyedService * service)170 static mojom::MediaHistoryStatsPtr GetStatsSync(
171 MediaHistoryKeyedService* service) {
172 base::RunLoop run_loop;
173 mojom::MediaHistoryStatsPtr stats_out;
174
175 service->GetMediaHistoryStats(
176 base::BindLambdaForTesting([&](mojom::MediaHistoryStatsPtr stats) {
177 stats_out = std::move(stats);
178 run_loop.Quit();
179 }));
180
181 run_loop.Run();
182 return stats_out;
183 }
184
GetPlaybacksSync(MediaHistoryKeyedService * service)185 static std::vector<mojom::MediaHistoryPlaybackRowPtr> GetPlaybacksSync(
186 MediaHistoryKeyedService* service) {
187 base::RunLoop run_loop;
188 std::vector<mojom::MediaHistoryPlaybackRowPtr> out;
189
190 service->GetMediaHistoryPlaybackRowsForDebug(base::BindLambdaForTesting(
191 [&](std::vector<mojom::MediaHistoryPlaybackRowPtr> playbacks) {
192 out = std::move(playbacks);
193 run_loop.Quit();
194 }));
195
196 run_loop.Run();
197 return out;
198 }
199
GetOriginsSync(MediaHistoryKeyedService * service)200 static std::vector<mojom::MediaHistoryOriginRowPtr> GetOriginsSync(
201 MediaHistoryKeyedService* service) {
202 base::RunLoop run_loop;
203 std::vector<mojom::MediaHistoryOriginRowPtr> out;
204
205 service->GetOriginRowsForDebug(base::BindLambdaForTesting(
206 [&](std::vector<mojom::MediaHistoryOriginRowPtr> origins) {
207 out = std::move(origins);
208 run_loop.Quit();
209 }));
210
211 run_loop.Run();
212 return out;
213 }
214
GetExpectedMetadata()215 media_session::MediaMetadata GetExpectedMetadata() {
216 media_session::MediaMetadata expected_metadata =
217 GetExpectedDefaultMetadata();
218 expected_metadata.title = base::ASCIIToUTF16("Big Buck Bunny");
219 expected_metadata.artist = base::ASCIIToUTF16("Test Footage");
220 expected_metadata.album = base::ASCIIToUTF16("The Chrome Collection");
221 return expected_metadata;
222 }
223
GetExpectedArtwork()224 std::vector<media_session::MediaImage> GetExpectedArtwork() {
225 std::vector<media_session::MediaImage> images;
226
227 {
228 media_session::MediaImage image;
229 image.src = embedded_test_server()->GetURL("/artwork-96.png");
230 image.sizes.push_back(gfx::Size(96, 96));
231 image.type = base::ASCIIToUTF16("image/png");
232 images.push_back(image);
233 }
234
235 {
236 media_session::MediaImage image;
237 image.src = embedded_test_server()->GetURL("/artwork-128.png");
238 image.sizes.push_back(gfx::Size(128, 128));
239 image.type = base::ASCIIToUTF16("image/png");
240 images.push_back(image);
241 }
242
243 {
244 media_session::MediaImage image;
245 image.src = embedded_test_server()->GetURL("/artwork-big.jpg");
246 image.sizes.push_back(gfx::Size(192, 192));
247 image.sizes.push_back(gfx::Size(256, 256));
248 image.type = base::ASCIIToUTF16("image/jpg");
249 images.push_back(image);
250 }
251
252 {
253 media_session::MediaImage image;
254 image.src = embedded_test_server()->GetURL("/artwork-any.jpg");
255 image.sizes.push_back(gfx::Size(0, 0));
256 image.type = base::ASCIIToUTF16("image/jpg");
257 images.push_back(image);
258 }
259
260 {
261 media_session::MediaImage image;
262 image.src = embedded_test_server()->GetURL("/artwork-notype.jpg");
263 image.sizes.push_back(gfx::Size(0, 0));
264 images.push_back(image);
265 }
266
267 {
268 media_session::MediaImage image;
269 image.src = embedded_test_server()->GetURL("/artwork-nosize.jpg");
270 image.type = base::ASCIIToUTF16("image/jpg");
271 images.push_back(image);
272 }
273
274 return images;
275 }
276
GetExpectedDefaultMetadata()277 media_session::MediaMetadata GetExpectedDefaultMetadata() {
278 media_session::MediaMetadata expected_metadata;
279 expected_metadata.title = base::ASCIIToUTF16("Media History");
280 expected_metadata.source_title = base::ASCIIToUTF16(base::StringPrintf(
281 "%s:%u", embedded_test_server()->GetIPLiteralString().c_str(),
282 embedded_test_server()->port()));
283 return expected_metadata;
284 }
285
SimulateNavigationToCommit(Browser * browser)286 void SimulateNavigationToCommit(Browser* browser) {
287 // Navigate to trigger the session to be saved.
288 ui_test_utils::NavigateToURL(browser,
289 embedded_test_server()->GetURL("/empty.html"));
290
291 // Wait until the session has finished saving.
292 WaitForDB(GetMediaHistoryService(browser));
293 }
294
FetchResult(MediaHistoryKeyedService * service,const int64_t feed_id)295 media_history::MediaHistoryKeyedService::MediaFeedFetchResult FetchResult(
296 MediaHistoryKeyedService* service,
297 const int64_t feed_id) {
298 media_history::MediaHistoryKeyedService::MediaFeedFetchResult result;
299 result.feed_id = feed_id;
300 result.items = GetExpectedItems();
301 result.status = media_feeds::mojom::FetchResult::kSuccess;
302 result.display_name = "Test";
303 result.reset_token = test::GetResetTokenSync(service, feed_id);
304 return result;
305 }
306
GetTestURL() const307 const GURL GetTestURL() const {
308 return embedded_test_server()->GetURL("/media/media_history.html");
309 }
310
GetTestAltURL() const311 const GURL GetTestAltURL() const {
312 return embedded_test_server()->GetURL("/media/media_history.html?alt=1");
313 }
314
GetMediaSession(Browser * browser)315 static content::MediaSession* GetMediaSession(Browser* browser) {
316 return content::MediaSession::Get(
317 browser->tab_strip_model()->GetActiveWebContents());
318 }
319
GetMediaHistoryService(Browser * browser)320 static MediaHistoryKeyedService* GetMediaHistoryService(Browser* browser) {
321 return MediaHistoryKeyedServiceFactory::GetForProfile(browser->profile());
322 }
323
GetOTRMediaHistoryService(Browser * browser)324 static MediaHistoryKeyedService* GetOTRMediaHistoryService(Browser* browser) {
325 return MediaHistoryKeyedServiceFactory::GetForProfile(
326 browser->profile()->GetPrimaryOTRProfile());
327 }
328
GetMediaFeedsService(Browser * browser)329 static media_feeds::MediaFeedsService* GetMediaFeedsService(
330 Browser* browser) {
331 return media_feeds::MediaFeedsServiceFactory::GetInstance()->GetForProfile(
332 browser->profile());
333 }
334
WaitForDB(MediaHistoryKeyedService * service)335 static void WaitForDB(MediaHistoryKeyedService* service) {
336 base::RunLoop run_loop;
337 service->PostTaskToDBForTest(run_loop.QuitClosure());
338 run_loop.Run();
339 }
340
GetExpectedItems()341 static std::vector<media_feeds::mojom::MediaFeedItemPtr> GetExpectedItems() {
342 std::vector<media_feeds::mojom::MediaFeedItemPtr> items;
343
344 {
345 auto item = media_feeds::mojom::MediaFeedItem::New();
346 item->type = media_feeds::mojom::MediaFeedItemType::kVideo;
347 item->name = base::ASCIIToUTF16("The Video");
348 item->date_published = base::Time::FromDeltaSinceWindowsEpoch(
349 base::TimeDelta::FromMinutes(20));
350 item->is_family_friendly = media_feeds::mojom::IsFamilyFriendly::kNo;
351 item->action_status =
352 media_feeds::mojom::MediaFeedItemActionStatus::kActive;
353 items.push_back(std::move(item));
354 }
355
356 return items;
357 }
358
CreateBrowserFromParam()359 Browser* CreateBrowserFromParam() {
360 if (GetParam() == TestState::kIncognito) {
361 return CreateIncognitoBrowser();
362 } else if (GetParam() == TestState::kSavingBrowserHistoryDisabled) {
363 browser()->profile()->GetPrefs()->SetBoolean(
364 prefs::kSavingBrowserHistoryDisabled, true);
365 }
366
367 return browser();
368 }
369
IsReadOnly() const370 bool IsReadOnly() const { return GetParam() != TestState::kNormal; }
371
372 private:
373 base::test::ScopedFeatureList scoped_feature_list_;
374 };
375
376 INSTANTIATE_TEST_SUITE_P(
377 All,
378 MediaHistoryBrowserTest,
379 testing::Values(TestState::kNormal,
380 TestState::kIncognito,
381 TestState::kSavingBrowserHistoryDisabled));
382
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,RecordMediaSession_OnNavigate_Incomplete)383 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
384 RecordMediaSession_OnNavigate_Incomplete) {
385 auto* browser = CreateBrowserFromParam();
386
387 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
388 EXPECT_TRUE(SetMediaMetadataWithArtwork(browser));
389
390 auto expected_metadata = GetExpectedMetadata();
391 auto expected_artwork = GetExpectedArtwork();
392
393 {
394 media_session::test::MockMediaSessionMojoObserver observer(
395 *GetMediaSession(browser));
396 observer.WaitForState(
397 media_session::mojom::MediaSessionInfo::SessionState::kActive);
398 observer.WaitForExpectedMetadata(expected_metadata);
399 observer.WaitForExpectedImagesOfType(
400 media_session::mojom::MediaSessionImageType::kArtwork,
401 expected_artwork);
402 observer.WaitForAudioVideoState(
403 media_session::mojom::MediaAudioVideoState::kAudioVideo);
404 }
405
406 SimulateNavigationToCommit(browser);
407
408 // Verify the session in the database.
409 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
410
411 if (IsReadOnly()) {
412 EXPECT_TRUE(sessions.empty());
413 } else {
414 EXPECT_EQ(1u, sessions.size());
415 EXPECT_EQ(GetTestURL(), sessions[0]->url);
416 EXPECT_EQ(kTestClipDuration, sessions[0]->duration);
417 EXPECT_LT(base::TimeDelta(), sessions[0]->position);
418 EXPECT_EQ(expected_metadata.title, sessions[0]->metadata.title);
419 EXPECT_EQ(expected_metadata.artist, sessions[0]->metadata.artist);
420 EXPECT_EQ(expected_metadata.album, sessions[0]->metadata.album);
421 EXPECT_EQ(expected_metadata.source_title,
422 sessions[0]->metadata.source_title);
423 EXPECT_EQ(expected_artwork, sessions[0]->artwork);
424 }
425
426 // The OTR service should have the same data.
427 EXPECT_EQ(sessions,
428 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 1));
429
430 {
431 // Check the tables have the expected number of records
432 mojom::MediaHistoryStatsPtr stats =
433 GetStatsSync(GetMediaHistoryService(browser));
434
435 if (IsReadOnly()) {
436 EXPECT_EQ(0,
437 stats->table_row_counts[MediaHistoryOriginTable::kTableName]);
438 EXPECT_EQ(0,
439 stats->table_row_counts[MediaHistorySessionTable::kTableName]);
440 EXPECT_EQ(
441 0,
442 stats->table_row_counts[MediaHistorySessionImagesTable::kTableName]);
443 EXPECT_EQ(0,
444 stats->table_row_counts[MediaHistoryImagesTable::kTableName]);
445 } else {
446 EXPECT_EQ(1,
447 stats->table_row_counts[MediaHistoryOriginTable::kTableName]);
448 EXPECT_EQ(1,
449 stats->table_row_counts[MediaHistorySessionTable::kTableName]);
450 EXPECT_EQ(
451 7,
452 stats->table_row_counts[MediaHistorySessionImagesTable::kTableName]);
453 EXPECT_EQ(6,
454 stats->table_row_counts[MediaHistoryImagesTable::kTableName]);
455 }
456
457 // The OTR service should have the same data.
458 EXPECT_EQ(stats, GetStatsSync(GetOTRMediaHistoryService(browser)));
459 }
460 }
461
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,RecordMediaSession_DefaultMetadata)462 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
463 RecordMediaSession_DefaultMetadata) {
464 auto* browser = CreateBrowserFromParam();
465
466 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
467
468 media_session::MediaMetadata expected_metadata = GetExpectedDefaultMetadata();
469
470 {
471 media_session::test::MockMediaSessionMojoObserver observer(
472 *GetMediaSession(browser));
473 observer.WaitForState(
474 media_session::mojom::MediaSessionInfo::SessionState::kActive);
475 observer.WaitForExpectedMetadata(expected_metadata);
476 observer.WaitForAudioVideoState(
477 media_session::mojom::MediaAudioVideoState::kAudioVideo);
478 }
479
480 SimulateNavigationToCommit(browser);
481
482 // Verify the session in the database.
483 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
484
485 if (IsReadOnly()) {
486 EXPECT_TRUE(sessions.empty());
487 } else {
488 EXPECT_EQ(1u, sessions.size());
489 EXPECT_EQ(GetTestURL(), sessions[0]->url);
490 EXPECT_EQ(kTestClipDuration, sessions[0]->duration);
491 EXPECT_LT(base::TimeDelta(), sessions[0]->position);
492 EXPECT_EQ(expected_metadata.title, sessions[0]->metadata.title);
493 EXPECT_EQ(expected_metadata.artist, sessions[0]->metadata.artist);
494 EXPECT_EQ(expected_metadata.album, sessions[0]->metadata.album);
495 EXPECT_EQ(expected_metadata.source_title,
496 sessions[0]->metadata.source_title);
497 EXPECT_TRUE(sessions[0]->artwork.empty());
498 }
499
500 // The OTR service should have the same data.
501 EXPECT_EQ(sessions,
502 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 1));
503 }
504
505 // TODO(crbug.com/1078463): Flaky on Mac, Linux ASAN, and Win ASAN.
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DISABLED_RecordMediaSession_OnNavigate_Complete)506 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
507 DISABLED_RecordMediaSession_OnNavigate_Complete) {
508 auto* browser = CreateBrowserFromParam();
509
510 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
511 EXPECT_TRUE(FinishPlaying(browser));
512
513 media_session::MediaMetadata expected_metadata = GetExpectedDefaultMetadata();
514
515 {
516 media_session::test::MockMediaSessionMojoObserver observer(
517 *GetMediaSession(browser));
518 observer.WaitForState(
519 media_session::mojom::MediaSessionInfo::SessionState::kActive);
520 observer.WaitForExpectedMetadata(expected_metadata);
521 observer.WaitForAudioVideoState(
522 media_session::mojom::MediaAudioVideoState::kAudioVideo);
523 }
524
525 SimulateNavigationToCommit(browser);
526
527 {
528 // The session will not be returned since it is complete.
529 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
530 EXPECT_TRUE(sessions.empty());
531
532 // The OTR service should have the same data.
533 EXPECT_TRUE(
534 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 1).empty());
535 }
536
537 {
538 // If we remove the filter when we get the sessions we should see a result.
539 auto filter = base::BindRepeating(
540 [](const base::TimeDelta& duration, const base::TimeDelta& position) {
541 return true;
542 });
543
544 auto sessions =
545 GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1, filter);
546
547 if (IsReadOnly()) {
548 EXPECT_TRUE(sessions.empty());
549 } else {
550 EXPECT_EQ(1u, sessions.size());
551 EXPECT_EQ(GetTestURL(), sessions[0]->url);
552 }
553
554 // The OTR service should have the same data.
555 EXPECT_EQ(sessions, GetPlaybackSessionsSync(
556 GetOTRMediaHistoryService(browser), 1, filter));
557 }
558 }
559
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DoNotRecordSessionIfNotActive)560 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, DoNotRecordSessionIfNotActive) {
561 auto* browser = CreateBrowserFromParam();
562
563 ui_test_utils::NavigateToURL(browser, GetTestURL());
564 EXPECT_TRUE(SetMediaMetadata(browser));
565
566 media_session::MediaMetadata expected_metadata = GetExpectedDefaultMetadata();
567
568 {
569 media_session::test::MockMediaSessionMojoObserver observer(
570 *GetMediaSession(browser));
571 observer.WaitForState(
572 media_session::mojom::MediaSessionInfo::SessionState::kInactive);
573 observer.WaitForExpectedMetadata(expected_metadata);
574 }
575
576 SimulateNavigationToCommit(browser);
577
578 // Verify the session has not been stored in the database.
579 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
580 EXPECT_TRUE(sessions.empty());
581
582 // The OTR service should have the same data.
583 EXPECT_TRUE(
584 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 1).empty());
585 }
586
587 // Flaky failures: crbug.com/1066853
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DISABLED_GetPlaybackSessions)588 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, DISABLED_GetPlaybackSessions) {
589 auto* browser = CreateBrowserFromParam();
590 auto expected_default_metadata = GetExpectedDefaultMetadata();
591
592 {
593 // Start a session.
594 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
595 EXPECT_TRUE(SetMediaMetadataWithArtwork(browser));
596
597 media_session::test::MockMediaSessionMojoObserver observer(
598 *GetMediaSession(browser));
599 observer.WaitForState(
600 media_session::mojom::MediaSessionInfo::SessionState::kActive);
601 observer.WaitForExpectedMetadata(GetExpectedMetadata());
602 observer.WaitForAudioVideoState(
603 media_session::mojom::MediaAudioVideoState::kAudioVideo);
604 }
605
606 SimulateNavigationToCommit(browser);
607
608 {
609 // Start a second session on a different URL.
610 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestAltURL()));
611
612 media_session::test::MockMediaSessionMojoObserver observer(
613 *GetMediaSession(browser));
614 observer.WaitForState(
615 media_session::mojom::MediaSessionInfo::SessionState::kActive);
616 observer.WaitForExpectedMetadata(expected_default_metadata);
617 observer.WaitForAudioVideoState(
618 media_session::mojom::MediaAudioVideoState::kAudioVideo);
619 }
620
621 SimulateNavigationToCommit(browser);
622
623 {
624 // Get the two most recent playback sessions and check they are in order.
625 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 2);
626
627 if (IsReadOnly()) {
628 EXPECT_TRUE(sessions.empty());
629 } else {
630 ASSERT_EQ(2u, sessions.size());
631 EXPECT_EQ(GetTestAltURL(), sessions[0]->url);
632 EXPECT_EQ(GetTestURL(), sessions[1]->url);
633 }
634
635 // The OTR service should have the same data.
636 EXPECT_EQ(sessions,
637 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 2));
638 }
639
640 {
641 // Get the last playback session.
642 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
643
644 if (IsReadOnly()) {
645 EXPECT_TRUE(sessions.empty());
646 } else {
647 EXPECT_EQ(1u, sessions.size());
648 EXPECT_EQ(GetTestAltURL(), sessions[0]->url);
649 }
650
651 // The OTR service should have the same data.
652 EXPECT_EQ(sessions,
653 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 1));
654 }
655
656 {
657 // Start the first page again and seek to 4 seconds in with different
658 // metadata.
659 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
660 EXPECT_TRUE(content::ExecuteScript(
661 browser->tab_strip_model()->GetActiveWebContents(), "seekToFour()"));
662
663 media_session::test::MockMediaSessionMojoObserver observer(
664 *GetMediaSession(browser));
665 observer.WaitForState(
666 media_session::mojom::MediaSessionInfo::SessionState::kActive);
667 observer.WaitForExpectedMetadata(expected_default_metadata);
668 }
669
670 SimulateNavigationToCommit(browser);
671
672 {
673 // Check that recent playback sessions only returns two playback sessions
674 // because the first one was collapsed into the third one since they
675 // have the same URL. We should also use the data from the most recent
676 // playback.
677 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 3);
678
679 if (IsReadOnly()) {
680 EXPECT_TRUE(sessions.empty());
681 } else {
682 ASSERT_EQ(2u, sessions.size());
683 EXPECT_EQ(GetTestURL(), sessions[0]->url);
684 EXPECT_EQ(GetTestAltURL(), sessions[1]->url);
685
686 EXPECT_EQ(kTestClipDuration, sessions[0]->duration);
687 EXPECT_EQ(4, sessions[0]->position.InSeconds());
688 EXPECT_EQ(expected_default_metadata.title, sessions[0]->metadata.title);
689 EXPECT_EQ(expected_default_metadata.artist, sessions[0]->metadata.artist);
690 EXPECT_EQ(expected_default_metadata.album, sessions[0]->metadata.album);
691 EXPECT_EQ(expected_default_metadata.source_title,
692 sessions[0]->metadata.source_title);
693 }
694
695 // The OTR service should have the same data.
696 EXPECT_EQ(sessions,
697 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 3));
698 }
699
700 {
701 // Start the first page again and finish playing.
702 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
703 EXPECT_TRUE(FinishPlaying(browser));
704
705 media_session::test::MockMediaSessionMojoObserver observer(
706 *GetMediaSession(browser));
707 observer.WaitForState(
708 media_session::mojom::MediaSessionInfo::SessionState::kActive);
709 observer.WaitForExpectedMetadata(expected_default_metadata);
710 observer.WaitForAudioVideoState(
711 media_session::mojom::MediaAudioVideoState::kAudioVideo);
712 }
713
714 SimulateNavigationToCommit(browser);
715
716 {
717 // Get the recent playbacks and the test URL should not appear at all
718 // because playback has completed for that URL.
719 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 4);
720
721 if (IsReadOnly()) {
722 EXPECT_TRUE(sessions.empty());
723 } else {
724 EXPECT_EQ(1u, sessions.size());
725 EXPECT_EQ(GetTestAltURL(), sessions[0]->url);
726 }
727
728 // The OTR service should have the same data.
729 EXPECT_EQ(sessions,
730 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 4));
731 }
732
733 {
734 // Start the first session again.
735 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
736 EXPECT_TRUE(SetMediaMetadata(browser));
737
738 media_session::test::MockMediaSessionMojoObserver observer(
739 *GetMediaSession(browser));
740 observer.WaitForState(
741 media_session::mojom::MediaSessionInfo::SessionState::kActive);
742 observer.WaitForExpectedMetadata(GetExpectedMetadata());
743 observer.WaitForAudioVideoState(
744 media_session::mojom::MediaAudioVideoState::kAudioVideo);
745 }
746
747 SimulateNavigationToCommit(browser);
748
749 {
750 // The test URL should now appear in the recent playbacks list again since
751 // it is incomplete again.
752 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 2);
753
754 if (IsReadOnly()) {
755 EXPECT_TRUE(sessions.empty());
756 } else {
757 ASSERT_EQ(2u, sessions.size());
758 EXPECT_EQ(GetTestURL(), sessions[0]->url);
759 EXPECT_EQ(GetTestAltURL(), sessions[1]->url);
760 }
761
762 // The OTR service should have the same data.
763 EXPECT_EQ(sessions,
764 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 2));
765 }
766 }
767
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,SaveImagesWithDifferentSessions)768 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
769 SaveImagesWithDifferentSessions) {
770 auto* browser = CreateBrowserFromParam();
771 auto expected_metadata = GetExpectedMetadata();
772 auto expected_artwork = GetExpectedArtwork();
773
774 {
775 // Start a session.
776 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
777 EXPECT_TRUE(SetMediaMetadataWithArtwork(browser));
778
779 media_session::test::MockMediaSessionMojoObserver observer(
780 *GetMediaSession(browser));
781 observer.WaitForState(
782 media_session::mojom::MediaSessionInfo::SessionState::kActive);
783 observer.WaitForExpectedMetadata(expected_metadata);
784 observer.WaitForExpectedImagesOfType(
785 media_session::mojom::MediaSessionImageType::kArtwork,
786 expected_artwork);
787 }
788
789 SimulateNavigationToCommit(browser);
790
791 std::vector<media_session::MediaImage> expected_alt_artwork;
792
793 {
794 media_session::MediaImage image;
795 image.src = embedded_test_server()->GetURL("/artwork-96.png");
796 image.sizes.push_back(gfx::Size(96, 96));
797 image.type = base::ASCIIToUTF16("image/png");
798 expected_alt_artwork.push_back(image);
799 }
800
801 {
802 media_session::MediaImage image;
803 image.src = embedded_test_server()->GetURL("/artwork-alt.png");
804 image.sizes.push_back(gfx::Size(128, 128));
805 image.type = base::ASCIIToUTF16("image/png");
806 expected_alt_artwork.push_back(image);
807 }
808
809 {
810 // Start a second session on a different URL.
811 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestAltURL()));
812 EXPECT_TRUE(content::ExecuteScript(
813 browser->tab_strip_model()->GetActiveWebContents(),
814 "setMediaMetadataWithAltArtwork();"));
815
816 media_session::test::MockMediaSessionMojoObserver observer(
817 *GetMediaSession(browser));
818 observer.WaitForState(
819 media_session::mojom::MediaSessionInfo::SessionState::kActive);
820 observer.WaitForExpectedMetadata(expected_metadata);
821 observer.WaitForExpectedImagesOfType(
822 media_session::mojom::MediaSessionImageType::kArtwork,
823 expected_alt_artwork);
824 }
825
826 SimulateNavigationToCommit(browser);
827
828 // Verify the session in the database.
829 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 2);
830
831 if (IsReadOnly()) {
832 EXPECT_TRUE(sessions.empty());
833 } else {
834 ASSERT_EQ(2u, sessions.size());
835 EXPECT_EQ(GetTestAltURL(), sessions[0]->url);
836 EXPECT_EQ(expected_alt_artwork, sessions[0]->artwork);
837 EXPECT_EQ(GetTestURL(), sessions[1]->url);
838 EXPECT_EQ(expected_artwork, sessions[1]->artwork);
839 }
840
841 // The OTR service should have the same data.
842 EXPECT_EQ(sessions,
843 GetPlaybackSessionsSync(GetOTRMediaHistoryService(browser), 2));
844 }
845
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,RecordWatchtime_AudioVideo)846 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, RecordWatchtime_AudioVideo) {
847 auto* browser = CreateBrowserFromParam();
848
849 // Start a page and wait for significant playback so we record watchtime.
850 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
851 EXPECT_TRUE(WaitForSignificantPlayback(browser));
852 SimulateNavigationToCommit(browser);
853
854 {
855 auto playbacks = GetPlaybacksSync(GetMediaHistoryService(browser));
856 auto origins = GetOriginsSync(GetMediaHistoryService(browser));
857
858 if (IsReadOnly()) {
859 EXPECT_TRUE(playbacks.empty());
860 EXPECT_TRUE(origins.empty());
861 } else {
862 EXPECT_EQ(1u, playbacks.size());
863 EXPECT_TRUE(playbacks[0]->has_audio);
864 EXPECT_TRUE(playbacks[0]->has_video);
865 EXPECT_EQ(GetTestURL(), playbacks[0]->url);
866 EXPECT_GE(base::TimeDelta::FromSeconds(7), playbacks[0]->watchtime);
867
868 EXPECT_EQ(1u, origins.size());
869 EXPECT_EQ(url::Origin::Create(GetTestURL()), origins[0]->origin);
870 EXPECT_EQ(playbacks[0]->watchtime,
871 origins[0]->cached_audio_video_watchtime);
872 EXPECT_EQ(playbacks[0]->watchtime,
873 origins[0]->actual_audio_video_watchtime);
874 }
875
876 // The OTR service should have the same data.
877 EXPECT_EQ(playbacks, GetPlaybacksSync(GetOTRMediaHistoryService(browser)));
878 EXPECT_EQ(origins, GetOriginsSync(GetOTRMediaHistoryService(browser)));
879 }
880
881 // Start playing again.
882 EXPECT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
883 EXPECT_TRUE(WaitForSignificantPlayback(browser));
884 SimulateNavigationToCommit(browser);
885
886 {
887 auto playbacks = GetPlaybacksSync(GetMediaHistoryService(browser));
888 auto origins = GetOriginsSync(GetMediaHistoryService(browser));
889
890 if (IsReadOnly()) {
891 EXPECT_TRUE(playbacks.empty());
892 EXPECT_TRUE(origins.empty());
893 } else {
894 EXPECT_EQ(2u, playbacks.size());
895
896 // Calculate the total watchtime across the playbacks.
897 base::TimeDelta total_time;
898 for (auto& playback : playbacks) {
899 EXPECT_EQ(GetTestURL(), playback->url);
900 total_time += playback->watchtime;
901 }
902
903 // The total aggregate watchtime should have increased.
904 EXPECT_EQ(1u, origins.size());
905 EXPECT_EQ(url::Origin::Create(GetTestURL()), origins[0]->origin);
906 EXPECT_EQ(total_time, origins[0]->cached_audio_video_watchtime);
907 EXPECT_EQ(total_time, origins[0]->actual_audio_video_watchtime);
908
909 // The OTR service should have the same data.
910 EXPECT_EQ(playbacks,
911 GetPlaybacksSync(GetOTRMediaHistoryService(browser)));
912 EXPECT_EQ(origins, GetOriginsSync(GetOTRMediaHistoryService(browser)));
913 }
914 }
915 }
916
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,RecordWatchtime_AudioOnly)917 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, RecordWatchtime_AudioOnly) {
918 auto* browser = CreateBrowserFromParam();
919
920 // Start a page and wait for significant playback so we record watchtime.
921 EXPECT_TRUE(SetupPageAndStartPlayingAudioOnly(browser, GetTestURL()));
922 EXPECT_TRUE(WaitForSignificantPlayback(browser));
923
924 SimulateNavigationToCommit(browser);
925
926 {
927 auto playbacks = GetPlaybacksSync(GetMediaHistoryService(browser));
928 auto origins = GetOriginsSync(GetMediaHistoryService(browser));
929
930 if (IsReadOnly()) {
931 EXPECT_TRUE(playbacks.empty());
932 EXPECT_TRUE(origins.empty());
933 } else {
934 EXPECT_EQ(1u, playbacks.size());
935 EXPECT_TRUE(playbacks[0]->has_audio);
936 EXPECT_FALSE(playbacks[0]->has_video);
937 EXPECT_EQ(GetTestURL(), playbacks[0]->url);
938 EXPECT_GE(base::TimeDelta::FromSeconds(7), playbacks[0]->watchtime);
939
940 EXPECT_EQ(1u, origins.size());
941 EXPECT_EQ(url::Origin::Create(GetTestURL()), origins[0]->origin);
942 EXPECT_TRUE(origins[0]->cached_audio_video_watchtime.is_zero());
943 EXPECT_TRUE(origins[0]->actual_audio_video_watchtime.is_zero());
944
945 // The OTR service should have the same data.
946 EXPECT_EQ(playbacks,
947 GetPlaybacksSync(GetOTRMediaHistoryService(browser)));
948 EXPECT_EQ(origins, GetOriginsSync(GetOTRMediaHistoryService(browser)));
949 }
950 }
951
952 // Start playing again.
953 EXPECT_TRUE(SetupPageAndStartPlayingAudioOnly(browser, GetTestURL()));
954 EXPECT_TRUE(WaitForSignificantPlayback(browser));
955 SimulateNavigationToCommit(browser);
956
957 {
958 auto playbacks = GetPlaybacksSync(GetMediaHistoryService(browser));
959 auto origins = GetOriginsSync(GetMediaHistoryService(browser));
960
961 if (IsReadOnly()) {
962 EXPECT_TRUE(playbacks.empty());
963 EXPECT_TRUE(origins.empty());
964 } else {
965 EXPECT_EQ(2u, playbacks.size());
966
967 // The total aggregate watchtime should not have increased..
968 EXPECT_EQ(1u, origins.size());
969 EXPECT_EQ(url::Origin::Create(GetTestURL()), origins[0]->origin);
970 EXPECT_TRUE(origins[0]->cached_audio_video_watchtime.is_zero());
971 EXPECT_TRUE(origins[0]->actual_audio_video_watchtime.is_zero());
972
973 // The OTR service should have the same data.
974 EXPECT_EQ(playbacks,
975 GetPlaybacksSync(GetOTRMediaHistoryService(browser)));
976 EXPECT_EQ(origins, GetOriginsSync(GetOTRMediaHistoryService(browser)));
977 }
978 }
979 }
980
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,RecordWatchtime_VideoOnly)981 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, RecordWatchtime_VideoOnly) {
982 auto* browser = CreateBrowserFromParam();
983
984 // Start a page and wait for significant playback so we record watchtime.
985 EXPECT_TRUE(SetupPageAndStartPlayingVideoOnly(browser, GetTestURL()));
986 EXPECT_TRUE(WaitForSignificantPlayback(browser));
987
988 SimulateNavigationToCommit(browser);
989
990 {
991 auto playbacks = GetPlaybacksSync(GetMediaHistoryService(browser));
992 auto origins = GetOriginsSync(GetMediaHistoryService(browser));
993
994 if (IsReadOnly()) {
995 EXPECT_TRUE(playbacks.empty());
996 EXPECT_TRUE(origins.empty());
997 } else {
998 EXPECT_EQ(1u, playbacks.size());
999 EXPECT_FALSE(playbacks[0]->has_audio);
1000 EXPECT_TRUE(playbacks[0]->has_video);
1001 EXPECT_EQ(GetTestURL(), playbacks[0]->url);
1002 EXPECT_GE(base::TimeDelta::FromSeconds(7), playbacks[0]->watchtime);
1003
1004 EXPECT_EQ(1u, origins.size());
1005 EXPECT_EQ(url::Origin::Create(GetTestURL()), origins[0]->origin);
1006 EXPECT_TRUE(origins[0]->cached_audio_video_watchtime.is_zero());
1007 EXPECT_TRUE(origins[0]->actual_audio_video_watchtime.is_zero());
1008
1009 // The OTR service should have the same data.
1010 EXPECT_EQ(playbacks,
1011 GetPlaybacksSync(GetOTRMediaHistoryService(browser)));
1012 EXPECT_EQ(origins, GetOriginsSync(GetOTRMediaHistoryService(browser)));
1013 }
1014 }
1015
1016 // Start playing again.
1017 EXPECT_TRUE(SetupPageAndStartPlayingVideoOnly(browser, GetTestURL()));
1018 EXPECT_TRUE(WaitForSignificantPlayback(browser));
1019 SimulateNavigationToCommit(browser);
1020
1021 {
1022 auto playbacks = GetPlaybacksSync(GetMediaHistoryService(browser));
1023 auto origins = GetOriginsSync(GetMediaHistoryService(browser));
1024
1025 if (IsReadOnly()) {
1026 EXPECT_TRUE(playbacks.empty());
1027 EXPECT_TRUE(origins.empty());
1028 } else {
1029 EXPECT_EQ(2u, playbacks.size());
1030
1031 // The total aggregate watchtime should not have increased.
1032 EXPECT_EQ(1u, origins.size());
1033 EXPECT_EQ(url::Origin::Create(GetTestURL()), origins[0]->origin);
1034 EXPECT_TRUE(origins[0]->cached_audio_video_watchtime.is_zero());
1035 EXPECT_TRUE(origins[0]->actual_audio_video_watchtime.is_zero());
1036
1037 // The OTR service should have the same data.
1038 EXPECT_EQ(playbacks,
1039 GetPlaybacksSync(GetOTRMediaHistoryService(browser)));
1040 EXPECT_EQ(origins, GetOriginsSync(GetOTRMediaHistoryService(browser)));
1041 }
1042 }
1043 }
1044
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DoNotRecordSessionForAudioOnly)1045 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
1046 DoNotRecordSessionForAudioOnly) {
1047 auto* browser = CreateBrowserFromParam();
1048
1049 SetupPageAndStartPlayingAudioOnly(browser, GetTestURL());
1050
1051 {
1052 media_session::test::MockMediaSessionMojoObserver observer(
1053 *GetMediaSession(browser));
1054 observer.WaitForState(
1055 media_session::mojom::MediaSessionInfo::SessionState::kActive);
1056 observer.WaitForAudioVideoState(
1057 media_session::mojom::MediaAudioVideoState::kAudioOnly);
1058 }
1059
1060 SimulateNavigationToCommit(browser);
1061
1062 // Verify the session was not recorded.
1063 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
1064 EXPECT_TRUE(sessions.empty());
1065 }
1066
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DoNotRecordSessionForVideoOnly)1067 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
1068 DoNotRecordSessionForVideoOnly) {
1069 auto* browser = CreateBrowserFromParam();
1070
1071 SetupPageAndStartPlayingVideoOnly(browser, GetTestURL());
1072 WaitForSignificantPlayback(browser);
1073
1074 SimulateNavigationToCommit(browser);
1075
1076 // Verify the session was not recorded.
1077 auto sessions = GetPlaybackSessionsSync(GetMediaHistoryService(browser), 1);
1078 EXPECT_TRUE(sessions.empty());
1079 }
1080
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,ResetFeedsWhenBrowsingDataCleared)1081 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
1082 ResetFeedsWhenBrowsingDataCleared) {
1083 auto* browser = CreateBrowserFromParam();
1084 auto* service = GetMediaHistoryService(browser);
1085
1086 // Discover a test feed.
1087 if (auto* feeds_service = GetMediaFeedsService(browser)) {
1088 feeds_service->DiscoverMediaFeed(
1089 GURL("https://www.google.com/media-feed.json"));
1090 WaitForDB(service);
1091 }
1092
1093 // Store the feed data.
1094 service->StoreMediaFeedFetchResult(FetchResult(service, 1),
1095 base::DoNothing());
1096 WaitForDB(service);
1097
1098 {
1099 // Check that the tables have the right count in them.
1100 auto stats = GetStatsSync(service);
1101
1102 if (IsReadOnly()) {
1103 EXPECT_EQ(0, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1104 EXPECT_EQ(
1105 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1106 } else {
1107 EXPECT_EQ(1, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1108 EXPECT_EQ(
1109 1, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1110 }
1111 }
1112
1113 // Clear the browsing data.
1114 content::BrowsingDataRemover* remover =
1115 content::BrowserContext::GetBrowsingDataRemover(browser->profile());
1116 content::BrowsingDataRemoverCompletionObserver completion_observer(remover);
1117 remover->RemoveAndReply(
1118 base::Time(), base::Time::Max(),
1119 content::BrowsingDataRemover::DATA_TYPE_CACHE,
1120 content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1121 &completion_observer);
1122 completion_observer.BlockUntilCompletion();
1123
1124 {
1125 // Check that the tables have the right count in them.
1126 auto stats = GetStatsSync(service);
1127
1128 if (IsReadOnly()) {
1129 EXPECT_EQ(0, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1130 EXPECT_EQ(
1131 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1132 } else {
1133 EXPECT_EQ(1, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1134 EXPECT_EQ(
1135 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1136 }
1137 }
1138 }
1139
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,ResetFeedsWhenBrowsingDataClearedWithFilter)1140 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
1141 ResetFeedsWhenBrowsingDataClearedWithFilter) {
1142 const GURL feed_url("https://www.google.com/media-feed.json");
1143
1144 auto* browser = CreateBrowserFromParam();
1145 auto* service = GetMediaHistoryService(browser);
1146
1147 // Discover a test feed.
1148 if (auto* feeds_service = GetMediaFeedsService(browser)) {
1149 feeds_service->DiscoverMediaFeed(
1150 GURL("https://www.google.com/media-feed.json"));
1151 WaitForDB(service);
1152 }
1153
1154 // Store the feed data.
1155 service->StoreMediaFeedFetchResult(FetchResult(service, 1),
1156 base::DoNothing());
1157 WaitForDB(service);
1158
1159 {
1160 // Check that the tables have the right count in them.
1161 auto stats = GetStatsSync(service);
1162
1163 if (IsReadOnly()) {
1164 EXPECT_EQ(0, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1165 EXPECT_EQ(
1166 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1167 } else {
1168 EXPECT_EQ(1, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1169 EXPECT_EQ(
1170 1, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1171 }
1172 }
1173
1174 {
1175 // Clear the browsing data for another origin.
1176 auto filter = content::BrowsingDataFilterBuilder::Create(
1177 content::BrowsingDataFilterBuilder::Mode::kDelete);
1178 filter->AddOrigin(url::Origin::Create(GURL("https://www.example.org")));
1179 content::BrowsingDataRemover* remover =
1180 content::BrowserContext::GetBrowsingDataRemover(browser->profile());
1181 content::BrowsingDataRemoverCompletionObserver completion_observer(remover);
1182 remover->RemoveWithFilterAndReply(
1183 base::Time(), base::Time::Max(),
1184 content::BrowsingDataRemover::DATA_TYPE_CACHE,
1185 content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1186 std::move(filter), &completion_observer);
1187 completion_observer.BlockUntilCompletion();
1188 }
1189
1190 {
1191 // Check that the tables have the right count in them (nothing should have
1192 // been deleted).
1193 auto stats = GetStatsSync(service);
1194
1195 if (IsReadOnly()) {
1196 EXPECT_EQ(0, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1197 EXPECT_EQ(
1198 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1199 } else {
1200 EXPECT_EQ(1, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1201 EXPECT_EQ(
1202 1, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1203 }
1204 }
1205
1206 {
1207 // Clear the browsing data for the feed origin.
1208 auto filter = content::BrowsingDataFilterBuilder::Create(
1209 content::BrowsingDataFilterBuilder::Mode::kDelete);
1210 filter->AddOrigin(url::Origin::Create(feed_url));
1211 content::BrowsingDataRemover* remover =
1212 content::BrowserContext::GetBrowsingDataRemover(browser->profile());
1213 content::BrowsingDataRemoverCompletionObserver completion_observer(remover);
1214 remover->RemoveWithFilterAndReply(
1215 base::Time(), base::Time::Max(),
1216 content::BrowsingDataRemover::DATA_TYPE_CACHE,
1217 content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
1218 std::move(filter), &completion_observer);
1219 completion_observer.BlockUntilCompletion();
1220 }
1221
1222 {
1223 // Check that the tables have the right count in them.
1224 auto stats = GetStatsSync(service);
1225
1226 if (IsReadOnly()) {
1227 EXPECT_EQ(0, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1228 EXPECT_EQ(
1229 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1230 } else {
1231 EXPECT_EQ(1, stats->table_row_counts[MediaHistoryFeedsTable::kTableName]);
1232 EXPECT_EQ(
1233 0, stats->table_row_counts[MediaHistoryFeedItemsTable::kTableName]);
1234 }
1235 }
1236 }
1237
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DoNotRecordWatchtime_Background)1238 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,
1239 DoNotRecordWatchtime_Background) {
1240 auto* browser = CreateBrowserFromParam();
1241 auto* service = GetMediaHistoryService(browser);
1242
1243 // Setup the test page.
1244 auto* web_contents = browser->tab_strip_model()->GetActiveWebContents();
1245 ASSERT_TRUE(SetupPageAndStartPlaying(browser, GetTestURL()));
1246
1247 // Hide the web contents.
1248 web_contents->WasHidden();
1249
1250 // Wait for significant playback in the background tab.
1251 bool seeked = false;
1252 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1253 web_contents, "waitForSignificantPlayback();", &seeked));
1254 ASSERT_TRUE(seeked);
1255
1256 // Close all the tabs to trigger any saving.
1257 browser->tab_strip_model()->CloseAllTabs();
1258
1259 // Wait until the session has finished saving.
1260 WaitForDB(service);
1261
1262 // We should either have not saved any playback or it should be short.
1263 auto playbacks = GetPlaybacksSync(service);
1264 if (!playbacks.empty()) {
1265 ASSERT_EQ(1u, playbacks.size());
1266 EXPECT_GE(base::TimeDelta::FromSeconds(2), playbacks[0]->watchtime);
1267 }
1268 }
1269
IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest,DoNotRecordWatchtime_Muted)1270 IN_PROC_BROWSER_TEST_P(MediaHistoryBrowserTest, DoNotRecordWatchtime_Muted) {
1271 auto* browser = CreateBrowserFromParam();
1272 auto* service = GetMediaHistoryService(browser);
1273
1274 // Setup the test page and mute the player.
1275 auto* web_contents = browser->tab_strip_model()->GetActiveWebContents();
1276 ui_test_utils::NavigateToURL(browser, GetTestURL());
1277 ASSERT_TRUE(content::ExecuteScript(web_contents, "mute();"));
1278
1279 // Start playing the video.
1280 bool played = false;
1281 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1282 web_contents, "attemptPlayVideo();", &played));
1283 ASSERT_TRUE(played);
1284
1285 // Wait for significant playback in the muted tab.
1286 WaitForSignificantPlayback(browser);
1287
1288 // Close all the tabs to trigger any saving.
1289 browser->tab_strip_model()->CloseAllTabs();
1290
1291 // Wait until the session has finished saving.
1292 WaitForDB(service);
1293
1294 // No playbacks should have been saved since we were muted.
1295 auto playbacks = GetPlaybacksSync(service);
1296 EXPECT_TRUE(playbacks.empty());
1297 }
1298
1299 } // namespace media_history
1300