Backed out 7 changesets (bug 1540573) for causing bug 1548441
authorAndreea Pavel <apavel@mozilla.com>
Fri, 03 May 2019 20:35:27 +0300
changeset 531346 0bb9da8fe6af8020f0acd8b7fc3a768397f31562
parent 531345 6586c6e89759b74d65d511dd1de4eab60c2482fb
child 531347 adb1c1a79a40102f634a419b6c5d1245de474d67
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1540573, 1548441
milestone68.0a1
backs outdd882b8cd73efd56bc92aa1467139699e7e1db6d
b10d2cae45f2e0ea7809d60c54e80784ba871429
270a8917377f46e18a9948c3335bfbd9b8192449
3db059b34e40b810394a4ef355534fe707504699
fe196b2dfc6247bd8f9ec102aeb9927fffc1af87
1bde5042e507bbc2a96809c6a35f1b69e2e016bc
4ff116b9d729055b866bb9fadf35065bba8f1c63
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 7 changesets (bug 1540573) for causing bug 1548441 Backed out changeset dd882b8cd73e (bug 1540573) Backed out changeset b10d2cae45f2 (bug 1540573) Backed out changeset 270a8917377f (bug 1540573) Backed out changeset 3db059b34e40 (bug 1540573) Backed out changeset fe196b2dfc62 (bug 1540573) Backed out changeset 1bde5042e507 (bug 1540573) Backed out changeset 4ff116b9d729 (bug 1540573)
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/media/ChannelMediaDecoder.cpp
dom/media/FileBlockCache.cpp
dom/media/FileBlockCache.h
dom/media/MediaBlockCacheBase.h
dom/media/MediaCache.cpp
dom/media/MemoryBlockCache.h
dom/media/VideoUtils.cpp
dom/media/VideoUtils.h
dom/security/test/csp/test_CSP.html
dom/security/test/csp/test_redirects.html
mobile/android/app/mobile.js
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
modules/libpref/init/StaticPrefList.h
testing/profiles/unittest-required/user.js
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2450,53 +2450,37 @@ void HTMLMediaElement::ResumeLoad(Preloa
     }
   }
 }
 
 bool HTMLMediaElement::AllowedToPlay() const {
   return AutoplayPolicy::IsAllowedToPlay(*this);
 }
 
-uint32_t HTMLMediaElement::GetPreloadDefault() const {
-  if (mMediaSource) {
-    return HTMLMediaElement::PRELOAD_ATTR_METADATA;
-  }
-  if (OnCellularConnection()) {
-    return Preferences::GetInt("media.preload.default.cellular",
-                               HTMLMediaElement::PRELOAD_ATTR_NONE);
-  }
-  return Preferences::GetInt("media.preload.default",
-                             HTMLMediaElement::PRELOAD_ATTR_METADATA);
-}
-
-uint32_t HTMLMediaElement::GetPreloadDefaultAuto() const {
-  if (OnCellularConnection()) {
-    return Preferences::GetInt("media.preload.auto.cellular",
-                               HTMLMediaElement::PRELOAD_ATTR_METADATA);
-  }
-  return Preferences::GetInt("media.preload.auto",
-                             HTMLMediaElement::PRELOAD_ENOUGH);
-}
-
 void HTMLMediaElement::UpdatePreloadAction() {
   PreloadAction nextAction = PRELOAD_UNDEFINED;
   // If autoplay is set, or we're playing, we should always preload data,
   // as we'll need it to play.
   if ((AutoplayPolicy::IsAllowedToPlay(*this) &&
        HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay)) ||
       !mPaused) {
     nextAction = HTMLMediaElement::PRELOAD_ENOUGH;
   } else {
     // Find the appropriate preload action by looking at the attribute.
     const nsAttrValue* val =
         mAttrs.GetAttr(nsGkAtoms::preload, kNameSpaceID_None);
     // MSE doesn't work if preload is none, so it ignores the pref when src is
     // from MSE.
-    uint32_t preloadDefault = GetPreloadDefault();
-    uint32_t preloadAuto = GetPreloadDefaultAuto();
+    uint32_t preloadDefault =
+        mMediaSource
+            ? HTMLMediaElement::PRELOAD_ATTR_METADATA
+            : Preferences::GetInt("media.preload.default",
+                                  HTMLMediaElement::PRELOAD_ATTR_METADATA);
+    uint32_t preloadAuto = Preferences::GetInt(
+        "media.preload.auto", HTMLMediaElement::PRELOAD_ENOUGH);
     if (!val) {
       // Attribute is not set. Use the preload action specified by the
       // media.preload.default pref, or just preload metadata if not present.
       nextAction = static_cast<PreloadAction>(preloadDefault);
     } else if (val->Type() == nsAttrValue::eEnum) {
       PreloadAttrValue attr =
           static_cast<PreloadAttrValue>(val->GetEnumValue());
       if (attr == HTMLMediaElement::PRELOAD_ATTR_EMPTY ||
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -1732,19 +1732,16 @@ class HTMLMediaElement : public nsGeneri
 
  private:
   already_AddRefed<PlayPromise> CreatePlayPromise(ErrorResult& aRv) const;
 
   void UpdateHadAudibleAutoplayState();
 
   virtual void MaybeBeginCloningVisually(){};
 
-  uint32_t GetPreloadDefault() const;
-  uint32_t GetPreloadDefaultAuto() const;
-
   /**
    * This function is called by AfterSetAttr and OnAttrSetButNotChanged.
    * It will not be called if the value is being unset.
    *
    * @param aNamespaceID the namespace of the attr being set
    * @param aName the localname of the attribute being set
    * @param aNotify Whether we plan to notify document observers.
    */
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2024,27 +2024,16 @@ mozilla::ipc::IPCResult ContentChild::Re
   }
 
   static_cast<loader::ScriptCacheChild*>(actor)->Init(fd, wantCacheData);
   return IPC_OK();
 }
 
 PNeckoChild* ContentChild::AllocPNeckoChild() { return new NeckoChild(); }
 
-mozilla::ipc::IPCResult ContentChild::RecvNetworkLinkTypeChange(
-    const uint32_t& aType) {
-  mNetworkLinkType = aType;
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (obs) {
-    obs->NotifyObservers(nullptr, "contentchild:network-link-type-changed",
-                         nullptr);
-  }
-  return IPC_OK();
-}
-
 bool ContentChild::DeallocPNeckoChild(PNeckoChild* necko) {
   delete necko;
   return true;
 }
 
 PPrintingChild* ContentChild::AllocPPrintingChild() {
   // The ContentParent should never attempt to allocate the nsPrintingProxy,
   // which implements PPrintingChild. Instead, the nsPrintingProxy service is
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -484,19 +484,16 @@ class ContentChild final : public PConte
 
   mozilla::ipc::IPCResult RecvActivate(PBrowserChild* aTab);
 
   mozilla::ipc::IPCResult RecvDeactivate(PBrowserChild* aTab);
 
   mozilla::ipc::IPCResult RecvRefreshScreens(
       nsTArray<ScreenDetails>&& aScreens);
 
-  mozilla::ipc::IPCResult RecvNetworkLinkTypeChange(const uint32_t& aType);
-  uint32_t NetworkLinkType() const { return mNetworkLinkType; }
-
   // Get the directory for IndexedDB files. We query the parent for this and
   // cache the value
   nsString& GetIndexedDBPath();
 
   ContentParentId GetID() const { return mID; }
 
 #if defined(XP_WIN) && defined(ACCESSIBILITY)
   uint32_t GetChromeMainThreadId() const { return mMainChromeTid; }
@@ -809,18 +806,16 @@ class ContentChild final : public PConte
   mozilla::Atomic<bool> mShuttingDown;
 
 #ifdef NIGHTLY_BUILD
   // NOTE: This member is atomic because it can be accessed from
   // off-main-thread.
   mozilla::Atomic<uint32_t> mPendingInputEvents;
 #endif
 
-  uint32_t mNetworkLinkType = 0;
-
   DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
 };
 
 uint64_t NextWindowID();
 
 }  // namespace dom
 }  // namespace mozilla
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -153,17 +153,16 @@
 #include "nsIGfxInfo.h"
 #include "nsIIdleService.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsILocalStorageManager.h"
 #include "nsIMemoryInfoDumper.h"
 #include "nsIMemoryReporter.h"
 #include "nsIMozBrowserFrame.h"
 #include "nsIMutable.h"
