Bug 1540573 - P6. Use frugal preloading of media data when on cellular, otherwise aggressive. r=jya
authorChris Pearce <cpearce@mozilla.com>
Fri, 03 May 2019 02:44:49 +0000
changeset 472436 b10d2cae45f2e0ea7809d60c54e80784ba871429
parent 472435 270a8917377f46e18a9948c3335bfbd9b8192449
child 472437 dd882b8cd73efd56bc92aa1467139699e7e1db6d
push id113012
push userdluca@mozilla.com
push dateFri, 03 May 2019 13:13:31 +0000
treeherdermozilla-inbound@d12dfc397c08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1540573
milestone68.0a1
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
Bug 1540573 - P6. Use frugal preloading of media data when on cellular, otherwise aggressive. r=jya We're allowed to take some liberties as to what the default value and behaviour we assume for the 'preload' attribute on HTMLMediaElement by the spec. On desktop we assumed preload="metadata", while on mobile we assumed the default of preload="none" to save data. On mobile we also assumed that preload="auto" meant preload="metadata". I think it makes sense to instead of always assuming that data on Android is always expensive, we can instead detect if we're running on a cellular connection, and preload frugally then, otherwise aggressively. Differential Revision: https://phabricator.services.mozilla.com/D26235
dom/html/HTMLMediaElement.cpp
dom/html/HTMLMediaElement.h
mobile/android/app/mobile.js
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -2450,37 +2450,53 @@ 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 =
-        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);
+    uint32_t preloadDefault = GetPreloadDefault();
+    uint32_t preloadAuto = GetPreloadDefaultAuto();
     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,16 +1732,19 @@ 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/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -545,19 +545,16 @@ 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);
 
-// 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 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);
 
 // 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