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