Bug 1511281 - Update GeckoView user agent override to use docShell.customUserAgent r=snorp
authorRandall Barker <rbarker@mozilla.com>
Fri, 14 Dec 2018 14:40:06 +0000
changeset 507656 e5079e6a5c13fbec7b95ec31cf98866b82d44fb5
parent 507655 d02d14a3dd6e172c4cc8efb5c749752d3893fc90
child 507657 09c71a7cf75aeaf2963050e315276fb9a866fd62
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1511281
milestone66.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 1511281 - Update GeckoView user agent override to use docShell.customUserAgent r=snorp Differential Revision: https://phabricator.services.mozilla.com/D13593
mobile/android/chrome/geckoview/GeckoViewSettingsChild.js
mobile/android/modules/geckoview/GeckoViewSettings.jsm
--- a/mobile/android/chrome/geckoview/GeckoViewSettingsChild.js
+++ b/mobile/android/chrome/geckoview/GeckoViewSettingsChild.js
@@ -5,19 +5,41 @@
 
 ChromeUtils.import("resource://gre/modules/GeckoViewChildModule.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   GeckoViewUtils: "resource://gre/modules/GeckoViewUtils.jsm",
 });
 
+XPCOMUtils.defineLazyGetter(
+  this, "MOBILE_USER_AGENT",
+  function() {
+    return Cc["@mozilla.org/network/protocol;1?name=http"]
+           .getService(Ci.nsIHttpProtocolHandler).userAgent;
+  });
+
+XPCOMUtils.defineLazyGetter(
+  this, "DESKTOP_USER_AGENT",
+  function() {
+    return MOBILE_USER_AGENT
+           .replace(/Android \d.+?; [a-zA-Z]+/, "X11; Linux x86_64")
+           .replace(/Gecko\/[0-9\.]+/, "Gecko/20100101");
+  });
+
+XPCOMUtils.defineLazyGetter(
+  this, "VR_USER_AGENT",
+  function() {
+    return MOBILE_USER_AGENT.replace(/Mobile/, "Mobile VR");
+  });
+
 // This needs to match GeckoSessionSettings.java
 const USER_AGENT_MODE_MOBILE = 0;
 const USER_AGENT_MODE_DESKTOP = 1;
+const USER_AGENT_MODE_VR = 2;
 
 // Handles GeckoView content settings including:
 // * tracking protection
 // * user agent mode
 class GeckoViewSettingsChild extends GeckoViewChildModule {
   onInit() {
     debug `onInit`;
     this._userAgentMode = USER_AGENT_MODE_MOBILE;
@@ -37,41 +59,66 @@ class GeckoViewSettingsChild extends Gec
   get useTrackingProtection() {
     return docShell.useTrackingProtection;
   }
 
   set useTrackingProtection(aUse) {
     docShell.useTrackingProtection = aUse;
   }
 
+  get userAgent() {
+    if (this.userAgentOverride !== null) {
+      return this.userAgentOverride;
+    }
+    if (this.userAgentMode === USER_AGENT_MODE_DESKTOP) {
+      return DESKTOP_USER_AGENT;
+    }
+    if (this.userAgentMode === USER_AGENT_MODE_VR) {
+      return VR_USER_AGENT;
+    }
+    return null;
+  }
+
   get userAgentMode() {
     return this._userAgentMode;
   }
 
   set userAgentMode(aMode) {
     if (this.userAgentMode === aMode) {
       return;
     }
     this._userAgentMode = aMode;
+    const docShell = content && GeckoViewUtils.getRootDocShell(content);
+    if (docShell) {
+      docShell.customUserAgent = this.userAgent;
+    } else {
+      warn `Failed to set custom user agent. Doc shell not found`;
+    }
     if (this._userAgentOverride !== null) {
       return;
     }
     const utils = content.windowUtils;
     utils.setDesktopModeViewport(aMode === USER_AGENT_MODE_DESKTOP);
   }
 
   get userAgentOverride() {
     return this._userAgentOverride;
   }
 
   set userAgentOverride(aUserAgent) {
     if (aUserAgent === this._userAgentOverride) {
       return;
     }
     this._userAgentOverride = aUserAgent;
+    const docShell = content && GeckoViewUtils.getRootDocShell(content);
+    if (docShell) {
+      docShell.customUserAgent = this.userAgent;
+    } else {
+      warn `Failed to set custom user agent. Doc shell not found`;
+    }
     const utils = content.windowUtils;
     if (aUserAgent === null) {
       utils.setDesktopModeViewport(this._userAgentMode === USER_AGENT_MODE_DESKTOP);
       return;
     }
     utils.setDesktopModeViewport(false);
   }
 
--- a/mobile/android/modules/geckoview/GeckoViewSettings.jsm
+++ b/mobile/android/modules/geckoview/GeckoViewSettings.jsm
@@ -6,17 +6,16 @@
 
 var EXPORTED_SYMBOLS = ["GeckoViewSettings"];
 
 ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
-  Services: "resource://gre/modules/Services.jsm",
 });
 
 XPCOMUtils.defineLazyGetter(
   this, "MOBILE_USER_AGENT",
   function() {
     return Cc["@mozilla.org/network/protocol;1?name=http"]
            .getService(Ci.nsIHttpProtocolHandler).userAgent;
   });
