Commit a4831e9b authored by John Rummell's avatar John Rummell Committed by Commit Bot

Reland "Update BrowsingDataRemoverBrowserTest to include MediaLicenses"

Original change's description:
> MediaLicenses can be cleared from the ClearBrowsingData dialog, so update the
> BrowsingDataRemoverBrowserTest to check them as well. This uses the test-only
> External Clear Key CDM to store the license in the file system, if it is
> available.

This reverts commit e9fc38c7.

The original CL was flaky due to Mac's only saving file timestamps to
second granularity. As a result it was possible for the newly created license
to be saved with a timestamp prior to the current actual time, and deleting
"old" licenses would include it in the deletion. Change is to wait for some
time on Macs only to ensure that the "new" license has a later timestamp.

BUG=808690,879812
TEST=new browser_tests pass

Change-Id: Ibd7cf65b468f98af9aa583d3f320e54c8f3f223e
Reviewed-on: https://chromium-review.googlesource.com/c/1345248Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#610211}
parent 1d7df966
......@@ -66,6 +66,7 @@
#include "content/public/test/simple_url_loader_test_helper.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "media/base/media_switches.h"
#include "media/mojo/services/video_decode_perf_history.h"
#include "net/cookies/canonical_cookie.h"
#include "net/dns/mock_host_resolver.h"
......@@ -80,6 +81,15 @@
#include "third_party/re2/src/re2/re2.h"
#include "url/gurl.h"
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
#if defined(OS_MACOSX)
#include "base/threading/platform_thread.h"
#endif
#include "base/memory/scoped_refptr.h"
#include "chrome/browser/browsing_data/browsing_data_media_license_helper.h"
#include "chrome/browser/media/library_cdm_test_helper.h"
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
using content::BrowserThread;
using content::BrowsingDataFilterBuilder;
......@@ -281,14 +291,7 @@ bool SetGaiaCookieForProfile(Profile* profile) {
class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest {
public:
BrowsingDataRemoverBrowserTest() {
feature_list_.InitWithFeatures(
{leveldb::kLevelDBRewriteFeature,
// Ensure that kOnionSoupDOMStorage is enabled because the old
// SessionStorage implementation causes flaky tests.
blink::features::kOnionSoupDOMStorage},
{});
}
BrowsingDataRemoverBrowserTest() {}
// Call to use an Incognito browser rather than the default.
void UseIncognitoBrowser() {
......@@ -352,16 +355,22 @@ class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest {
}
void RemoveAndWait(int remove_mask) {
RemoveAndWait(remove_mask, base::Time());
RemoveAndWait(remove_mask, base::Time(), base::Time::Max());
}
void RemoveAndWait(int remove_mask, base::Time delete_begin) {
RemoveAndWait(remove_mask, delete_begin, base::Time::Max());
}
void RemoveAndWait(int remove_mask,
base::Time delete_begin,
base::Time delete_end) {
content::BrowsingDataRemover* remover =
content::BrowserContext::GetBrowsingDataRemover(
GetBrowser()->profile());
content::BrowsingDataRemoverCompletionObserver completion_observer(remover);
remover->RemoveAndReply(
delete_begin, base::Time::Max(), remove_mask,
delete_begin, delete_end, remove_mask,
content::BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB,
&completion_observer);
completion_observer.BlockUntilCompletion();
......@@ -447,6 +456,30 @@ class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest {
return count;
}
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
int GetMediaLicenseCount() {
base::RunLoop run_loop;
int count = -1;
content::StoragePartition* partition =
content::BrowserContext::GetDefaultStoragePartition(
browser()->profile());
scoped_refptr<BrowsingDataMediaLicenseHelper> media_license_helper =
BrowsingDataMediaLicenseHelper::Create(
partition->GetFileSystemContext());
media_license_helper->StartFetching(base::BindLambdaForTesting(
[&](const std::list<BrowsingDataMediaLicenseHelper::MediaLicenseInfo>&
licenses) {
count = licenses.size();
LOG(INFO) << "Found " << count << " licenses.";
for (const auto& license : licenses)
LOG(INFO) << license.last_modified_time;
run_loop.Quit();
}));
run_loop.Run();
return count;
}
#endif
inline void ExpectCookieTreeModelCount(int expected) {
std::unique_ptr<CookiesTreeModel> model = GetCookiesTreeModel();
EXPECT_EQ(expected, GetCookiesTreeModelCount(model->GetRoot()))
......@@ -521,6 +554,25 @@ class BrowsingDataRemoverBrowserTest : public InProcessBrowserTest {
return model;
}
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
std::vector<base::Feature> enabled_features = {
leveldb::kLevelDBRewriteFeature,
// Ensure that kOnionSoupDOMStorage is enabled because the old
// SessionStorage implementation causes flaky tests.
blink::features::kOnionSoupDOMStorage};
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// Testing MediaLicenses requires additional command line parameters as
// it uses the External Clear Key CDM.
RegisterClearKeyCdm(command_line);
enabled_features.push_back(media::kExternalClearKeyForTesting);
#endif
feature_list_.InitWithFeatures(enabled_features, {});
}
base::test::ScopedFeatureList feature_list_;
Browser* incognito_browser_ = nullptr;
};
......@@ -1043,6 +1095,127 @@ IN_PROC_BROWSER_TEST_P(BrowsingDataRemoverBrowserTestP, EmptyIndexedDb) {
TestEmptySiteData("IndexedDb", GetParam());
}
#if BUILDFLAG(ENABLE_LIBRARY_CDMS)
// Test Media Licenses by creating one and checking it is counted by the
// cookie counter. Then delete it and check that the cookie counter is back
// to zero.
IN_PROC_BROWSER_TEST_P(BrowsingDataRemoverBrowserTestP, MediaLicenseDeletion) {
const std::string kMediaLicenseType = "MediaLicense";
const base::Time delete_begin = GetParam();
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(0, GetMediaLicenseCount());
GURL url =
embedded_test_server()->GetURL("/browsing_data/media_license.html");
ui_test_utils::NavigateToURL(browser(), url);
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(0, GetMediaLicenseCount());
ExpectCookieTreeModelCount(0);
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
SetDataForType(kMediaLicenseType);
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(1, GetMediaLicenseCount());
ExpectCookieTreeModelCount(1);
EXPECT_TRUE(HasDataForType(kMediaLicenseType));
// Try to remove the Media Licenses using a time frame up until an hour ago,
// which should not remove the recently created Media License.
RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES,
delete_begin, kLastHour);
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(1, GetMediaLicenseCount());
ExpectCookieTreeModelCount(1);
EXPECT_TRUE(HasDataForType(kMediaLicenseType));
// Now try with a time range that includes the current time, which should
// clear the Media License created for this test.
RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES,
delete_begin, base::Time::Max());
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(0, GetMediaLicenseCount());
ExpectCookieTreeModelCount(0);
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
}
// Create and save a media license (which will be deleted in the following
// test).
IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest,
PRE_MediaLicenseTimedDeletion) {
const std::string kMediaLicenseType = "MediaLicense";
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(0, GetMediaLicenseCount());
GURL url =
embedded_test_server()->GetURL("/browsing_data/media_license.html");
ui_test_utils::NavigateToURL(browser(), url);
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(0, GetMediaLicenseCount());
ExpectCookieTreeModelCount(0);
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
SetDataForType(kMediaLicenseType);
EXPECT_EQ(0, GetSiteDataCount());
EXPECT_EQ(1, GetMediaLicenseCount());
ExpectCookieTreeModelCount(1);
EXPECT_TRUE(HasDataForType(kMediaLicenseType));
}
// Create and save a second media license, and then verify that timed deletion
// selects the correct license to delete.
IN_PROC_BROWSER_TEST_F(BrowsingDataRemoverBrowserTest,
MediaLicenseTimedDeletion) {
const std::string kMediaLicenseType = "MediaLicense";
// As the PRE_ test should run first, there should be one media license
// still stored. The time of it's creation should be sometime before
// this test starts. We can't see the license, since it's stored for a
// different origin (but we can delete it).
const base::Time start = base::Time::Now();
LOG(INFO) << "MediaLicenseTimedDeletion starting @ " << start;
EXPECT_EQ(1, GetMediaLicenseCount());
GURL url =
embedded_test_server()->GetURL("/browsing_data/media_license.html");
ui_test_utils::NavigateToURL(browser(), url);
// This test should use a different domain than the PRE_ test, so there
// should be no existing media license for it.
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
#if defined(OS_MACOSX)
// On some Macs the file system uses second granularity. So before
// creating the second license, delay for 1 second so that the new
// license's time is not the same second as |start|.
base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(1));
#endif
// Create a media license for this domain.
SetDataForType(kMediaLicenseType);
EXPECT_EQ(2, GetMediaLicenseCount());
EXPECT_TRUE(HasDataForType(kMediaLicenseType));
// Try to remove the Media Licenses using a time frame up until the start
// of this test, which should only delete the media license created by
// the PRE_ test.
RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES,
base::Time(), start);
EXPECT_EQ(1, GetMediaLicenseCount());
EXPECT_TRUE(HasDataForType(kMediaLicenseType));
// Now try with a time range that includes the current time, which should
// clear the media license created as part of this test.
RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES,
base::Time(), base::Time::Now());
EXPECT_EQ(0, GetMediaLicenseCount());
ExpectCookieTreeModelCount(0);
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
}
#endif // BUILDFLAG(ENABLE_LIBRARY_CDMS)
const std::vector<std::string> kStorageTypes{
"Cookie", "LocalStorage", "FileSystem", "SessionStorage",
"IndexedDb", "WebSql", "ServiceWorker", "CacheStorage",
......
<html>
<script>
function success_() {
domAutomationController.send(true);
}
function failure_() {
domAutomationController.send(false);
}
// EME creates session IDs dynamically, so we have no idea what it will be.
// As the tests only need to create a single session, keep track of the
// last session ID created.
var savedSessionId = 'unknown';
function createPersistentSession() {
// This function creates a persistent-license type session, and resolves
// with the created session object on success.
return navigator.requestMediaKeySystemAccess(
'org.chromium.externalclearkey', [{
initDataTypes: ['keyids'],
audioCapabilities: [
// Include a set of codecs that should cover all user agents.
{contentType: 'audio/mp4; codecs="mp4a.40.2"'},
{contentType: 'audio/webm; codecs="opus"'}
],
persistentState: 'required',
sessionTypes: ['persistent-license'],
}])
.then(function(access) {
return access.createMediaKeys();
})
.then(function(mediaKeys) {
return mediaKeys.createSession('persistent-license');
});
}
function handleMessageEvent(e) {
var session = e.target;
var te = new TextEncoder();
var license = te.encode(
'{"keys":[{"kty":"oct","k":"tQ0bJVWb6b0KPL6KtZIy_A","kid":"LwVHf8JLtPrv2GUXFW2v_A"}],"type":"persistent-license"}');
savedSessionId = session.sessionId;
session.update(license).then(success_, failure_);
}
function setMediaLicense() {
var te = new TextEncoder();
var initData = te.encode('{"kids":["LwVHf8JLtPrv2GUXFW2v_A"]}');
createPersistentSession().then(function(session) {
// generateRequest() will trigger a 'message' event, which we need to
// wait for in order to call update() which provides the license.
session.addEventListener('message', handleMessageEvent, false);
return session.generateRequest('keyids', initData);
})
// Success is reported from handleMessageEvent().
.catch(failure_);
}
function hasMediaLicense() {
createPersistentSession().then(function(session) {
return session.load(savedSessionId);
})
.then(function(result) {
// |result| is a boolean, indicating if the session was loaded or not.
domAutomationController.send(result);
})
.catch(failure_);
}
</script>
<body>
This page is used to test creation and deletion of Media Licenses.
The functions are called from BrowsingDataRemoverBrowserTest::HasDataForType
and BrowsingDataRemoverBrowserTest::SetDataForType.
</body>
</html>
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment