Backed out 3 changesets (bug 1343678) for WPT failures on Android. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Wed, 28 Aug 2019 23:09:08 +0300
changeset 490470 13c98841413b119c56fafe2bbeaaa631825fdd53
parent 490469 d986d84d5d29270c01355dbcaab13db91425d9cb
child 490471 3c5d4f4fc24be37e9b86598c1310738ecae158d4
push id36504
push userccoroiu@mozilla.com
push dateThu, 29 Aug 2019 04:08:39 +0000
treeherdermozilla-central@7004b8779a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1343678
milestone70.0a1
backs out619e7838ebfd94672b993d34914f3852610b2905
5010684cdca410c6fceaf69a02d3a93ff607a0ea
b01343e4c2eb8a91be32132fafc0318d4710dfc5
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 3 changesets (bug 1343678) for WPT failures on Android. CLOSED TREE Backed out changeset 619e7838ebfd (bug 1343678) Backed out changeset 5010684cdca4 (bug 1343678) Backed out changeset b01343e4c2eb (bug 1343678)
dom/serviceworkers/test/test_serviceworker_interfaces.js
dom/tests/mochitest/general/test_interfaces.js
dom/workers/test/test_worker_interfaces.js
mobile/android/app/geckoview-prefs.js
mobile/android/components/geckoview/GeckoView.manifest
mobile/android/components/geckoview/GeckoViewPush.js
mobile/android/components/geckoview/GeckoViewStartup.js
mobile/android/components/geckoview/moz.build
mobile/android/geckoview/api.txt
mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js
mobile/android/geckoview/src/androidTest/assets/www/push/push.html
mobile/android/geckoview/src/androidTest/assets/www/push/push.js
mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt
mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushUtils.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Base64Utils.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushDelegate.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushSubscription.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
mobile/android/installer/package-manifest.in
mobile/android/modules/geckoview/GeckoViewPushController.jsm
mobile/android/modules/geckoview/moz.build
widget/android/Base64UtilsSupport.h
widget/android/nsAppShell.cpp
--- a/dom/serviceworkers/test/test_serviceworker_interfaces.js
+++ b/dom/serviceworkers/test/test_serviceworker_interfaces.js
@@ -204,25 +204,25 @@ var interfaceNamesInGlobalScope = [
   "PerformanceResourceTiming",
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "PerformanceServerTiming",
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "ProgressEvent",
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "PromiseRejectionEvent",
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushEvent" },
+  { name: "PushEvent", fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushManager" },
+  { name: "PushManager", fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushMessageData" },
+  { name: "PushMessageData", fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushSubscription" },
+  { name: "PushSubscription", fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushSubscriptionOptions" },
+  { name: "PushSubscriptionOptions", fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "Request",
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "Response",
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "ServiceWorker",
   // IMPORTANT: Do not change this list without review from a DOM peer!
   "ServiceWorkerGlobalScope",
--- a/dom/tests/mochitest/general/test_interfaces.js
+++ b/dom/tests/mochitest/general/test_interfaces.js
@@ -913,23 +913,24 @@ var interfaceNamesInGlobalScope = [
   { name: "ProcessingInstruction", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "ProgressEvent", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "PromiseRejectionEvent", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "PublicKeyCredential" },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushManager", insecureContext: true },
+  { name: "PushManager", insecureContext: true, fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushSubscription", insecureContext: true },
+  { name: "PushSubscription", insecureContext: true, fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "PushSubscriptionOptions",
     insecureContext: true,
+    fennecOrDesktop: true,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "RadioNodeList", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "Range", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "Report", insecureContext: true, nightly: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -208,23 +208,24 @@ var interfaceNamesInGlobalScope = [
   { name: "PerformanceResourceTiming", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "PerformanceServerTiming", insecureContext: false },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "ProgressEvent", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "PromiseRejectionEvent", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushManager", insecureContext: true },
+  { name: "PushManager", insecureContext: true, fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
-  { name: "PushSubscription", insecureContext: true },
+  { name: "PushSubscription", insecureContext: true, fennecOrDesktop: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   {
     name: "PushSubscriptionOptions",
     insecureContext: true,
+    fennecOrDesktop: true,
   },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "Request", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "Response", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
   { name: "ServiceWorkerRegistration", insecureContext: true },
   // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/mobile/android/app/geckoview-prefs.js
+++ b/mobile/android/app/geckoview-prefs.js
@@ -34,17 +34,17 @@ pref("geckoview.console.enabled", false)
 #else
   pref("geckoview.logging", "Debug");
 #endif
 
 // Enable capture attribute for file input.
 pref("dom.capture.enabled", true);
 
 // Disable Web Push until we get it working
-pref("dom.push.enabled", true);
+pref("dom.push.enabled", false);
 
 // enable external storage API
 pref("dom.storageManager.enabled", true);
 
 // enable Visual Viewport API
 pref("dom.visualviewport.enabled", true);
 
 // Use containerless scrolling.
--- a/mobile/android/components/geckoview/GeckoView.manifest
+++ b/mobile/android/components/geckoview/GeckoView.manifest
@@ -18,12 +18,8 @@ contract @mozilla.org/prompter;1 {076ac1
 component {aa0dd6fc-73dd-4621-8385-c0b377e02cee} GeckoViewPrompt.js process=main
 contract @mozilla.org/colorpicker;1 {aa0dd6fc-73dd-4621-8385-c0b377e02cee} process=main
 component {e4565e36-f101-4bf5-950b-4be0887785a9} GeckoViewPrompt.js process=main
 contract @mozilla.org/filepicker;1 {e4565e36-f101-4bf5-950b-4be0887785a9} process=main
 
 # GeckoViewExternalAppService.js
 component {a89eeec6-6608-42ee-a4f8-04d425992f45} GeckoViewExternalAppService.js
 contract @mozilla.org/uriloader/external-helper-app-service;1 {a89eeec6-6608-42ee-a4f8-04d425992f45}
-
-# GeckoViewPush.js
-component {a54d84d7-98a4-4fec-b664-e42e512ae9cc} GeckoViewPush.js
-contract @mozilla.org/push/Service;1 {a54d84d7-98a4-4fec-b664-e42e512ae9cc}
deleted file mode 100644
--- a/mobile/android/components/geckoview/GeckoViewPush.js
+++ /dev/null
@@ -1,253 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-const { GeckoViewUtils } = ChromeUtils.import(
-  "resource://gre/modules/GeckoViewUtils.jsm"
-);
-
-const { debug, warn } = GeckoViewUtils.initLogging("GeckoViewPush"); // eslint-disable-line no-unused-vars
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "EventDispatcher",
-  "resource://gre/modules/Messaging.jsm"
-);
-
-// Observer notification topics for push messages and subscription status
-// changes. These are duplicated and used in `nsIPushNotifier`. They're exposed
-// on `nsIPushService` so that JS callers only need to import this service.
-const OBSERVER_TOPIC_PUSH = "push-message";
-const OBSERVER_TOPIC_SUBSCRIPTION_CHANGE = "push-subscription-change";
-const OBSERVER_TOPIC_SUBSCRIPTION_MODIFIED = "push-subscription-modified";
-
-function createSubscription({
-  scope,
-  principal,
-  browserPublicKey,
-  authSecret,
-  endpoint,
-  appServerKey,
-}) {
-  const decodedBrowserKey = ChromeUtils.base64URLDecode(browserPublicKey, {
-    padding: "ignore",
-  });
-  const decodedAuthSecret = ChromeUtils.base64URLDecode(authSecret, {
-    padding: "ignore",
-  });
-
-  return new PushSubscription({
-    endpoint: endpoint,
-    scope,
-    p256dhKey: decodedBrowserKey,
-    authenticationSecret: decodedAuthSecret,
-    appServerKey,
-  });
-}
-
-function scopeWithAttrs(scope, attrs) {
-  return scope + ChromeUtils.originAttributesToSuffix(attrs);
-}
-
-function PushService() {
-  this.wrappedJSObject = this;
-}
-
-PushService.prototype = {
-  classID: Components.ID("{a54d84d7-98a4-4fec-b664-e42e512ae9cc}"),
-  contractID: "@mozilla.org/push/Service;1",
-  QueryInterface: ChromeUtils.generateQI([
-    Ci.nsIObserver,
-    Ci.nsISupportsWeakReference,
-    Ci.nsIPushService,
-    Ci.nsIPushQuotaManager,
-    Ci.nsIPushErrorReporter,
-  ]),
-
-  pushTopic: OBSERVER_TOPIC_PUSH,
-  subscriptionChangeTopic: OBSERVER_TOPIC_SUBSCRIPTION_CHANGE,
-  subscriptionModifiedTopic: OBSERVER_TOPIC_SUBSCRIPTION_MODIFIED,
-
-  // nsIObserver methods
-
-  observe(subject, topic, data) {},
-
-  // nsIPushService methods
-
-  subscribe(scope, principal, callback) {
-    this.subscribeWithKey(scope, principal, null, callback);
-  },
-
-  async subscribeWithKey(scope, principal, appServerKey, callback) {
-    try {
-      const response = await EventDispatcher.instance.sendRequestForResult({
-        type: "GeckoView:PushSubscribe",
-        scope: scopeWithAttrs(scope, principal.originAttributes),
-        appServerKey: appServerKey
-          ? ChromeUtils.base64URLEncode(new Uint8Array(appServerKey), {
-              pad: true,
-            })
-          : null,
-      });
-
-      let subscription = null;
-      if (response) {
-        subscription = createSubscription({
-          ...response,
-          scope,
-          principal,
-          appServerKey,
-        });
-      }
-
-      callback.onPushSubscription(Cr.NS_OK, subscription);
-    } catch (e) {
-      callback.onPushSubscription(Cr.NS_ERROR_FAILURE, null);
-    }
-  },
-
-  async unsubscribe(scope, principal, callback) {
-    try {
-      await EventDispatcher.instance.sendRequestForResult({
-        type: "GeckoView:PushUnsubscribe",
-        scope: scopeWithAttrs(scope, principal.originAttributes),
-      });
-
-      callback.onUnsubscribe(Cr.NS_OK, true);
-    } catch (e) {
-      callback.onUnsubscribe(Cr.NS_ERROR_FAILURE, false);
-    }
-  },
-
-  async getSubscription(scope, principal, callback) {
-    try {
-      const response = await EventDispatcher.instance.sendRequestForResult({
-        type: "GeckoView:PushGetSubscription",
-        scope: scopeWithAttrs(scope, principal.originAttributes),
-      });
-
-      let subscription = null;
-      if (response) {
-        subscription = createSubscription({
-          ...response,
-          scope,
-          principal,
-        });
-      }
-
-      callback.onPushSubscription(Cr.NS_OK, subscription);
-    } catch (e) {
-      callback.onPushSubscription(Cr.NS_ERROR_FAILURE, null);
-    }
-  },
-
-  clearForDomain(domain, callback) {
-    callback.onClear(Cr.NS_OK);
-  },
-
-  // nsIPushQuotaManager methods
-
-  notificationForOriginShown(origin) {},
-
-  notificationForOriginClosed(origin) {},
-
-  // nsIPushErrorReporter methods
-
-  reportDeliveryError(messageId, reason) {},
-};
-
-/** `PushSubscription` instances are passed to all subscription callbacks. */
-function PushSubscription(props) {
-  this._props = props;
-}
-
-PushSubscription.prototype = {
-  QueryInterface: ChromeUtils.generateQI([Ci.nsIPushSubscription]),
-
-  /** The URL for sending messages to this subscription. */
-  get endpoint() {
-    return this._props.endpoint;
-  },
-
-  /** The last time a message was sent to this subscription. */
-  get lastPush() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /** The total number of messages sent to this subscription. */
-  get pushCount() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /**
-   * The app will take care of throttling, so we don't
-   * care about the quota stuff here.
-   */
-  get quota() {
-    return -1;
-  },
-
-  /**
-   * Indicates whether this subscription was created with the system principal.
-   * System subscriptions are exempt from the background message quota and
-   * permission checks.
-   */
-  get isSystemSubscription() {
-    return false;
-  },
-
-  /** The private key used to decrypt incoming push messages, in JWK format */
-  get p256dhPrivateKey() {
-    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-  },
-
-  /**
-   * Indicates whether this subscription is subject to the background message
-   * quota.
-   */
-  quotaApplies() {
-    return false;
-  },
-
-  /**
-   * Indicates whether this subscription exceeded the background message quota,
-   * or the user revoked the notification permission. The caller must request a
-   * new subscription to continue receiving push messages.
-   */
-  isExpired() {
-    return false;
-  },
-
-  /**
-   * Returns a key for encrypting messages sent to this subscription. JS
-   * callers receive the key buffer as a return value, while C++ callers
-   * receive the key size and buffer as out parameters.
-   */
-  getKey(name) {
-    switch (name) {
-      case "p256dh":
-        return this._getRawKey(this._props.p256dhKey);
-
-      case "auth":
-        return this._getRawKey(this._props.authenticationSecret);
-
-      case "appServer":
-        return this._getRawKey(this._props.appServerKey);
-    }
-    return [];
-  },
-
-  _getRawKey(key) {
-    if (!key) {
-      return [];
-    }
-    return new Uint8Array(key);
-  },
-};
-
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory([PushService]);
--- a/mobile/android/components/geckoview/GeckoViewStartup.js
+++ b/mobile/android/components/geckoview/GeckoViewStartup.js
@@ -67,21 +67,16 @@ GeckoViewStartup.prototype = {
           module: "resource://gre/modules/GeckoViewStorageController.jsm",
           ged: [
             "GeckoView:ClearData",
             "GeckoView:ClearSessionContextData",
             "GeckoView:ClearHostData",
           ],
         });
 
-        GeckoViewUtils.addLazyGetter(this, "GeckoViewPushController", {
-          module: "resource://gre/modules/GeckoViewPushController.jsm",
-          ged: ["GeckoView:PushEvent", "GeckoView:PushSubscriptionChanged"],
-        });
-
         GeckoViewUtils.addLazyPrefObserver(
           {
             name: "geckoview.console.enabled",
             default: false,
           },
           {
             handler: _ => this.GeckoViewConsole,
           }
--- a/mobile/android/components/geckoview/moz.build
+++ b/mobile/android/components/geckoview/moz.build
@@ -19,13 +19,12 @@ if CONFIG['MOZ_ANDROID_HISTORY']:
     ]
     include('/ipc/chromium/chromium-config.mozbuild')
 
 EXTRA_COMPONENTS += [
     'GeckoView.manifest',
     'GeckoViewExternalAppService.js',
     'GeckoViewPermission.js',
     'GeckoViewPrompt.js',
-    'GeckoViewPush.js',
     'GeckoViewStartup.js',
 ]
 
 FINAL_LIBRARY = 'xul'
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -79,19 +79,16 @@ import org.mozilla.geckoview.SessionFind
 import org.mozilla.geckoview.SessionTextInput;
 import org.mozilla.geckoview.StorageController;
 import org.mozilla.geckoview.WebExtension;
 import org.mozilla.geckoview.WebExtensionController;
 import org.mozilla.geckoview.WebExtensionEventDispatcher;
 import org.mozilla.geckoview.WebMessage;
 import org.mozilla.geckoview.WebNotification;
 import org.mozilla.geckoview.WebNotificationDelegate;
-import org.mozilla.geckoview.WebPushController;
-import org.mozilla.geckoview.WebPushDelegate;
-import org.mozilla.geckoview.WebPushSubscription;
 import org.mozilla.geckoview.WebRequest;
 import org.mozilla.geckoview.WebRequestError;
 import org.mozilla.geckoview.WebResponse;
 
 package org.mozilla.geckoview {
 
   @AnyThread public final enum AllowOrDeny {
     method public static AllowOrDeny valueOf(String);
@@ -312,17 +309,16 @@ package org.mozilla.geckoview {
     method @UiThread @NonNull public static synchronized GeckoRuntime getDefault(@NonNull Context);
     method @UiThread @Nullable public GeckoRuntime.Delegate getDelegate();
     method @UiThread @Nullable public File getProfileDir();
     method @AnyThread @NonNull public GeckoRuntimeSettings getSettings();
     method @UiThread @NonNull public StorageController getStorageController();
     method @UiThread @NonNull public RuntimeTelemetry getTelemetry();
     method @UiThread @NonNull public WebExtensionController getWebExtensionController();
     method @UiThread @Nullable public WebNotificationDelegate getWebNotificationDelegate();
-    method @UiThread @NonNull public WebPushController getWebPushController();
     method @UiThread public void orientationChanged();
     method @UiThread public void orientationChanged(int);
     method @AnyThread public void readFromParcel(@NonNull Parcel);
     method @UiThread @NonNull public GeckoResult<Void> registerWebExtension(@NonNull WebExtension);
     method @UiThread public void setDelegate(@Nullable GeckoRuntime.Delegate);
     method @UiThread public void setWebNotificationDelegate(@Nullable WebNotificationDelegate);
     method @AnyThread public void shutdown();
     method @UiThread @NonNull public GeckoResult<Void> unregisterWebExtension(@NonNull WebExtension);
@@ -1263,39 +1259,16 @@ package org.mozilla.geckoview {
     field @Nullable public final String title;
   }
 
   public interface WebNotificationDelegate {
     method @AnyThread default public void onCloseNotification(@NonNull WebNotification);
     method @AnyThread default public void onShowNotification(@NonNull WebNotification);
   }
 
-  public class WebPushController {
-    method @UiThread public void onPushEvent(@NonNull WebPushSubscription);
-    method @UiThread public void onPushEvent(@NonNull WebPushSubscription, @Nullable byte[]);
-    method @UiThread public void onSubscriptionChanged(@NonNull WebPushSubscription);
-    method @UiThread public void setDelegate(@Nullable WebPushDelegate);
-  }
-
-  public interface WebPushDelegate {
-    method @UiThread @Nullable default public GeckoResult<WebPushSubscription> onGetSubscription(@NonNull String);
-    method @UiThread @Nullable default public GeckoResult<WebPushSubscription> onSubscribe(@NonNull String, @Nullable byte[]);
-    method @UiThread @Nullable default public GeckoResult<Void> onUnsubscribe(@NonNull String);
-  }
-
-  public class WebPushSubscription implements Parcelable {
-    ctor public WebPushSubscription(@NonNull String, @NonNull String, @Nullable byte[], @NonNull byte[], @NonNull byte[]);
-    field public static final Parcelable.Creator<WebPushSubscription> CREATOR;
-    field @Nullable public final byte[] appServerKey;
-    field @NonNull public final byte[] authSecret;
-    field @NonNull public final byte[] browserPublicKey;
-    field @NonNull public final String endpoint;
-    field @NonNull public final String scope;
-  }
-
   @AnyThread public class WebRequest extends WebMessage {
     ctor public WebRequest(@NonNull String);
     field public static final int CACHE_MODE_DEFAULT = 1;
     field public static final int CACHE_MODE_FORCE_CACHE = 5;
     field public static final int CACHE_MODE_NO_CACHE = 4;
     field public static final int CACHE_MODE_NO_STORE = 2;
     field public static final int CACHE_MODE_ONLY_IF_CACHED = 6;
     field public static final int CACHE_MODE_RELOAD = 3;
--- a/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js
+++ b/mobile/android/geckoview/src/androidTest/assets/web_extensions/test-support/test-support.js
@@ -7,17 +7,17 @@ let port = null;
 window.addEventListener("pageshow", () => {
   port = browser.runtime.connectNative("browser");
 
   port.onMessage.addListener(message => {
     if (message.eval) {
       try {
         // Using eval here is the whole point of this WebExtension so we can
         // safely ignore the eslint warning.
-        const response = window.eval(message.eval); // eslint-disable-line no-eval
+        const response = eval(message.eval); // eslint-disable-line no-eval
         sendResponse(message.id, response);
       } catch (ex) {
         sendSyncResponse(message.id, null, ex);
       }
     }
   });
 
   function sendResponse(id, response, exception) {
deleted file mode 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/push/push.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<html>
-    <head>
-        <title>Push API test</title>
-    </head>
-    <body>
-        <p>Hello, world!</p>
-        <script src="push.js"></script>
-    </body>
-</html>
deleted file mode 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/push/push.js
+++ /dev/null
@@ -1,44 +0,0 @@
-window.doSubscribe = async function(applicationServerKey) {
-  const registration = await navigator.serviceWorker.register("./sw.js");
-  const sub = await registration.pushManager.subscribe({
-    applicationServerKey,
-  });
-  return sub.toJSON();
-};
-
-window.doGetSubscription = async function() {
-  const registration = await navigator.serviceWorker.register("./sw.js");
-  const sub = await registration.pushManager.getSubscription();
-  if (sub) {
-    return sub.toJSON();
-  }
-
-  return null;
-};
-
-window.doUnsubscribe = async function() {
-  const registration = await navigator.serviceWorker.register("./sw.js");
-  const sub = await registration.pushManager.getSubscription();
-  sub.unsubscribe();
-  return {};
-};
-
-window.doWaitForPushEvent = function() {
-  return new Promise(resolve => {
-    navigator.serviceWorker.addEventListener("message", function(e) {
-      if (e.data.type === "push") {
-        resolve(e.data.payload);
-      }
-    });
-  });
-};
-
-window.doWaitForSubscriptionChange = function() {
-  return new Promise(resolve => {
-    navigator.serviceWorker.addEventListener("message", function(e) {
-      if (e.data.type === "pushsubscriptionchange") {
-        resolve(e.data.type);
-      }
-    });
-  });
-};
deleted file mode 100644
--- a/mobile/android/geckoview/src/androidTest/assets/www/push/sw.js
+++ /dev/null
@@ -1,21 +0,0 @@
-self.addEventListener("install", function() {
-  self.skipWaiting();
-});
-
-self.addEventListener("activate", function(e) {
-  e.waitUntil(self.clients.claim());
-});
-
-self.addEventListener("push", async function(e) {
-  const clients = await self.clients.matchAll();
-  clients.forEach(function(client) {
-    client.postMessage({ type: "push", payload: e.data.text() });
-  });
-});
-
-self.addEventListener("pushsubscriptionchange", async function(e) {
-  const clients = await self.clients.matchAll();
-  clients.forEach(function(client) {
-    client.postMessage({ type: "pushsubscriptionchange" });
-  });
-});
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
+++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/BaseSessionTest.kt
@@ -54,17 +54,16 @@ open class BaseSessionTest(noErrorCollec
         const val VIEWPORT_PATH = "/assets/www/viewport.html"
         const val IFRAME_REDIRECT_LOCAL = "/assets/www/iframe_redirect_local.html"
         const val IFRAME_REDIRECT_AUTOMATION = "/assets/www/iframe_redirect_automation.html"
         const val AUTOPLAY_PATH = "/assets/www/autoplay.html"
         const val SCROLL_TEST_PATH = "/assets/www/scroll.html"
         const val COLORS_HTML_PATH = "/assets/www/colors.html"
         const val FIXED_BOTTOM = "/assets/www/fixedbottom.html"
         const val STORAGE_TITLE_HTML_PATH = "/assets/www/reflect_local_storage_into_title.html"
-        const val PUSH_HTML_PATH = "/assets/www/push/push.html"
     }
 
     @get:Rule val sessionRule = GeckoSessionTestRule()
 
     @get:Rule val errors = ErrorCollector()
 
     val mainSession get() = sessionRule.session
 
deleted file mode 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushTest.kt
+++ /dev/null
@@ -1,199 +0,0 @@
-/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
- * Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-package org.mozilla.geckoview.test
-
-import android.os.Parcel
-import android.support.test.filters.MediumTest
-import android.support.test.runner.AndroidJUnit4
-import android.util.Base64
-import org.hamcrest.MatcherAssert.assertThat
-import org.hamcrest.Matchers.*
-import org.json.JSONObject
-import org.junit.After
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mozilla.geckoview.*
-import org.mozilla.geckoview.test.util.Callbacks
-import java.math.BigInteger
-import java.security.KeyPair
-import java.security.KeyPairGenerator
-import java.security.SecureRandom
-import java.security.interfaces.ECPublicKey
-import java.security.spec.ECGenParameterSpec
-
-@RunWith(AndroidJUnit4::class)
-@MediumTest
-class WebPushTest : BaseSessionTest() {
-    companion object {
-        val PUSH_ENDPOINT: String = "https://test.endpoint"
-        val APP_SERVER_KEY_PAIR: KeyPair = generateKeyPair()
-        val AUTH_SECRET: ByteArray = generateAuthSecret()
-        val BROWSER_KEY_PAIR: KeyPair = generateKeyPair()
-
-        private fun generateKeyPair(): KeyPair {
-            try {
-                val spec = ECGenParameterSpec("secp256r1")
-                val generator = KeyPairGenerator.getInstance("EC")
-                generator.initialize(spec)
-                return generator.generateKeyPair()
-            } catch (e: Exception) {
-                throw RuntimeException(e)
-            }
-        }
-
-        private fun generateAuthSecret(): ByteArray {
-            val bytes = BigInteger(128, SecureRandom()).toByteArray()
-            if (bytes.size > 16) {
-                return bytes.copyOfRange(bytes.size - 16, bytes.size)
-            }
-
-            return bytes
-        }
-    }
-
-    var delegate: TestPushDelegate? = null
-
-    @Before
-    fun setup() {
-        // Grant "desktop notification" permission
-        mainSession.delegateUntilTestEnd(object : Callbacks.PermissionDelegate {
-            override fun onContentPermissionRequest(session: GeckoSession, uri: String?, type: Int, callback: GeckoSession.PermissionDelegate.Callback) {
-                assertThat("Should grant DESKTOP_NOTIFICATIONS permission", type, equalTo(GeckoSession.PermissionDelegate.PERMISSION_DESKTOP_NOTIFICATION))
-                callback.grant()
-            }
-        })
-
-        delegate = TestPushDelegate()
-
-        sessionRule.addExternalDelegateUntilTestEnd(WebPushDelegate::class,
-                { d -> sessionRule.runtime.webPushController.setDelegate(d) },
-                { sessionRule.runtime.webPushController.setDelegate(null) }, delegate!!)
-
-
-        mainSession.loadTestPath(PUSH_HTML_PATH)
-        mainSession.waitForPageStop()
-    }
-
-    @After
-    fun tearDown() {
-        sessionRule.runtime.webPushController.setDelegate(null)
-        delegate = null
-    }
-
-    private fun verifySubscription(subscription: JSONObject) {
-        assertThat("Push endpoint should match", subscription.getString("endpoint"), equalTo(PUSH_ENDPOINT))
-
-        val keys = subscription.getJSONObject("keys")
-        val authSecret = Base64.decode(keys.getString("auth"), Base64.URL_SAFE)
-        val encryptionKey = WebPushUtils.keyFromString(keys.getString("p256dh"))
-
-        assertThat("Auth secret should match", authSecret, equalTo(AUTH_SECRET))
-        assertThat("Encryption key should match", encryptionKey, equalTo(BROWSER_KEY_PAIR.public))
-    }
-
-    @Test
-    fun subscribe() {
-        // PushManager.subscribe()
-        val appServerKey = WebPushUtils.keyToString(APP_SERVER_KEY_PAIR.public as ECPublicKey)
-        var pushSubscription = mainSession.evaluatePromiseJS("window.doSubscribe(\"$appServerKey\")").value as JSONObject
-        assertThat("Should have a stored subscription", delegate!!.storedSubscription, notNullValue())
-        verifySubscription(pushSubscription)
-
-        // PushManager.getSubscription()
-        pushSubscription = mainSession.evaluatePromiseJS("window.doGetSubscription()").value as JSONObject
-        verifySubscription(pushSubscription)
-    }
-
-    @Test
-    fun subscribeNoAppServerKey() {
-        // PushManager.subscribe()
-        var pushSubscription = mainSession.evaluatePromiseJS("window.doSubscribe()").value as JSONObject
-        assertThat("Should have a stored subscription", delegate!!.storedSubscription, notNullValue())
-        verifySubscription(pushSubscription)
-
-        // PushManager.getSubscription()
-        pushSubscription = mainSession.evaluatePromiseJS("window.doGetSubscription()").value as JSONObject
-        verifySubscription(pushSubscription)
-    }
-
-    @Test
-    fun unsubscribe() {
-        subscribe()
-
-        // PushManager.unsubscribe()
-        val unsubResult = mainSession.evaluatePromiseJS("window.doUnsubscribe()").value as JSONObject
-        assertThat("Unsubscribe result should be non-null", unsubResult, notNullValue())
-        assertThat("Should not have a stored subscription", delegate!!.storedSubscription, nullValue())
-    }
-
-    @Test
-    fun pushEvent() {
-        subscribe()
-
-        val p = mainSession.evaluatePromiseJS("window.doWaitForPushEvent()")
-
-        val testPayload = "The Payload";
-        sessionRule.runtime.webPushController.onPushEvent(delegate!!.storedSubscription!!, testPayload.toByteArray(Charsets.UTF_8))
-
-        assertThat("Push data should match", p.value as String, equalTo(testPayload))
-    }
-
-    @Test
-    fun subscriptionChanged() {
-        subscribe()
-
-        val p = mainSession.evaluatePromiseJS("window.doWaitForSubscriptionChange()")
-
-        sessionRule.runtime.webPushController.onSubscriptionChanged(delegate!!.storedSubscription!!)
-
-        assertThat("Result should not be null", p.value, notNullValue())
-    }
-
-    @Test(expected = IllegalArgumentException::class)
-    fun invalidDuplicateKeys() {
-        WebPushSubscription("https://scope", PUSH_ENDPOINT,
-                WebPushUtils.keyToBytes(APP_SERVER_KEY_PAIR.public as ECPublicKey),
-                WebPushUtils.keyToBytes(APP_SERVER_KEY_PAIR.public as ECPublicKey)!!, AUTH_SECRET)
-    }
-
-    @Test
-    fun parceling() {
-        val testScope = "https://test.scope";
-        val sub = WebPushSubscription(testScope, PUSH_ENDPOINT,
-                WebPushUtils.keyToBytes(APP_SERVER_KEY_PAIR.public as ECPublicKey),
-                WebPushUtils.keyToBytes(BROWSER_KEY_PAIR.public as ECPublicKey)!!, AUTH_SECRET)
-
-        val parcel = Parcel.obtain()
-        sub.writeToParcel(parcel, 0)
-        parcel.setDataPosition(0)
-
-        val sub2 = WebPushSubscription.CREATOR.createFromParcel(parcel)
-        assertThat("Scope should match", sub.scope, equalTo(sub2.scope))
-        assertThat("Endpoint should match", sub.endpoint, equalTo(sub2.endpoint))
-        assertThat("App server key should match", sub.appServerKey, equalTo(sub2.appServerKey))
-        assertThat("Encryption key should match", sub.browserPublicKey, equalTo(sub2.browserPublicKey))
-        assertThat("Auth secret should match", sub.authSecret, equalTo(sub2.authSecret))
-    }
-
-    class TestPushDelegate : WebPushDelegate {
-        var storedSubscription: WebPushSubscription? = null
-
-        override fun onGetSubscription(scope: String): GeckoResult<WebPushSubscription>? {
-            return GeckoResult.fromValue(storedSubscription)
-        }
-
-        override fun onUnsubscribe(scope: String): GeckoResult<Void>? {
-            storedSubscription = null
-            return GeckoResult.fromValue(null)
-        }
-
-        override fun onSubscribe(scope: String, appServerKey: ByteArray?): GeckoResult<WebPushSubscription>? {
-            appServerKey?.let { assertThat("Application server key should match", it, equalTo(WebPushUtils.keyToBytes(APP_SERVER_KEY_PAIR.public as ECPublicKey))) }
-            storedSubscription = WebPushSubscription(scope, PUSH_ENDPOINT, appServerKey, WebPushUtils.keyToBytes(BROWSER_KEY_PAIR.public as ECPublicKey)!!, AUTH_SECRET)
-            return GeckoResult.fromValue(storedSubscription)
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/WebPushUtils.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/* -*- 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.test;
-
-import android.support.annotation.AnyThread;
-import android.support.annotation.Nullable;
-import android.util.Base64;
-
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.KeyFactory;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECGenParameterSpec;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.EllipticCurve;
-import java.security.spec.InvalidKeySpecException;
-
-/**
- * Utilities for converting {@link ECPublicKey} to/from X9.62 encoding.
- *
- * @see <a href="https://tools.ietf.org/html/rfc8291">Message Encryption for Web Push</a>
- */
-/* package */ class WebPushUtils {
-    public static final int P256_PUBLIC_KEY_LENGTH = 65; // 1 + 32 + 32
-    private static final byte NIST_HEADER = 0x04; // uncompressed format
-
-    private static ECParameterSpec sSpec;
-
-    private WebPushUtils() {
-    }
-
-    /**
-     * Encodes an {@link ECPublicKey} into X9.62 format as required
-     * by Web Push.
-     *
-     * @param key the {@link ECPublicKey} to encode
-     * @return the encoded {@link ECPublicKey}
-     */
-    @AnyThread
-    public static @Nullable byte[] keyToBytes(final @Nullable ECPublicKey key) {
-        if (key == null) {
-            return null;
-        }
-
-        final ByteBuffer buffer = ByteBuffer.allocate(P256_PUBLIC_KEY_LENGTH);
-        buffer.put(NIST_HEADER);
-
-        putUnsignedBigInteger(buffer, key.getW().getAffineX());
-        putUnsignedBigInteger(buffer, key.getW().getAffineY());
-
-        if (buffer.position() != P256_PUBLIC_KEY_LENGTH) {
-            throw new RuntimeException("Unexpected key length " + buffer.position());
-        }
-
-        return buffer.array();
-    }
-
-    private static void putUnsignedBigInteger(final ByteBuffer buffer, final BigInteger value) {
-        final byte[] bytes = value.toByteArray();
-        if (bytes.length < 32) {
-            buffer.put(new byte[32 - bytes.length]);
-            buffer.put(bytes);
-        } else {
-            buffer.put(bytes, bytes.length - 32, 32);
-        }
-    }
-
-    /**
-     * Encodes an {@link ECPublicKey} into X9.62 format as required
-     * by Web Push, further encoded into Base64.
-     *
-     * @param key the {@link ECPublicKey} to encode
-     * @return the encoded {@link ECPublicKey}
-     */
-    @AnyThread
-    public static @Nullable String keyToString(final @Nullable ECPublicKey key) {
-        return Base64.encodeToString(keyToBytes(key), Base64.URL_SAFE | Base64.NO_WRAP | Base64.NO_PADDING);
-    }
-
-    /**
-     * @return A {@link ECParameterSpec} for P-256 (secp256r1).
-     */
-    public static ECParameterSpec getP256Spec() {
-        if (sSpec == null) {
-            try {
-                final KeyPairGenerator gen = KeyPairGenerator.getInstance("EC");
-                final ECGenParameterSpec genSpec = new ECGenParameterSpec("secp256r1");
-                gen.initialize(genSpec);
-                sSpec = ((ECPublicKey) gen.generateKeyPair().getPublic()).getParams();
-            } catch (NoSuchAlgorithmException e) {
-                throw new RuntimeException(e);
-            } catch (InvalidAlgorithmParameterException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        return sSpec;
-    }
-
-    /**
-     * Converts a Base64 X9.62 encoded Web Push key into a {@link ECPublicKey}.
-     *
-     * @param base64Bytes the X9.62 data as Base64
-     * @return a {@link ECPublicKey}
-     */
-    @AnyThread
-    public static @Nullable ECPublicKey keyFromString(final @Nullable String base64Bytes) {
-        if (base64Bytes == null) {
-            return null;
-        }
-
-        return keyFromBytes(Base64.decode(base64Bytes, Base64.URL_SAFE));
-    }
-
-    private static BigInteger readUnsignedBigInteger(final byte[] bytes, final int offset, final int length) {
-        byte[] mag = bytes;
-        if (offset != 0 || length != bytes.length) {
-            mag = new byte[length];
-            System.arraycopy(bytes, offset, mag, 0, length);
-        }
-        return new BigInteger(1, mag);
-    }
-
-    /**
-     * Converts a X9.62 encoded Web Push key into a {@link ECPublicKey}.
-     *
-     * @param bytes the X9.62 data
-     * @return a {@link ECPublicKey}
-     */
-    @AnyThread
-    public static @Nullable ECPublicKey keyFromBytes(final @Nullable byte[] bytes) {
-        if (bytes == null) {
-            return null;
-        }
-
-        if (bytes.length != P256_PUBLIC_KEY_LENGTH) {
-            throw new IllegalArgumentException(String.format("Expected exactly %d bytes", P256_PUBLIC_KEY_LENGTH));
-        }
-
-        if (bytes[0] != NIST_HEADER) {
-            throw new IllegalArgumentException("Expected uncompressed NIST format");
-        }
-
-        try {
-            final BigInteger x = readUnsignedBigInteger(bytes, 1, 32);
-            final BigInteger y = readUnsignedBigInteger(bytes, 33, 32);
-
-            final ECPoint point = new ECPoint(x, y);
-            final ECPublicKeySpec spec = new ECPublicKeySpec(point, getP256Spec());
-            final KeyFactory factory = KeyFactory.getInstance("EC");
-            final ECPublicKey key = (ECPublicKey) factory.generatePublic(spec);
-
-            return key;
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        } catch (InvalidKeySpecException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/Base64Utils.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.mozilla.geckoview;
-
-import org.mozilla.gecko.annotation.WrapForJNI;
-
-/**
- * This class exposes the Base64 URL encode/decode functions from Gecko. They are different
- * from android.util.Base64 in that they always use URL encoding, no padding, and are
- * constant time. The last bit is important when dealing with values that might be secret
- * as we do with Web Push.
- */
-/* package */ class Base64Utils {
-    @WrapForJNI public static native byte[] decode(final String data);
-    @WrapForJNI public static native String encode(final byte[] data);
-}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoRuntime.java
@@ -160,17 +160,16 @@ public final class GeckoRuntime implemen
     private static GeckoRuntime sRuntime;
     private GeckoRuntimeSettings mSettings;
     private Delegate mDelegate;
     private WebNotificationDelegate mNotificationDelegate;
     private RuntimeTelemetry mTelemetry;
     private final WebExtensionEventDispatcher mWebExtensionDispatcher;
     private StorageController mStorageController;
     private final WebExtensionController mWebExtensionController;
-    private WebPushController mPushController;
 
     private GeckoRuntime() {
         mWebExtensionDispatcher = new WebExtensionEventDispatcher();
         mWebExtensionController = new WebExtensionController(this, mWebExtensionDispatcher);
         if (sRuntime != null) {
             throw new IllegalStateException("Only one GeckoRuntime instance is allowed");
         }
         sRuntime = this;
@@ -644,34 +643,16 @@ public final class GeckoRuntime implemen
         ThreadUtils.assertOnUiThread();
 
         if (mStorageController == null) {
             mStorageController = new StorageController();
         }
         return mStorageController;
     }
 
-    /**
-     * Get the Web Push controller for this runtime.
-     * The Web Push controller can be used to allow content
-     * to use the Web Push API.
-     *
-     * @return The {@link WebPushController} for this instance.
-     */
-    @UiThread
-    public @NonNull WebPushController getWebPushController() {
-        ThreadUtils.assertOnUiThread();
-
-        if (mPushController == null) {
-            mPushController = new WebPushController();
-        }
-
-        return mPushController;
-    }
-
     @Override // Parcelable
     @AnyThread
     public int describeContents() {
         return 0;
     }
 
     @Override // Parcelable
     @AnyThread
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushController.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/* -*- 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 org.mozilla.gecko.EventDispatcher;
-import org.mozilla.gecko.util.BundleEventListener;
-import org.mozilla.gecko.util.EventCallback;
-import org.mozilla.gecko.util.GeckoBundle;
-import org.mozilla.gecko.util.ThreadUtils;
-
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.UiThread;
-
-public class WebPushController {
-    private static final String LOGTAG = "WebPushController";
-
-    private WebPushDelegate mDelegate;
-    private BundleEventListener mEventListener;
-
-    /* package */ WebPushController() {
-        mEventListener = new EventListener();
-        EventDispatcher.getInstance().registerUiThreadListener(mEventListener,
-                "GeckoView:PushSubscribe",
-                "GeckoView:PushUnsubscribe",
-                "GeckoView:PushGetSubscription");
-    }
-
-    /**
-     * Sets the {@link WebPushDelegate} for this instance.
-     *
-     * @param delegate The {@link WebPushDelegate} instance.
-     */
-    @UiThread
-    public void setDelegate(final @Nullable WebPushDelegate delegate) {
-        ThreadUtils.assertOnUiThread();
-        mDelegate = delegate;
-    }
-
-    /**
-     * Send a push event for a given subscription.
-     *
-     * @param subscription The WebPushSubscription that the event belongs to.
-     */
-    @UiThread
-    public void onPushEvent(final @NonNull WebPushSubscription subscription) {
-        ThreadUtils.assertOnUiThread();
-        onPushEvent(subscription, null);
-    }
-
-    /**
-     * Send a push event with a payload for a given subscription.
-     *
-     * @param subscription The WebPushSubscription that the event belongs to.
-     * @param data The unencrypted payload.
-     */
-    @UiThread
-    public void onPushEvent(final @NonNull WebPushSubscription subscription, final @Nullable byte[] data) {
-        ThreadUtils.assertOnUiThread();
-
-        final GeckoBundle msg = new GeckoBundle(2);
-        msg.putBundle("subscription", subscription.toBundle());
-        msg.putString("data", Base64Utils.encode(data));
-        EventDispatcher.getInstance().dispatch("GeckoView:PushEvent", msg);
-    }
-
-    /**
-     * Notify that a given subscription has changed. This is normally a signal to the content
-     * that it needs to re-subscribe.
-     *
-     * @param subscription The subscription that changed.
-     */
-    @UiThread
-    public void onSubscriptionChanged(final @NonNull WebPushSubscription subscription) {
-        ThreadUtils.assertOnUiThread();
-
-        final GeckoBundle msg = new GeckoBundle(1);
-        msg.putBundle("subscription", subscription.toBundle());
-        EventDispatcher.getInstance().dispatch("GeckoView:PushSubscriptionChanged", msg);
-    }
-
-    private class EventListener implements BundleEventListener {
-
-        @Override
-        public void handleMessage(final String event, final GeckoBundle message, final EventCallback callback) {
-            if (mDelegate == null) {
-                callback.sendError("Not allowed");
-                return;
-            }
-
-            switch (event) {
-                case "GeckoView:PushSubscribe": {
-                    byte[] appServerKey = null;
-                    if (message.containsKey("appServerKey")) {
-                        appServerKey = Base64Utils.decode(message.getString("appServerKey"));
-                    }
-
-                    final GeckoResult<WebPushSubscription> result =
-                            mDelegate.onSubscribe(message.getString("scope"), appServerKey);
-
-                    if (result == null) {
-                        callback.sendSuccess(null);
-                        return;
-                    }
-
-                    result.accept(subscription -> callback.sendSuccess(subscription != null ? subscription.toBundle() : null),
-                        error -> callback.sendSuccess(null));
-                    break;
-                }
-                case "GeckoView:PushUnsubscribe": {
-                    final GeckoResult<Void> result = mDelegate.onUnsubscribe(message.getString("scope"));
-                    if (result == null) {
-                        callback.sendSuccess(null);
-                        return;
-                    }
-
-                    result.accept(val -> callback.sendSuccess(null), err -> callback.sendError(err.getMessage()));
-                    break;
-                }
-                case "GeckoView:PushGetSubscription": {
-                    final GeckoResult<WebPushSubscription> result = mDelegate.onGetSubscription(message.getString("scope"));
-                    if (result == null) {
-                        callback.sendSuccess(null);
-                        return;
-                    }
-
-                    result.accept(subscription -> callback.sendSuccess(subscription != null ? subscription.toBundle() : null),
-                        err -> callback.sendError(err.getMessage()));
-                    break;
-                }
-            }
-        }
-    }
-}
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushDelegate.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/* -*- 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.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.annotation.UiThread;
-
-public interface WebPushDelegate {
-    /**
-     * Creates a push subscription for the given service worker scope. A scope
-     * uniquely identifies a service worker. `appServerKey` optionally
-     * creates a restricted subscription.
-     *
-     * Applications will likely want to persist the returned {@link WebPushSubscription} in order
-     * to support {@link #onGetSubscription(String)}.
-     *
-     * @param scope The Service Worker scope.
-     * @param appServerKey An optional application server key.
-     * @return A {@link GeckoResult} which resolves to a {@link WebPushSubscription}
-     *
-     * @see <a href="http://w3c.github.io/push-api/#dom-pushmanager-subscribe">subscribe()</a>
-     * @see <a href="http://w3c.github.io/push-api/#dom-pushsubscriptionoptionsinit-applicationserverkey">Application server key</a>
-     */
-    @UiThread
-    default @Nullable GeckoResult<WebPushSubscription> onSubscribe(@NonNull String scope,
-                                                                   @Nullable byte[] appServerKey) {
-        return null;
-    }
-
-    /**
-     * Retrieves a subscription for the given service worker scope.
-     *
-     * @param scope The scope for the requested {@link WebPushSubscription}.
-     * @return A {@link GeckoResult} which resolves to a {@link WebPushSubscription}
-     *
-     * @see <a href="http://w3c.github.io/push-api/#dom-pushmanager-getsubscription">getSubscription()</a>
-     */
-    @UiThread
-    default @Nullable GeckoResult<WebPushSubscription> onGetSubscription(@NonNull String scope) {
-        return null;
-    }
-
-    /**
-     * Removes a push subscription. If this fails, apps should resolve the
-     * returned {@link GeckoResult} with an exception.
-     *
-     * @param scope The Service Worker scope for the subscription.
-     * @return A {@link GeckoResult}, which if non-exceptional indicates successfully unsubscribing.
-     *
-     * @see <a href="http://w3c.github.io/push-api/#dom-pushsubscription-unsubscribe">unsubscribe()</a>
-     */
-    @UiThread
-    default @Nullable GeckoResult<Void> onUnsubscribe(@NonNull String scope) {
-        return null;
-    }
-}
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebPushSubscription.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- 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 org.mozilla.gecko.util.GeckoBundle;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.support.annotation.AnyThread;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-
-import java.util.Arrays;
-
-/**
- * This class represents a single Web Push subscription, as described in
- * the <a href="https://www.w3.org/TR/push-api/">Web Push API</a> specification.
- *
- * This is a low-level interface, allowing applications to do all of the heavy lifting
- * themselves. It is recommended that consumers have a thorough understanding of the
- * Web Push API, especially <a href="https://tools.ietf.org/html/rfc8291">RFC 8291</a>.
- *
- * Only trivial sanity checks are performed on the values held here. The application must
- * ensure it is generating compliant keys/secrets itself.
- */
-public class WebPushSubscription implements Parcelable {
-    private static final int P256_PUBLIC_KEY_LENGTH = 65;
-
-    /**
-     * The Service Worker scope associated with this subscription.
-     *
-     * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register">ServiceWorker registration</a>
-     */
-    @NonNull
-    public final String scope;
-
-    /**
-     * The Web Push endpoint for this subscription. This is the URL of a web service which
-     * implements the Web Push protocol.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc8030#section-5">RFC 8030</a>
-     */
-    @NonNull
-    public final String endpoint;
-
-    /**
-     * This is an optional public key provided by the application server to authenticate
-     * itself with the endpoint, formatted according to X9.62.
-     *
-     * This key is used for VAPID, the Voluntary Application Server Identification (VAPID)
-     * for Web Push, from <a href="https://tools.ietf.org/html/rfc8292">RFC 8292</a>.
-     *
-     * @see <a href="https://www.w3.org/TR/push-api/#dom-pushsubscriptionoptions-applicationserverkey">applicationServerKey</a>
-     * @see <a href="https://tools.ietf.org/html/rfc8291">Message Encryption for Web Push</a>
-     */
-    @Nullable
-    public final byte[] appServerKey;
-
-    /**
-     * The P-256 EC public key, formatted as X9.62, generated by the embedder, to be provided
-     * to the app server for message encryption.
-     *
-     * @see <a href="https://www.w3.org/TR/push-api/#dom-pushencryptionkeyname-p256dh">PushEncryptionKeyName - p256dh</a>
-     * @see <a href="https://tools.ietf.org/html/rfc8291#section-3.1">RFC 8291 section 3.1</a>
-     */
-    @NonNull
-    public final byte[] browserPublicKey;
-
-    /**
-     * 16 byte secret key, generated by the embedder, to be provided to the app server for use
-     * in encrypting and authenticating messages sent to the {@link #endpoint}.
-     *
-     * @see <a href="https://www.w3.org/TR/push-api/#dom-pushencryptionkeyname-auth">PushEncryptionKeyName - auth</a>
-     * @see <a href="https://tools.ietf.org/html/rfc8291#section-3.2">RFC 8291, section 3.2</a>
-     */
-    @NonNull
-    public final byte[] authSecret;
-
-    public WebPushSubscription(final @NonNull String scope,
-                               final @NonNull String endpoint,
-                               final @Nullable byte[] appServerKey,
-                               final @NonNull byte[] browserPublicKey,
-                               final @NonNull byte[] authSecret) {
-        this.scope = scope;
-        this.endpoint = endpoint;
-        this.appServerKey = appServerKey;
-        this.browserPublicKey = browserPublicKey;
-        this.authSecret = authSecret;
-
-        if (appServerKey != null) {
-            if (appServerKey.length != P256_PUBLIC_KEY_LENGTH) {
-                throw new IllegalArgumentException(String.format("appServerKey should be %d bytes", P256_PUBLIC_KEY_LENGTH));
-            }
-
-            if (Arrays.equals(appServerKey, browserPublicKey)) {
-                throw new IllegalArgumentException("appServerKey and browserPublicKey must differ");
-            }
-        }
-
-        if (browserPublicKey.length != P256_PUBLIC_KEY_LENGTH) {
-            throw new IllegalArgumentException(String.format("browserPublicKey should be %d bytes", P256_PUBLIC_KEY_LENGTH));
-        }
-
-        if (authSecret.length != 16) {
-            throw new IllegalArgumentException("authSecret must be 128 bits");
-        }
-    }
-
-    private WebPushSubscription(final Parcel in) {
-        this.scope = in.readString();
-        this.endpoint = in.readString();
-
-        if (ParcelableUtils.readBoolean(in)) {
-            this.appServerKey = new byte[P256_PUBLIC_KEY_LENGTH];
-            in.readByteArray(this.appServerKey);
-        } else {
-            appServerKey = null;
-        }
-
-        this.browserPublicKey = new byte[P256_PUBLIC_KEY_LENGTH];
-        in.readByteArray(this.browserPublicKey);
-
-        this.authSecret = new byte[16];
-        in.readByteArray(this.authSecret);
-    }
-
-    /* package */ GeckoBundle toBundle() {
-        final GeckoBundle bundle = new GeckoBundle(5);
-        bundle.putString("scope", scope);
-        bundle.putString("endpoint", endpoint);
-        if (appServerKey != null) {
-            bundle.putString("appServerKey", Base64Utils.encode(appServerKey));
-        }
-        bundle.putString("browserPublicKey", Base64Utils.encode(browserPublicKey));
-        bundle.putString("authSecret", Base64Utils.encode(authSecret));
-        return bundle;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(final Parcel out, final int flags) {
-        out.writeString(scope);
-        out.writeString(endpoint);
-
-        ParcelableUtils.writeBoolean(out, appServerKey != null);
-        if (appServerKey != null) {
-            out.writeByteArray(appServerKey);
-        }
-
-        out.writeByteArray(browserPublicKey);
-        out.writeByteArray(authSecret);
-    }
-
-    public static final Parcelable.Creator<WebPushSubscription> CREATOR = new Parcelable.Creator<WebPushSubscription>() {
-        @Override
-        @AnyThread
-        public WebPushSubscription createFromParcel(final Parcel parcel) {
-            return new WebPushSubscription(parcel);
-        }
-
-        @Override
-        @AnyThread
-        public WebPushSubscription[] newArray(final int size) {
-            return new WebPushSubscription[size];
-        }
-    };
-}
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/doc-files/CHANGELOG.md
@@ -43,18 +43,16 @@ exclude: true
 - Updated [`ContentBlocking`][70.13] to better report blocked and allowed ETP events.
   ([bug 1567268]({{bugzilla}}1567268))
 - Added API for controlling Gecko logging [`GeckoRuntimeSettings.debugLogging`][70.14]
   ([bug 1573304]({{bugzilla}}1573304))
 - Added [`WebNotification`][70.15] and [`WebNotificationDelegate`][70.16] for handling Web Notifications.
   ([bug 1533057]({{bugzilla}}1533057))
 - Added Social Tracking Protection support to [`ContentBlocking`][70.17].
   ([bug 1568295]({{bugzilla}}1568295))
-- Added support for Web Push via [`WebPushController`][70.18], [`WebPushDelegate`][70.19], and
-  [`WebPushSubscription`][70.20].
 
 [70.1]: {{javadoc_uri}}/GeckoSessionSettings.Builder.html#contextId-java.lang.String-
 [70.2]: {{javadoc_uri}}/StorageController.html#clearDataForSessionContext-java.lang.String-
 [70.3]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-java.io.File-java.io.File-java.lang.String-
 [70.4]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-java.io.File-java.util.Map-java.lang.String-
 [70.5]: {{javadoc_uri}}/GeckoView.html
 [70.6]: {{javadoc_uri}}/GeckoSession.html
 [70.7]: {{javadoc_uri}}/GeckoSession.PromptDelegate.html#CAPTURE_TYPE_NONE
@@ -63,19 +61,16 @@ exclude: true
 [70.10]: {{javadoc_uri}}/GeckoView.html#setSession-org.mozilla.geckoview.GeckoSession-
 [70.11]: {{javadoc_uri}}/GeckoSession.PromptDelegate.html
 [70.12]: {{javadoc_uri}}/RuntimeTelemetry.Delegate.html
 [70.13]: {{javadoc_uri}}/ContentBlocking.html
 [70.14]: {{javadoc_uri}}/GeckoRuntimeSettings.Builder.html#debugLogging-boolean-
 [70.15]: {{javadoc_uri}}/WebNotification.html
 [70.16]: {{javadoc_uri}}/WebNotificationDelegate.html
 [70.17]: {{javadoc_uri}}/ContentBlocking.html
-[70.18]: {{javadoc_uri}}/WebPushController.html
-[70.19]: {{javadoc_uri}}/WebPushDelegate.html
-[70.20]: {{javadoc_uri}}/WebPushSubscription.html
 
 ## v69
 - Modified behavior of ['setAutomaticFontSizeAdjustment'][69.1] so that it no 
   longer has any effect on ['setFontInflationEnabled'][69.2]
 - Add [GeckoSession.LOAD_FLAGS_FORCE_ALLOW_DATA_URI][69.14]
 - Added [`GeckoResult.accept`][69.3] for consuming a result without
   transforming it.
 - [`GeckoSession.setMessageDelegate`][69.13] callers must now specify the
@@ -318,9 +313,9 @@ exclude: true
 [65.19]: {{javadoc_uri}}/GeckoSession.NavigationDelegate.LoadRequest.html#isRedirect
 [65.20]: {{javadoc_uri}}/GeckoSession.html#LOAD_FLAGS_BYPASS_CLASSIFIER    
 [65.21]: {{javadoc_uri}}/GeckoSession.ContentDelegate.ContextElement.html
 [65.22]: {{javadoc_uri}}/GeckoSession.ContentDelegate.html#onContextMenu-org.mozilla.geckoview.GeckoSession-int-int-org.mozilla.geckoview.GeckoSession.ContentDelegate.ContextElement-
 [65.23]: {{javadoc_uri}}/GeckoSession.FinderResult.html
 [65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
 [65.25]: {{javadoc_uri}}/GeckoResult.html
 
-[api-version]: 8ecf6e4cd7db924c5966e8c956df7fbc502fa4be
+[api-version]: 3dc92af421d9e7e2393619f7a17c57422aa51699
--- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java
@@ -38,21 +38,18 @@ import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Environment;
-import android.os.Handler;
 import android.os.SystemClock;
-import android.security.keystore.KeyProperties;
 import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
 import android.support.v4.app.ActivityCompat;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.NotificationManagerCompat;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
 import android.view.Menu;
@@ -61,21 +58,16 @@ import android.view.MenuItem;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.ProgressBar;
 
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.NoSuchAlgorithmException;
-import java.security.interfaces.ECPublicKey;
-import java.security.spec.ECGenParameterSpec;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.Locale;
 
 public class GeckoViewActivity extends AppCompatActivity {
     private static final String LOGTAG = "GeckoViewActivity";
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -236,17 +236,16 @@
 [mobile]
 @BINPATH@/chrome/geckoview@JAREXT@
 @BINPATH@/chrome/geckoview.manifest
 
 #ifdef MOZ_GECKOVIEW_JAR
 @BINPATH@/components/GeckoView.manifest
 @BINPATH@/components/GeckoViewExternalAppService.js
 @BINPATH@/components/GeckoViewPrompt.js
-@BINPATH@/components/GeckoViewPush.js
 @BINPATH@/components/GeckoViewPermission.js
 @BINPATH@/components/GeckoViewStartup.js
 #else
 @BINPATH@/chrome/chrome@JAREXT@
 @BINPATH@/chrome/chrome.manifest
 @BINPATH@/components/AboutRedirector.js
 @BINPATH@/components/AddonUpdateService.js
 @BINPATH@/components/BlocklistPrompt.js
deleted file mode 100644
--- a/mobile/android/modules/geckoview/GeckoViewPushController.jsm
+++ /dev/null
@@ -1,77 +0,0 @@
-/* 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/. */
-
-"use strict";
-
-var EXPORTED_SYMBOLS = ["GeckoViewPushController"];
-
-const { GeckoViewUtils } = ChromeUtils.import(
-  "resource://gre/modules/GeckoViewUtils.jsm"
-);
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-
-XPCOMUtils.defineLazyServiceGetter(
-  this,
-  "PushNotifier",
-  "@mozilla.org/push/Notifier;1",
-  "nsIPushNotifier"
-);
-
-// eslint-disable-next-line no-unused-vars
-const { debug, warn } = GeckoViewUtils.initLogging("GeckoViewPushController");
-
-function createScopeAndPrincipal(scopeAndAttrs) {
-  const [scope, attrs] = scopeAndAttrs.split("^");
-  const uri = Services.io.newURI(scope);
-
-  return [
-    scope,
-    Services.scriptSecurityManager.createContentPrincipal(
-      uri,
-      ChromeUtils.createOriginAttributesFromOrigin(attrs)
-    ),
-  ];
-}
-
-const GeckoViewPushController = {
-  onEvent(aEvent, aData, aCallback) {
-    debug`onEvent ${aEvent} ${aData}`;
-
-    switch (aEvent) {
-      case "GeckoView:PushEvent": {
-        const {
-          subscription: { scope },
-          data,
-        } = aData;
-
-        const [url, principal] = createScopeAndPrincipal(scope);
-
-        if (!data) {
-          PushNotifier.notifyPush(url, principal);
-          return;
-        }
-
-        const payload = new Uint8Array(
-          ChromeUtils.base64URLDecode(data, { padding: "ignore" })
-        );
-
-        PushNotifier.notifyPushWithData(url, principal, "", payload);
-        break;
-      }
-      case "GeckoView:PushSubscriptionChanged": {
-        const {
-          subscription: { scope },
-        } = aData;
-
-        const [url, principal] = createScopeAndPrincipal(scope);
-
-        PushNotifier.notifySubscriptionChange(url, principal);
-        break;
-      }
-    }
-  },
-};
--- a/mobile/android/modules/geckoview/moz.build
+++ b/mobile/android/modules/geckoview/moz.build
@@ -12,17 +12,16 @@ EXTRA_JS_MODULES += [
     'GeckoViewAutoFill.jsm',
     'GeckoViewChildModule.jsm',
     'GeckoViewConsole.jsm',
     'GeckoViewContent.jsm',
     'GeckoViewMedia.jsm',
     'GeckoViewModule.jsm',
     'GeckoViewNavigation.jsm',
     'GeckoViewProgress.jsm',
-    'GeckoViewPushController.jsm',
     'GeckoViewRemoteDebugger.jsm',
     'GeckoViewSettings.jsm',
     'GeckoViewStorageController.jsm',
     'GeckoViewTab.jsm',
     'GeckoViewTelemetry.jsm',
     'GeckoViewUtils.jsm',
     'GeckoViewWebExtension.jsm',
     'LoadURIDelegate.jsm',
deleted file mode 100644
--- a/widget/android/Base64UtilsSupport.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; tab-width: 20; indent-tabs-mode: nil; -*-
- * 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/. */
-
-#ifndef Base64UtilsSupport_h__
-#define Base64UtilsSupport_h__
-
-#include "GeneratedJNINatives.h"
-#include "mozilla/Base64.h"
-
-namespace mozilla {
-namespace widget {
-
-class Base64UtilsSupport final
-    : public java::Base64Utils::Natives<Base64UtilsSupport> {
- public:
-  static jni::ByteArray::LocalRef Decode(jni::String::Param data) {
-    FallibleTArray<uint8_t> bytes;
-    if (NS_FAILED(Base64URLDecode(
-            data->ToCString(), Base64URLDecodePaddingPolicy::Ignore, bytes))) {
-      return nullptr;
-    }
-
-    return jni::ByteArray::New((const signed char*)bytes.Elements(),
-                               bytes.Length());
-  }
-
-  static jni::String::LocalRef Encode(jni::ByteArray::Param data) {
-    nsTArray<int8_t> bytes = data->GetElements();
-    nsCString result;
-    if (NS_FAILED(
-            Base64URLEncode(data->Length(), (const uint8_t*)bytes.Elements(),
-                            Base64URLEncodePaddingPolicy::Omit, result))) {
-      return nullptr;
-    }
-    return jni::StringParam(result);
-  }
-};
-
-}  // namespace widget
-}  // namespace mozilla
-
-#endif  // Base64UtilsSupport_h__
--- a/widget/android/nsAppShell.cpp
+++ b/widget/android/nsAppShell.cpp
@@ -67,17 +67,16 @@
 #include "GeckoTelemetryDelegate.h"
 #include "GeckoVRManager.h"
 #include "PrefsHelper.h"
 #include "ScreenHelperAndroid.h"
 #include "Telemetry.h"
 #include "fennec/MemoryMonitor.h"
 #include "fennec/ThumbnailHelper.h"
 #include "WebExecutorSupport.h"
-#include "Base64UtilsSupport.h"
 
 #ifdef DEBUG_ANDROID_EVENTS
 #  define EVLOG(args...) ALOG(args)
 #else
 #  define EVLOG(args...) \
     do {                 \
     } while (0)
 #endif
@@ -408,17 +407,16 @@ nsAppShell::nsAppShell()
     mozilla::GeckoBatteryManager::Init();
     mozilla::GeckoNetworkManager::Init();
     mozilla::GeckoProcessManager::Init();
     mozilla::GeckoScreenOrientation::Init();
     mozilla::GeckoSystemStateListener::Init();
     mozilla::PrefsHelper::Init();
     mozilla::widget::Telemetry::Init();
     mozilla::widget::WebExecutorSupport::Init();
-    mozilla::widget::Base64UtilsSupport::Init();
     nsWindow::InitNatives();
     mozilla::gl::AndroidSurfaceTexture::Init();
     mozilla::WebAuthnTokenManager::Init();
     mozilla::widget::GeckoTelemetryDelegate::Init();
 
     if (jni::IsFennec()) {
       BrowserLocaleManagerSupport::Init();
       mozilla::ANRReporter::Init();