-#include "nsINetworkLinkService.h"
 #include "nsIObserverService.h"
 #include "nsIParentChannel.h"
 #include "nsIRemoteWindowContext.h"
 #include "nsIScriptError.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsISearchService.h"
 #include "nsIServiceWorkerManager.h"
 #include "nsISiteSecurityService.h"
@@ -610,17 +609,16 @@ static const char* sObserverTopics[] = {
     "a11y-init-or-shutdown",
 #endif
     "cacheservice:empty-cache",
     "intl:app-locales-changed",
     "intl:requested-locales-changed",
     "cookie-changed",
     "private-cookie-changed",
     "clear-site-data-reload-needed",
-    NS_NETWORK_LINK_TYPE_TOPIC,
 };
 
 #if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
 bool ContentParent::sEarlySandboxInit = false;
 #endif
 
 // PreallocateProcess is called by the PreallocatedProcessManager.
 // ContentParent then takes this process back within GetNewOrUsedBrowserProcess.
@@ -3121,40 +3119,20 @@ ContentParent::Observe(nsISupports* aSub
       cs->RemoveCookie(xpcCookie);
     } else if ((!nsCRT::strcmp(aData, u"added")) ||
                (!nsCRT::strcmp(aData, u"changed"))) {
       cs->AddCookie(xpcCookie);
     }
   } else if (!strcmp(aTopic, "clear-site-data-reload-needed")) {
     // Rebroadcast "clear-site-data-reload-needed".
     Unused << SendClearSiteDataReloadNeeded(nsString(aData));
-  } else if (!strcmp(aTopic, NS_NETWORK_LINK_TYPE_TOPIC)) {
-    UpdateNetworkLinkType();
-  }
-
+  }
   return NS_OK;
 }
 
