Add an experimental "feature" to disable the media cache.

When enabled, a Profile's media URLRequestContext will just use the
same disk cache as the main one. Also affect App Media
URLRequestContexts.

Bug: 789657
Change-Id: I4150324ad84c1679495bd512dd0231edb30c733b
Reviewed-on: https://chromium-review.googlesource.com/1064858
Reviewed-by: Maks Orlovich <morlovich@chromium.org>
Commit-Queue: Matt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#559712}
diff --git a/chrome/browser/profiles/profile_browsertest.cc b/chrome/browser/profiles/profile_browsertest.cc
index beb7eb0..6f6b923 100644
--- a/chrome/browser/profiles/profile_browsertest.cc
+++ b/chrome/browser/profiles/profile_browsertest.cc
@@ -82,13 +82,15 @@
   TestURLFetcherDelegate(
       scoped_refptr<net::URLRequestContextGetter> context_getter,
       const GURL& url,
-      net::URLRequestStatus expected_request_status)
+      net::URLRequestStatus expected_request_status,
+      int load_flags = net::LOAD_NORMAL)
       : expected_request_status_(expected_request_status),
         is_complete_(false),
         fetcher_(net::URLFetcher::Create(url,
                                          net::URLFetcher::GET,
                                          this,
                                          TRAFFIC_ANNOTATION_FOR_TESTS)) {
+    fetcher_->SetLoadFlags(load_flags);
     fetcher_->SetRequestContext(context_getter.get());
     fetcher_->Start();
   }
@@ -889,4 +891,79 @@
   base::FilePath home;
   base::PathService::Get(base::DIR_HOME, &home);
   ASSERT_EQ(profile_impl->last_selected_directory(), home);
-}
\ No newline at end of file
+}
+
+// Verifies that, by default, there's a separate disk cache for media files.
+IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, SeparateMediaCache) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Do a normal load using the media URLRequestContext, populating the cache.
+  TestURLFetcherDelegate url_fetcher_delegate(
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+          ->GetMediaURLRequestContext(),
+      embedded_test_server()->GetURL("/cachetime"), net::URLRequestStatus(),
+      net::LOAD_NORMAL);
+  url_fetcher_delegate.WaitForCompletion();
+
+  // Cache-only load from the main request context should fail, since the media
+  // request context has its own cache.
+  TestURLFetcherDelegate url_fetcher_delegate2(
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+          ->GetURLRequestContext(),
+      embedded_test_server()->GetURL("/cachetime"),
+      net::URLRequestStatus(net::URLRequestStatus::FAILED, net::ERR_CACHE_MISS),
+      net::LOAD_ONLY_FROM_CACHE);
+  url_fetcher_delegate2.WaitForCompletion();
+
+  // Cache-only load from the media request context should succeed.
+  TestURLFetcherDelegate url_fetcher_delegate3(
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+          ->GetMediaURLRequestContext(),
+      embedded_test_server()->GetURL("/cachetime"), net::URLRequestStatus(),
+      net::LOAD_ONLY_FROM_CACHE);
+  url_fetcher_delegate3.WaitForCompletion();
+}
+
+class ProfileWithoutMediaCacheBrowserTest : public ProfileBrowserTest {
+ public:
+  ProfileWithoutMediaCacheBrowserTest() {
+    feature_list_.InitAndEnableFeature(features::kUseSameCacheForMedia);
+  }
+
+  ~ProfileWithoutMediaCacheBrowserTest() override {}
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+// Verifies that when kUseSameCacheForMedia is enabled, the media
+// URLRequestContext uses the same disk cache as the main one.
+IN_PROC_BROWSER_TEST_F(ProfileWithoutMediaCacheBrowserTest,
+                       NoSeparateMediaCache) {
+  ASSERT_TRUE(embedded_test_server()->Start());
+
+  // Do a normal load using the media URLRequestContext, populating the cache.
+  TestURLFetcherDelegate url_fetcher_delegate(
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+          ->GetMediaURLRequestContext(),
+      embedded_test_server()->GetURL("/cachetime"), net::URLRequestStatus(),
+      net::LOAD_NORMAL);
+  url_fetcher_delegate.WaitForCompletion();
+
+  // Cache-only load from the main request context should succeed, since the
+  // media request context uses the same cache.
+  TestURLFetcherDelegate url_fetcher_delegate2(
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+          ->GetURLRequestContext(),
+      embedded_test_server()->GetURL("/cachetime"), net::URLRequestStatus(),
+      net::LOAD_ONLY_FROM_CACHE);
+  url_fetcher_delegate2.WaitForCompletion();
+
+  // Cache-only load from the media request context should also succeed.
+  TestURLFetcherDelegate url_fetcher_delegate3(
+      content::BrowserContext::GetDefaultStoragePartition(browser()->profile())
+          ->GetMediaURLRequestContext(),
+      embedded_test_server()->GetURL("/cachetime"), net::URLRequestStatus(),
+      net::LOAD_ONLY_FROM_CACHE);
+  url_fetcher_delegate3.WaitForCompletion();
+}
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 328f490..7bf2b29 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -11,6 +11,7 @@
 
 #include "base/bind.h"
 #include "base/command_line.h"
+#include "base/feature_list.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/metrics/field_trial.h"
@@ -36,6 +37,7 @@
 #include "chrome/browser/previews/previews_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -674,6 +676,8 @@
   // Copy most state from the original context.
   MediaRequestContext* context = new MediaRequestContext(name);
   context->CopyFrom(original_context);
+  if (base::FeatureList::IsEnabled(features::kUseSameCacheForMedia))
+    return context;
 
   // For in-memory context, return immediately after creating the new
   // context before attaching a separate cache. It is important to return
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 86575e8..2b69b23 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -609,6 +609,10 @@
                                               base::FEATURE_ENABLED_BY_DEFAULT};
 #endif
 
+// Enables using the main HTTP cache for media files as well.
+const base::Feature kUseSameCacheForMedia{"UseSameCacheForMedia",
+                                          base::FEATURE_DISABLED_BY_DEFAULT};
+
 #if !defined(OS_ANDROID)
 // Enables or disables Voice Search on the local NTP.
 const base::Feature kVoiceSearchOnLocalNtp{"VoiceSearchOnLocalNtp",
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 7b53d68..3019fa4 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -331,6 +331,8 @@
 extern const base::Feature kUserActivityEventLogging;
 #endif
 
+extern const base::Feature kUseSameCacheForMedia;
+
 #if !defined(OS_ANDROID)
 extern const base::Feature kVoiceSearchOnLocalNtp;
 #endif