Commit 9efc6c3e 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.
>
> 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.

This reverts commit b6bfa2b7.

BUG=808690
TEST=new browser_tests pass

Change-Id: Iad919ec23bf157a9bc4af3e6d54af2b28fdc217e
Reviewed-on: https://chromium-review.googlesource.com/c/1354498Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Commit-Queue: John Rummell <jrummell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#612301}
parent fb0cacc9
......@@ -63,6 +63,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"
......@@ -79,6 +80,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;
......@@ -280,14 +290,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() {
......@@ -351,16 +354,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();
......@@ -446,6 +455,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()))
......@@ -520,6 +553,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;
};
......@@ -1059,6 +1111,130 @@ 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);
#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
// This test should use a different domain than the PRE_ test, so there
// should be no existing media license for it.
// Note that checking HasDataForType() may result in an empty file being
// created. Deleting licenses checks for any file within the time range
// specified in order to delete all the files for the domain, so this may
// cause problems (especially with Macs that use second granularity).
// http://crbug.com/909829.
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
// Create a media license for this domain.
SetDataForType(kMediaLicenseType);
EXPECT_EQ(2, GetMediaLicenseCount());
EXPECT_TRUE(HasDataForType(kMediaLicenseType));
// As Clear Browsing Data typically deletes recent data (e.g. last hour,
// last day, etc.), try to remove the Media Licenses created since the
// the start of this test, which should only delete the just created
// media license, and leave the one created by the PRE_ test.
RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES, start);
EXPECT_EQ(1, GetMediaLicenseCount());
EXPECT_FALSE(HasDataForType(kMediaLicenseType));
// Now try with a time range that includes all time, which should
// clear the media license created by the PRE_ test.
RemoveAndWait(content::BrowsingDataRemover::DATA_TYPE_MEDIA_LICENSES);
EXPECT_EQ(0, GetMediaLicenseCount());
ExpectCookieTreeModelCount(0);
}
#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 = 'UnknownSessionId';
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