-void ContentParent::UpdateNetworkLinkType() {
-  nsresult rv;
-  nsCOMPtr<nsINetworkLinkService> nls =
-      do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID, &rv);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  uint32_t linkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
-  rv = nls->GetLinkType(&linkType);
-  if (NS_FAILED(rv)) {
-    return;
-  }
-
-  Unused << SendNetworkLinkTypeChange(linkType);
-}
-
 NS_IMETHODIMP
 ContentParent::GetInterface(const nsIID& aIID, void** aResult) {
   NS_ENSURE_ARG_POINTER(aResult);
 
   if (aIID.Equals(NS_GET_IID(nsIMessageSender))) {
     nsCOMPtr<nsIMessageSender> mm = GetMessageManager();
     mm.forget(aResult);
     return NS_OK;
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1208,18 +1208,16 @@ class ContentParent final : public PCont
 
   bool IsRecordingOrReplaying() const {
     return mRecordReplayState != eNotRecordingOrReplaying;
   }
 
   void OnBrowsingContextGroupSubscribe(BrowsingContextGroup* aGroup);
   void OnBrowsingContextGroupUnsubscribe(BrowsingContextGroup* aGroup);
 
-  void UpdateNetworkLinkType();
-
  private:
   // Released in ActorDestroy; deliberately not exposed to the CC.
   RefPtr<ContentParent> mSelfRef;
 
   // If you add strong pointers to cycle collected objects here, be sure to
   // release these objects in ShutDownProcess.  See the comment there for more
   // details.
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -425,18 +425,16 @@ child:
       Endpoint<PCompositorManagerChild> compositor,
       Endpoint<PImageBridgeChild> bridge,
       Endpoint<PVRManagerChild> vr,
       Endpoint<PVideoDecoderManagerChild> video,
       uint32_t[] namespaces);
 
     async AudioDefaultDeviceChange();
 
-    async NetworkLinkTypeChange(uint32_t type);
-
     // Re-create the rendering stack for a device reset.
     async ReinitRenderingForDeviceReset();
 
     /**
      * Enable system-level sandboxing features, if available.  Can
      * usually only be performed zero or one times.  The child may
      * abnormally exit if this fails; the details are OS-specific.
      */
--- a/dom/media/ChannelMediaDecoder.cpp
+++ b/dom/media/ChannelMediaDecoder.cpp
@@ -6,17 +6,16 @@
 
 #include "ChannelMediaDecoder.h"
 #include "DecoderTraits.h"
 #include "MediaDecoderStateMachine.h"
 #include "MediaFormatReader.h"
 #include "BaseMediaResource.h"
 #include "MediaShutdownManager.h"
 #include "mozilla/StaticPrefs.h"
-#include "VideoUtils.h"
 
 namespace mozilla {
 
 extern LazyLogModule gMediaDecoderLog;
 #define LOG(x, ...) \
   DDMOZ_LOG(gMediaDecoderLog, LogLevel::Debug, x, ##__VA_ARGS__)
 
 ChannelMediaDecoder::ResourceCallback::ResourceCallback(
@@ -454,34 +453,32 @@ MediaStatistics ChannelMediaDecoder::Get
   result.mPlaybackRateReliable = aInfo.mReliable;
   result.mPlaybackPosition = aPlaybackPosition;
   return result;
 }
 
 bool ChannelMediaDecoder::ShouldThrottleDownload(
     const MediaStatistics& aStats) {
   // We throttle the download if either the throttle override pref is set
-  // (so that we always throttle at the readahead limit on mobile if using
-  // a cellular network) or if the download is fast enough that there's no
-  // concern about playback being interrupted.
+  // (so that we can always throttle in Firefox on mobile) or if the download
+  // is fast enough that there's no concern about playback being interrupted.
   MOZ_ASSERT(NS_IsMainThread());
   NS_ENSURE_TRUE(GetStateMachine(), false);
 
   int64_t length = aStats.mTotalBytes;
   if (length > 0 &&
       length <= int64_t(StaticPrefs::MediaMemoryCacheMaxSize()) * 1024) {
     // Don't throttle the download of small resources. This is to speed
     // up seeking, as seeks into unbuffered ranges would require starting
     // up a new HTTP transaction, which adds latency.
     return false;
   }
 
-  if (OnCellularConnection() &&
-      Preferences::GetBool(
-          "media.throttle-cellular-regardless-of-download-rate", false)) {
+  if (Preferences::GetBool("media.throttle-regardless-of-download-rate",
+                           false)) {
     return true;
   }
 
   if (!aStats.mDownloadRateReliable || !aStats.mPlaybackRateReliable) {
     return false;
   }
   uint32_t factor =
       std::max(2u, Preferences::GetUint("media.throttle-factor", 2));
--- a/dom/media/FileBlockCache.cpp
+++ b/dom/media/FileBlockCache.cpp
@@ -120,36 +120,39 @@ void FileBlockCache::Flush() {
     MutexAutoLock mon(self->mDataMutex);
     // Just discard pending changes, assume MediaCache won't read from
     // blocks it hasn't written to.
     self->mChangeIndexList.clear();
     self->mBlockChanges.Clear();
   }));
 }
 
-size_t FileBlockCache::GetMaxBlocks(size_t aCacheSizeInKB) const {
+int32_t FileBlockCache::GetMaxBlocks() const {
   // We look up the cache size every time. This means dynamic changes
   // to the pref are applied.
+  const uint32_t cacheSizeKb =
+      std::min(StaticPrefs::MediaCacheSize(), uint32_t(INT32_MAX) * 2);
   // Ensure we can divide BLOCK_SIZE by 1024.
   static_assert(MediaCacheStream::BLOCK_SIZE % 1024 == 0,
                 "BLOCK_SIZE should be a multiple of 1024");
   // Ensure BLOCK_SIZE/1024 is at least 2.
   static_assert(MediaCacheStream::BLOCK_SIZE / 1024 >= 2,
                 "BLOCK_SIZE / 1024 should be at least 2");
   // Ensure we can convert BLOCK_SIZE/1024 to a uint32_t without truncation.
   static_assert(MediaCacheStream::BLOCK_SIZE / 1024 <= int64_t(UINT32_MAX),
                 "BLOCK_SIZE / 1024 should be at most UINT32_MAX");
   // Since BLOCK_SIZE is a strict multiple of 1024,
-  // aCacheSizeInKB * 1024 / BLOCK_SIZE == aCacheSizeInKB / (BLOCK_SIZE /
-  // 1024), but the latter formula avoids a potential overflow from `* 1024`.
+  // cacheSizeKb * 1024 / BLOCK_SIZE == cacheSizeKb / (BLOCK_SIZE / 1024),
+  // but the latter formula avoids a potential overflow from `* 1024`.
   // And because BLOCK_SIZE/1024 is at least 2, the maximum cache size
   // INT32_MAX*2 will give a maxBlocks that can fit in an int32_t.
-  constexpr size_t blockSizeKb = size_t(MediaCacheStream::BLOCK_SIZE / 1024);
-  const size_t maxBlocks = aCacheSizeInKB / blockSizeKb;
-  return std::max(maxBlocks, size_t(1));
+  constexpr uint32_t blockSizeKb =
+      uint32_t(MediaCacheStream::BLOCK_SIZE / 1024);
+  const int32_t maxBlocks = int32_t(cacheSizeKb / blockSizeKb);
+  return std::max(maxBlocks, int32_t(1));
 }
 
 FileBlockCache::FileBlockCache()
     : mFileMutex("MediaCache.Writer.IO.Mutex"),
       mFD(nullptr),
       mFDCurrentPos(0),
       mDataMutex("MediaCache.Writer.Data.Mutex"),
       mIsWriteScheduled(false),
--- a/dom/media/FileBlockCache.h
+++ b/dom/media/FileBlockCache.h
@@ -63,17 +63,17 @@ class FileBlockCache : public MediaBlock
   // Launch thread and open temporary file.
   nsresult Init() override;
 
   // Will discard pending changes if any.
   void Flush() override;
 
   // Maximum number of blocks allowed in this block cache.
   // Calculated from "media.cache_size" pref.
-  size_t GetMaxBlocks(size_t aCacheSizeInKB) const override;
+  int32_t GetMaxBlocks() const override;
 
   // Can be called on any thread. This defers to a non-main thread.
   nsresult WriteBlock(uint32_t aBlockIndex, Span<const uint8_t> aData1,
                       Span<const uint8_t> aData2) override;
 
   // Synchronously reads data from file. May read from file or memory
   // depending on whether written blocks have been flushed to file yet.
   // Not recommended to be called from the main thread, as can cause jank.
--- a/dom/media/MediaBlockCacheBase.h
+++ b/dom/media/MediaBlockCacheBase.h
@@ -51,17 +51,17 @@ class MediaBlockCacheBase {
   virtual nsresult Init() = 0;
 
   // Erase data and discard pending changes to reset the cache to its pristine
   // state as it was after Init().
   virtual void Flush() = 0;
 
   // Maximum number of blocks expected in this block cache. (But allow overflow
   // to accomodate incoming traffic before MediaCache can handle it.)
-  virtual size_t GetMaxBlocks(size_t aCacheSizeInKiB) const = 0;
+  virtual int32_t GetMaxBlocks() const = 0;
 
   // Can be called on any thread. This defers to a non-main thread.
   virtual nsresult WriteBlock(uint32_t aBlockIndex, Span<const uint8_t> aData1,
                               Span<const uint8_t> aData2) = 0;
 
   // Synchronously reads data from file. May read from file or memory
   // depending on whether written blocks have been flushed to file yet.
   // Not recommended to be called from the main thread, as can cause jank.
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -6,37 +6,34 @@
 
 #include "MediaCache.h"
 
 #include "ChannelMediaResource.h"
 #include "FileBlockCache.h"
 #include "MediaBlockCacheBase.h"
 #include "MediaResource.h"
 #include "MemoryBlockCache.h"
-#include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ErrorNames.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/SystemGroup.h"
 #include "mozilla/Telemetry.h"
 #include "nsContentUtils.h"
-#include "nsINetworkLinkService.h"
 #include "nsIObserverService.h"
 #include "nsIPrincipal.h"
 #include "nsPrintfCString.h"
 #include "nsProxyRelease.h"
 #include "nsThreadUtils.h"
 #include "prio.h"
-#include "VideoUtils.h"
 #include <algorithm>
 
 namespace mozilla {
 
 #undef LOG
 #undef LOGI
 #undef LOGE
 LazyLogModule gMediaCacheLog("MediaCache");
@@ -112,27 +109,24 @@ StaticRefPtr<MediaCacheFlusher> MediaCac
 NS_IMPL_ISUPPORTS(MediaCacheFlusher, nsIObserver, nsISupportsWeakReference)
 
 /* static */
 void MediaCacheFlusher::RegisterMediaCache(MediaCache* aMediaCache) {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   if (!gMediaCacheFlusher) {
     gMediaCacheFlusher = new MediaCacheFlusher();
+
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
     if (observerService) {
       observerService->AddObserver(gMediaCacheFlusher, "last-pb-context-exited",
                                    true);
       observerService->AddObserver(gMediaCacheFlusher,
                                    "cacheservice:empty-cache", true);
-      observerService->AddObserver(
-          gMediaCacheFlusher, "contentchild:network-link-type-changed", true);
-      observerService->AddObserver(gMediaCacheFlusher,
-                                   NS_NETWORK_LINK_TYPE_TOPIC, true);
     }
   }
 
   gMediaCacheFlusher->mMediaCaches.AppendElement(aMediaCache);
 }
 
 /* static */
 void MediaCacheFlusher::UnregisterMediaCache(MediaCache* aMediaCache) {
@@ -243,20 +237,16 @@ class MediaCache {
 
   mozilla::Monitor& Monitor() {
     // This method should only be called outside the main thread.
     // The MOZ_DIAGNOSTIC_ASSERT(!NS_IsMainThread()) assertion should be
     // re-added as part of bug 1464045
     return mMonitor;
   }
 
-  // Updates the cache size, readahead limit, and resume threshold, based on
-  // whether we're on a cellular connection or not. Main thread only.
-  static void UpdateGeometryStatics();
-
   /**
    * An iterator that makes it easy to iterate through all streams that
    * have a given resource ID and are not closed.
    * Must be used while holding the media cache lock.
    */
   class ResourceStreamIterator {
    public:
     ResourceStreamIterator(MediaCache* aMediaCache, int64_t aResourceID)
@@ -287,17 +277,16 @@ class MediaCache {
 #ifdef DEBUG
         ,
         mInUpdate(false)
 #endif
   {
     NS_ASSERTION(NS_IsMainThread(), "Only construct MediaCache on main thread");
     MOZ_COUNT_CTOR(MediaCache);
     MediaCacheFlusher::RegisterMediaCache(this);
-    UpdateGeometryStatics();
   }
 
   ~MediaCache() {
     NS_ASSERTION(NS_IsMainThread(), "Only destroy MediaCache on main thread");
     if (this == gMediaCache) {
       LOG("~MediaCache(Global file-backed MediaCache)");
       // This is the file-backed MediaCache, reset the global pointer.
       gMediaCache = nullptr;
@@ -319,31 +308,16 @@ class MediaCache {
     MediaCacheFlusher::UnregisterMediaCache(this);
     NS_ASSERTION(mStreams.IsEmpty(), "Stream(s) still open!");
     Truncate();
     NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?");
 
     MOZ_COUNT_DTOR(MediaCache);
   }
 
-  static size_t CacheSize() {
-    MOZ_ASSERT(sThread->IsOnCurrentThread());
-    return sCacheSizeInKB;
-  }
-
-  static size_t ReadaheadLimit() {
-    MOZ_ASSERT(sThread->IsOnCurrentThread());
-    return sReadaheadLimit;
-  }
-
-  static size_t ResumeThreshold() {
-    MOZ_ASSERT(sThread->IsOnCurrentThread());
-    return sResumeThreshold;
-  }
-
   // Find a free or reusable block and return its index. If there are no
   // free blocks and no reusable blocks, add a new block to the cache
   // and return it. Can return -1 on OOM.
   int32_t FindBlockForIncomingData(AutoLock&, TimeStamp aNow,
                                    MediaCacheStream* aStream,
                                    int32_t aStreamBlockIndex);
   // Find a reusable block --- a free block, if there is one, otherwise
   // the reusable block with the latest predicted-next-use, or -1 if
@@ -472,21 +446,16 @@ class MediaCache {
   nsTArray<int64_t> mSuspendedStatusToNotify;
   // The thread on which we will run data callbacks from the channels.
   // Note this thread is shared among all MediaCache instances.
   static StaticRefPtr<nsIThread> sThread;
   // True if we've tried to init sThread. Note we try once only so it is safe
   // to access sThread on all threads.
   static bool sThreadInit;
 
-  // Accesson MediaCache thread only.
-  static size_t sCacheSizeInKB;
-  static size_t sReadaheadLimit;
-  static size_t sResumeThreshold;
-
  private:
   // Used by MediaCacheStream::GetDebugInfo() only for debugging.
   // Don't add new callers to this function.
   friend nsCString MediaCacheStream::GetDebugInfo();
   mozilla::Monitor& GetMonitorOnTheMainThread() {
     MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
     return mMonitor;
   }
@@ -496,47 +465,16 @@ class MediaCache {
 /* static */
 MediaCache* MediaCache::gMediaCache;
 
 /* static */
 StaticRefPtr<nsIThread> MediaCache::sThread;
 /* static */
 bool MediaCache::sThreadInit = false;
 
-/* static */ size_t MediaCache::sCacheSizeInKB = 0;
-/* static */ size_t MediaCache::sReadaheadLimit = 0;
-/* static */ size_t MediaCache::sResumeThreshold = 0;
-
-void MediaCache::UpdateGeometryStatics() {
-  NS_ASSERTION(NS_IsMainThread(),
-               "Only call on main thread");  // JNI required on Android...
-  bool cacheAggressively = !OnCellularConnection();
-  LOG("MediaCache::UpdateGeometryStatics() cacheAggressively=%d",
-      cacheAggressively);
-  // Read the prefs on the main thread, and post their value to the MediaCache
-  // thread. This ensures the values are synchronized.
-  uint32_t cacheSize = 0, readaheadLimit = 0, resumeThreshold = 0;
-  if (cacheAggressively) {
-    cacheSize = StaticPrefs::MediaCacheSize();
-    readaheadLimit = StaticPrefs::MediaCacheReadaheadLimit();
-    resumeThreshold = StaticPrefs::MediaCacheResumeThreshold();
-  } else {
-    cacheSize = StaticPrefs::MediaCacheCellularSize();
-    readaheadLimit = StaticPrefs::MediaCacheCellularReadaheadLimit();
-    resumeThreshold = StaticPrefs::MediaCacheCellularResumeThreshold();
-  }
-  nsCOMPtr<nsIRunnable> r =
-      NS_NewRunnableFunction("MediaCache::UpdateGeometryStatics", [=]() {
-        sCacheSizeInKB = cacheSize;
-        sReadaheadLimit = readaheadLimit;
-        sResumeThreshold = resumeThreshold;
-      });
-  sThread->Dispatch(r.forget());
-}
-
 NS_IMETHODIMP
 MediaCacheFlusher::Observe(nsISupports* aSubject, char const* aTopic,
                            char16_t const* aData) {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   if (strcmp(aTopic, "last-pb-context-exited") == 0) {
     for (MediaCache* mc : mMediaCaches) {
       mc->CloseStreamsForPrivateBrowsing();
@@ -544,20 +482,16 @@ MediaCacheFlusher::Observe(nsISupports* 
     return NS_OK;
   }
   if (strcmp(aTopic, "cacheservice:empty-cache") == 0) {
     for (MediaCache* mc : mMediaCaches) {
       mc->Flush();
     }
     return NS_OK;
   }
-  if (strcmp(aTopic, "contentchild:network-link-type-changed") == 0 ||
-      strcmp(aTopic, NS_NETWORK_LINK_TYPE_TOPIC) == 0) {
-    MediaCache::UpdateGeometryStatics();
-  }
   return NS_OK;
 }
 
 MediaCacheStream::MediaCacheStream(ChannelMediaResource* aClient,
                                    bool aIsPrivateBrowsing)
     : mMediaCache(nullptr),
       mClient(aClient),
       mIsTransportSeekable(false),
@@ -888,18 +822,17 @@ int32_t MediaCache::FindBlockForIncoming
       FindReusableBlock(aLock, aNow, aStream, aStreamBlockIndex, INT32_MAX);
 
   if (blockIndex < 0 || !IsBlockFree(blockIndex)) {
     // The block returned is already allocated.
     // Don't reuse it if a) there's room to expand the cache or
     // b) the data we're going to store in the free block is not higher
     // priority than the data already stored in the free block.
     // The latter can lead us to go over the cache limit a bit.
-    if ((mIndex.Length() <
-             uint32_t(mBlockCache->GetMaxBlocks(MediaCache::CacheSize())) ||
+    if ((mIndex.Length() < uint32_t(mBlockCache->GetMaxBlocks()) ||
          blockIndex < 0 ||
          PredictNextUseForIncomingData(aLock, aStream) >=
              PredictNextUse(aLock, aNow, blockIndex))) {
       blockIndex = mIndex.Length();
       if (!mIndex.AppendElement()) return -1;
       mIndexWatermark = std::max(mIndexWatermark, blockIndex + 1);
       mFreeBlocks.AddFirstBlock(blockIndex);
       return blockIndex;
@@ -1217,17 +1150,17 @@ void MediaCache::Update() {
   // stream, decoder and element code.
   AutoTArray<StreamAction, 10> actions;
 
   mUpdateQueued = false;
 #ifdef DEBUG
   mInUpdate = true;
 #endif
 
-  int32_t maxBlocks = mBlockCache->GetMaxBlocks(MediaCache::CacheSize());
+  int32_t maxBlocks = mBlockCache->GetMaxBlocks();
   TimeStamp now = TimeStamp::Now();
 
   int32_t freeBlockCount = mFreeBlocks.GetCount();
   TimeDuration latestPredictedUseForOverflow = 0;
   if (mIndex.Length() > uint32_t(maxBlocks)) {
     // Try to trim back the cache to its desired maximum size. The cache may
     // have overflowed simply due to data being received when we have
     // no blocks in the main part of the cache that are free or lower
@@ -1338,18 +1271,18 @@ void MediaCache::Update() {
   TimeDuration latestNextUse;
   if (freeBlockCount == 0) {
     int32_t reusableBlock = FindReusableBlock(lock, now, nullptr, 0, maxBlocks);
     if (reusableBlock >= 0) {
       latestNextUse = PredictNextUse(lock, now, reusableBlock);
     }
   }
 
-  int32_t resumeThreshold = MediaCache::ResumeThreshold();
-  int32_t readaheadLimit = MediaCache::ReadaheadLimit();
+  int32_t resumeThreshold = StaticPrefs::MediaCacheResumeThreshold();
+  int32_t readaheadLimit = StaticPrefs::MediaCacheReadaheadLimit();
 
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     actions.AppendElement(StreamAction{});
 
     MediaCacheStream* stream = mStreams[i];
     if (stream->mClosed) {
       LOG("Stream %p closed", stream);
       continue;
--- a/dom/media/MemoryBlockCache.h
+++ b/dom/media/MemoryBlockCache.h
@@ -40,17 +40,17 @@ class MemoryBlockCache : public MediaBlo
   // Allocate initial buffer.
   // If re-initializing, clear buffer.
   virtual nsresult Init() override;
 
   void Flush() override;
 
   // Maximum number of blocks allowed in this block cache.
   // Based on initial content length, and minimum usable block cache.
-  size_t GetMaxBlocks(size_t) const override { return mMaxBlocks; }
+  int32_t GetMaxBlocks() const override { return mMaxBlocks; }
 
   // Can be called on any thread.
   virtual nsresult WriteBlock(uint32_t aBlockIndex, Span<const uint8_t> aData1,
                               Span<const uint8_t> aData2) override;
 
   // Synchronously reads data from buffer.
   virtual nsresult Read(int64_t aOffset, uint8_t* aData, int32_t aLength,
                         int32_t* aBytes) override;
@@ -68,17 +68,17 @@ class MemoryBlockCache : public MediaBlo
   // aContentLength bytes. Buffer size can only grow.
   // Returns false if allocation failed.
   bool EnsureBufferCanContain(size_t aContentLength);
 
   // Initial content length.
   const size_t mInitialContentLength;
 
   // Maximum number of blocks that this MemoryBlockCache expects.
-  const size_t mMaxBlocks;
+  const int32_t mMaxBlocks;
 
   // Mutex which controls access to all members below.
   Mutex mMutex;
 
   nsTArray<uint8_t> mBuffer;
   bool mHasGrown = false;
 };
 
--- a/dom/media/VideoUtils.cpp
+++ b/dom/media/VideoUtils.cpp
@@ -9,31 +9,28 @@
 
 #include "CubebUtils.h"
 #include "ImageContainer.h"
 #include "MediaContainerType.h"
 #include "MediaResource.h"
 #include "TimeUnits.h"
 #include "VorbisUtils.h"
 #include "mozilla/Base64.h"
-#include "mozilla/dom/ContentChild.h"
 #include "mozilla/SharedThreadPool.h"
 #include "mozilla/StaticPrefs.h"
 #include "mozilla/SystemGroup.h"
 #include "mozilla/TaskCategory.h"
 #include "mozilla/TaskQueue.h"
 #include "mozilla/Telemetry.h"
 #include "nsCharSeparatedTokenizer.h"
 #include "nsContentTypeParser.h"
 #include "nsIConsoleService.h"
-#include "nsINetworkLinkService.h"
 #include "nsIRandomGenerator.h"
 #include "nsIServiceManager.h"
 #include "nsMathUtils.h"
-#include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 
 using layers::PlanarYCbCrImage;
 using media::TimeUnit;
 
@@ -710,51 +707,9 @@ UniquePtr<TrackInfo> CreateTrackInfoWith
       if (maybeSamplerate && *maybeSamplerate > 0) {
         audioInfo->mRate = *maybeSamplerate;
       }
     }
   }
   return trackInfo;
 }
 
-bool OnCellularConnection() {
-  uint32_t linkType = nsINetworkLinkService::LINK_TYPE_UNKNOWN;
-  if (XRE_IsContentProcess()) {
-    mozilla::dom::ContentChild* cpc =
-        mozilla::dom::ContentChild::GetSingleton();
-    if (!cpc) {
-      NS_WARNING("Can't get ContentChild singleton in content process!");
-      return false;
-    }
-    linkType = cpc->NetworkLinkType();
-  } else {
-    nsresult rv;
-    nsCOMPtr<nsINetworkLinkService> nls =
-        do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID, &rv);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Can't get nsINetworkLinkService.");
-      return false;
-    }
-
-    rv = nls->GetLinkType(&linkType);
-    if (NS_FAILED(rv)) {
-      NS_WARNING("Can't get network link type.");
-      return false;
-    }
-  }
-
-  switch (linkType) {
-    case nsINetworkLinkService::LINK_TYPE_UNKNOWN:
-    case nsINetworkLinkService::LINK_TYPE_ETHERNET:
-    case nsINetworkLinkService::LINK_TYPE_USB:
-    case nsINetworkLinkService::LINK_TYPE_WIFI:
-      return false;
-    case nsINetworkLinkService::LINK_TYPE_WIMAX:
-    case nsINetworkLinkService::LINK_TYPE_2G:
-    case nsINetworkLinkService::LINK_TYPE_3G:
-    case nsINetworkLinkService::LINK_TYPE_4G:
-      return true;
-  }
-
-  return false;
-}
-
 }  // end namespace mozilla
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -540,15 +540,11 @@ static bool StringListContains(const Lis
 
 inline void AppendStringIfNotEmpty(nsACString& aDest, nsACString&& aSrc) {
   if (!aSrc.IsEmpty()) {
     aDest.Append(NS_LITERAL_CSTRING("\n"));
     aDest.Append(aSrc);
   }
 }
 
-// Returns true if we're running on a cellular connection; 2G, 3G, etc.
-// Main thread only.
-bool OnCellularConnection();
-
 }  // end namespace mozilla
 
 #endif
--- a/dom/security/test/csp/test_CSP.html
+++ b/dom/security/test/csp/test_CSP.html
@@ -101,24 +101,22 @@ window.testResult = function(testname, r
   // ... otherwise, finish
   window.examiner.remove();
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
 SpecialPowers.pushPrefEnv(
-  {'set':[// On a cellular connection the default preload value is 0 ("preload
-          // none"). Our Android emulators emulate a cellular connection, and
-          // so by default preload no media data. This causes the media_* tests
-          // to timeout. We set the default used by cellular connections to the
-          // same as used by non-cellular connections in order to get
-          // consistent behavior across platforms/devices.
-          ["media.preload.default", 2],
-          ["media.preload.default.cellular", 2]]},
+  {'set':[// This defaults to 0 ("preload none") on mobile (B2G/Android), which
+          // blocks loading the resource until the user interacts with a
+          // corresponding widget, which breaks the media_* tests. We set it
+          // back to the default used by desktop Firefox to get consistent
+          // behavior.
+          ["media.preload.default", 2]]},
     function() {
       // save this for last so that our listeners are registered.
       // ... this loads the testbed of good and bad requests.
       document.getElementById('cspframe').src = 'file_main.html';
     });
 </script>
 </pre>
 </body>
--- a/dom/security/test/csp/test_redirects.html
+++ b/dom/security/test/csp/test_redirects.html
@@ -114,24 +114,22 @@ var testResult = function(testName, url,
 
   window.examiner.remove();
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
 SpecialPowers.pushPrefEnv(
-  {'set':[// On a cellular connection the default preload value is 0 ("preload
-          // none"). Our Android emulators emulate a cellular connection, and
-          // so by default preload no media data. This causes the media_* tests
-          // to timeout. We set the default used by cellular connections to the
-          // same as used by non-cellular connections in order to get
-          // consistent behavior across platforms/devices.
-          ["media.preload.default", 2],
-          ["media.preload.default.cellular", 2]]},
+  {'set':[// This defaults to 0 ("preload none") on mobile (B2G/Android), which
+          // blocks loading the resource until the user interacts with a
+          // corresponding widget, which breaks the media_* tests. We set it
+          // back to the default used by desktop Firefox to get consistent
+          // behavior.
+          ["media.preload.default", 2]]},
   function() {
     // save this for last so that our listeners are registered.
     // ... this loads the testbed of good and bad requests.
     document.getElementById("harness").src = "file_redirects_main.html";
   });
 </script>
 </pre>
 
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -545,20 +545,22 @@ pref("notification.feature.enabled", tru
 pref("dom.webnotifications.enabled", true);
 
 // prevent tooltips from showing up
 pref("browser.chrome.toolbar_tips", false);
 
 // don't allow meta-refresh when backgrounded
 pref("browser.meta_refresh_when_inactive.disabled", true);
 
-// On mobile we throttle the download once the readahead_limit is hit
-// if we're using a cellular connection, even if the download is slow.
-// This is to preserve battery and data.
-pref("media.throttle-cellular-regardless-of-download-rate", true);
+// prevent video elements from preloading too much data
+pref("media.preload.default", 1); // default to preload none
+pref("media.preload.auto", 2);    // preload metadata if preload=auto
+// On mobile we'll throttle the download once the readahead_limit is hit,
+// even if the download is slow. This is to preserve battery and data.
+pref("media.throttle-regardless-of-download-rate", true);
 
 // Number of video frames we buffer while decoding video.
 // On Android this is decided by a similar value which varies for
 // each OMX decoder |OMX_PARAM_PORTDEFINITIONTYPE::nBufferCountMin|. This
 // number must be less than the OMX equivalent or gecko will think it is
 // chronically starved of video frames. All decoders seen so far have a value
 // of at least 4.
 pref("media.video-queue.default-size", 3);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
@@ -1,21 +1,16 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * vim: ts=4 sw=4 expandtab:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.geckoview;
 
-import android.arch.lifecycle.ProcessLifecycleOwner;
-import android.arch.lifecycle.Lifecycle;
-import android.arch.lifecycle.LifecycleObserver;
-import android.arch.lifecycle.OnLifecycleEvent;
-
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.res.Configuration;
@@ -26,17 +21,16 @@ import android.os.Process;
 import android.support.annotation.AnyThread;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.UiThread;
 import android.util.Log;
 
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
-import org.mozilla.gecko.GeckoNetworkManager;
 import org.mozilla.gecko.GeckoScreenOrientation;
 import org.mozilla.gecko.GeckoSystemStateListener;
 import org.mozilla.gecko.GeckoThread;
 import org.mozilla.gecko.PrefsHelper;
 import org.mozilla.gecko.util.BundleEventListener;
 import org.mozilla.gecko.util.DebugConfig;
 import org.mozilla.gecko.util.EventCallback;
 import org.mozilla.gecko.util.GeckoBundle;
@@ -94,46 +88,16 @@ public final class GeckoRuntime implemen
      * This is a key for extra data sent with {@link #ACTION_CRASHED}. The value is
      * a boolean indicating whether or not the crash was fatal or not. If true, the
      * main application process was affected by the crash. If false, only an internal
      * process used by Gecko has crashed and the application may be able to recover.
      * @see GeckoSession.ContentDelegate#onCrash(GeckoSession)
      */
     public static final String EXTRA_CRASH_FATAL = "fatal";
 
-    private final class LifecycleListener implements LifecycleObserver {
-        public LifecycleListener() {
-        }
-
-        @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
-        void onCreate() {
-            Log.d(LOGTAG, "Lifecycle: onCreate");
-        }
-
-        @OnLifecycleEvent(Lifecycle.Event.ON_START)
-        void onStart() {
-            Log.d(LOGTAG, "Lifecycle: onStart");
-        }
-
-        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
-        void onResume() {
-            Log.d(LOGTAG, "Lifecycle: onResume");
-            // Monitor network status and send change notifications to Gecko
-            // while active.
-            GeckoNetworkManager.getInstance().start(GeckoAppShell.getApplicationContext());
-        }
-
-        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
-        void onPause() {
-            Log.d(LOGTAG, "Lifecycle: onPause");
-            // Stop monitoring network status while inactive.
-            GeckoNetworkManager.getInstance().stop();
-        }
-    }
-
     private static GeckoRuntime sDefaultRuntime;
 
     /**
      * Get the default runtime for the given context.
      * This will create and initialize the runtime with the default settings.
      *
      * Note: Only use this for session-less apps.
      *       For regular apps, use create() instead.
@@ -297,19 +261,16 @@ public final class GeckoRuntime implemen
         // Bug 1453062 -- the EventDispatcher should really live here (or in GeckoThread)
         EventDispatcher.getInstance().registerUiThreadListener(mEventListener, "Gecko:Exited");
 
         // Attach and commit settings.
         mSettings.attachTo(this);
 
         // Initialize the system ClipboardManager by accessing it on the main thread.
         GeckoAppShell.getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE);
-
-        // Add process lifecycle listener to react to backgrounding events.
-        ProcessLifecycleOwner.get().getLifecycle().addObserver(new LifecycleListener());
         return true;
     }
 
     /* package */ void setDefaultPrefs(final GeckoBundle prefs) {
         EventDispatcher.getInstance().dispatch("GeckoView:SetDefaultPrefs", prefs);
     }
 
     /**
--- a/modules/libpref/init/StaticPrefList.h
+++ b/modules/libpref/init/StaticPrefList.h
@@ -1430,28 +1430,27 @@ VARCACHE_PREF(
 //---------------------------------------------------------------------------
 // Media prefs
 //---------------------------------------------------------------------------
 
 // These prefs use camel case instead of snake case for the getter because one
 // reviewer had an unshakeable preference for that.
 
 // File-backed MediaCache size.
+#ifdef ANDROID
+# define PREF_VALUE  32768  // Measured in KiB
+#else
+# define PREF_VALUE 512000  // Measured in KiB
+#endif
 VARCACHE_PREF(
   "media.cache_size",
    MediaCacheSize,
-  uint32_t, 512000 // Measured in KiB
+  RelaxedAtomicUint32, PREF_VALUE
 )
-// Size of file backed MediaCache while on a connection which is cellular (3G, etc),
-// and thus assumed to be "expensive".
-VARCACHE_PREF(
-  "media.cache_size.cellular",
-   MediaCacheCellularSize,
-  uint32_t, 32768 // Measured in KiB
-)
+#undef PREF_VALUE
 
 // If a resource is known to be smaller than this size (in kilobytes), a
 // memory-backed MediaCache may be used; otherwise the (single shared global)
 // file-backed MediaCache is used.
 VARCACHE_PREF(
   "media.memory_cache_max_size",
    MediaMemoryCacheMaxSize,
   uint32_t, 8192      // Measured in KiB
@@ -1470,40 +1469,42 @@ VARCACHE_PREF(
 VARCACHE_PREF(
   "media.memory_caches_combined_limit_pc_sysmem",
    MediaMemoryCachesCombinedLimitPcSysmem,
   uint32_t, 5         // A percentage
 )
 
 // When a network connection is suspended, don't resume it until the amount of
 // buffered data falls below this threshold (in seconds).
+#ifdef ANDROID
+# define PREF_VALUE 10  // Use a smaller limit to save battery.
+#else
+# define PREF_VALUE 30
+#endif
 VARCACHE_PREF(
   "media.cache_resume_threshold",
    MediaCacheResumeThreshold,
-  uint32_t, 30
+  RelaxedAtomicInt32, PREF_VALUE
 )
-VARCACHE_PREF(
-  "media.cache_resume_threshold.cellular",
-   MediaCacheCellularResumeThreshold,
-  uint32_t, 10
-)
+#undef PREF_VALUE
 
 // Stop reading ahead when our buffered data is this many seconds ahead of the
 // current playback position. This limit can stop us from using arbitrary
 // amounts of network bandwidth prefetching huge videos.
+#ifdef ANDROID
+# define PREF_VALUE 30  // Use a smaller limit to save battery.
+#else
+# define PREF_VALUE 60
+#endif
 VARCACHE_PREF(
   "media.cache_readahead_limit",
    MediaCacheReadaheadLimit,
-  uint32_t, 60
+  RelaxedAtomicInt32, PREF_VALUE
 )
-VARCACHE_PREF(
-  "media.cache_readahead_limit.cellular",
-   MediaCacheCellularReadaheadLimit,
-  uint32_t, 30
-)
+#undef PREF_VALUE
 
 // AudioSink
 VARCACHE_PREF(
   "media.resampling.enabled",
    MediaResamplingEnabled,
   RelaxedAtomicBool, false
 )
 
--- a/testing/profiles/unittest-required/user.js
+++ b/testing/profiles/unittest-required/user.js
@@ -172,17 +172,16 @@ user_pref("media.hls.server.url", "http:
 // Don't block old libavcodec libraries when testing, because our test systems
 // cannot easily be upgraded.
 user_pref("media.libavcodec.allow-obsolete", true);
 user_pref("media.memory_cache_max_size", 32);
 user_pref("media.memory_caches_combined_limit_kb", 256);
 user_pref("media.openUnsupportedTypeWithExternalApp", false);
 user_pref("media.preload.auto", 3); // auto = enough
 user_pref("media.preload.default", 2); // default = metadata
-user_pref("media.preload.default.cellular", 2); // default = metadata
 user_pref("media.suspend-bkgnd-video.enabled", false);
 user_pref("media.test.dumpDebugInfo", true);
 user_pref("media.volume_scale", "0.01");
 // Enable speech synth test service, and disable built in platform services.
 user_pref("media.webspeech.synth.test", true);
 user_pref("network.http.prompt-temp-redirect", false);
 // Disable speculative connections so they aren't reported as leaking when they're hanging around.
 user_pref("network.http.speculative-parallel-limit", 0);