@@ -75,32 +74,16 @@ class GeckoViewSettings extends GeckoVie
     this.userAgentMode = settings.userAgentMode;
     this.userAgentOverride = settings.userAgentOverride;
   }
 
   get useMultiprocess() {
     return this.browser.isRemoteBrowser;
   }
 
-  observe(aSubject, aTopic, aData) {
-    debug `observer`;
-
-    let channel = aSubject.QueryInterface(Ci.nsIHttpChannel);
-
-    if (this.browser.outerWindowID !== channel.topLevelOuterContentWindowId) {
-      return;
-    }
-
-    if (this.userAgentOverride !== null ||
-        this.userAgentMode === USER_AGENT_MODE_DESKTOP ||
-        this.userAgentMode === USER_AGENT_MODE_VR) {
-      channel.setRequestHeader("User-Agent", this.userAgent, false);
-    }
-  }
-
   get userAgent() {
     if (this.userAgentOverride !== null) {
       return this.userAgentOverride;
     }
     if (this.userAgentMode === USER_AGENT_MODE_DESKTOP) {
       return DESKTOP_USER_AGENT;
     }
     if (this.userAgentMode === USER_AGENT_MODE_VR) {
@@ -112,44 +95,27 @@ class GeckoViewSettings extends GeckoVie
   get userAgentMode() {
     return this._userAgentMode;
   }
 
   set userAgentMode(aMode) {
     if (this.userAgentMode === aMode) {
       return;
     }
-    this.updateUserAgentObserver(this._userAgentOverride, aMode);
     this._userAgentMode = aMode;
   }
 
   get userAgentOverride() {
     return this._userAgentOverride;
   }
 
   set userAgentOverride(aUserAgent) {
-    this.updateUserAgentObserver(aUserAgent, this._userAgentMode);
     this._userAgentOverride = aUserAgent;
   }
 
-  updateUserAgentObserver(aUserAgent, aMode) {
-    const wasAdded = this.userAgentOverride !== null || this.userAgentMode !== USER_AGENT_MODE_MOBILE;
-    const shouldAdd = aUserAgent !== null || aMode !== USER_AGENT_MODE_MOBILE;
-
-    try {
-      if (wasAdded && !shouldAdd) {
-        Services.obs.removeObserver(this, "http-on-useragent-request");
-      } else if (!wasAdded && shouldAdd) {
-        Services.obs.addObserver(this, "http-on-useragent-request");
-      }
-    } catch (e) {
-      warn `Caught exception while adding/removing "http-on-useragent-request" observer: ${e.message}`;
-    }
-  }
-
   get displayMode() {
     return this.window.docShell.displayMode;
   }
 
   set displayMode(aMode) {
     this.window.docShell.displayMode = aMode;
   }
 }