Backed out changeset a6b390c7b979 (bug 1498246) for failures on org.mozilla.geckoview.test.GeckoSessionTestRuleTest.includesAllCallbacks. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Fri, 09 Nov 2018 02:47:36 +0200
changeset 445326 758408e4e612af2a86f1cf8a50a77604a923db0e
parent 445325 46dbc3229ed09b52e31c2f7adad962878b8c460b
child 445327 343511c3bccd8a4b035fa7628c3813f5aab3ea15
push id109718
push userrgurzau@mozilla.com
push dateFri, 09 Nov 2018 05:49:16 +0000
treeherdermozilla-inbound@58c02c05d2db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1498246
milestone65.0a1
backs outa6b390c7b9791dfa760f9b09248ff84bd2a4c3e6
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 changeset a6b390c7b979 (bug 1498246) for failures on org.mozilla.geckoview.test.GeckoSessionTestRuleTest.includesAllCallbacks. CLOSED TREE
mobile/android/chrome/geckoview/GeckoViewMediaChild.js
mobile/android/chrome/geckoview/geckoview.js
mobile/android/chrome/geckoview/jar.mn
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/MediaElement.java
mobile/android/modules/geckoview/GeckoViewMedia.jsm
mobile/android/modules/geckoview/moz.build
deleted file mode 100644
--- a/mobile/android/chrome/geckoview/GeckoViewMediaChild.js
+++ /dev/null
@@ -1,433 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* 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";
-ChromeUtils.import("resource://gre/modules/GeckoViewChildModule.jsm");
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-
-class GeckoViewMediaChild extends GeckoViewChildModule {
-  onInit() {
-    this._videoIndex = 0;
-    XPCOMUtils.defineLazyGetter(this, "_videos", () =>
-      new Map());
-    this._mediaEvents = [
-      "abort", "canplay", "canplaythrough", "durationchange", "emptied",
-      "ended", "error", "loadeddata", "loadedmetadata", "pause", "play", "playing",
-      "progress", "ratechange", "resize", "seeked", "seeking", "stalled", "suspend",
-      "timeupdate", "volumechange", "waiting",
-    ];
-
-    this._mediaEventCallback = (event) => {
-      this.handleMediaEvent(event);
-    };
-    this._fullscreenMedia = null;
-    this._stateSymbol = Symbol();
-  }
-
-  onEnable() {
-    debug `onEnable`;
-    addEventListener("UAWidgetBindToTree", this, false);
-    addEventListener("MozDOMFullscreen:Entered", this, false);
-    addEventListener("MozDOMFullscreen:Exited", this, false);
-    addEventListener("pagehide", this, false);
-
-    this.messageManager.addMessageListener("GeckoView:MediaObserve", this);
-    this.messageManager.addMessageListener("GeckoView:MediaUnobserve", this);
-    this.messageManager.addMessageListener("GeckoView:MediaPlay", this);
-    this.messageManager.addMessageListener("GeckoView:MediaPause", this);
-    this.messageManager.addMessageListener("GeckoView:MediaSeek", this);
-    this.messageManager.addMessageListener("GeckoView:MediaSetVolume", this);
-    this.messageManager.addMessageListener("GeckoView:MediaSetMuted", this);
-    this.messageManager.addMessageListener("GeckoView:MediaSetPlaybackRate", this);
-  }
-
-  onDisable() {
-    debug `onDisable`;
-
-    removeEventListener("UAWidgetBindToTree", this);
-    removeEventListener("MozDOMFullscreen:Entered", this);
-    removeEventListener("MozDOMFullscreen:Exited", this);
-    removeEventListener("pagehide", this);
-
-    this.messageManager.removeMessageListener("GeckoView:MediaObserve", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaUnobserve", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaPlay", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaPause", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaSeek", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaSetVolume", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaSetMuted", this);
-    this.messageManager.removeMessageListener("GeckoView:MediaSetPlaybackRate", this);
-  }
-
-  receiveMessage(aMsg) {
-    debug `receiveMessage: ${aMsg.name}`;
-
-    const data = aMsg.data;
-    const element = this.findElement(data.id);
-    if (!element) {
-      warn `Didn't find HTMLMediaElement with id: ${data.id}`;
-      return;
-    }
-
-    switch (aMsg.name) {
-      case "GeckoView:MediaObserve":
-        this.observeMedia(element);
-        break;
-      case "GeckoView:MediaUnobserve":
-        this.unobserveMedia(element);
-        break;
-      case "GeckoView:MediaPlay":
-        element.play();
-        break;
-      case "GeckoView:MediaPause":
-        element.pause();
-        break;
-      case "GeckoView:MediaSeek":
-        element.currentTime = data.time;
-        break;
-      case "GeckoView:MediaSetVolume":
-        element.volume = data.volume;
-        break;
-      case "GeckoView:MediaSetMuted":
-        element.muted = !!data.muted;
-        break;
-      case "GeckoView:MediaSetPlaybackRate":
-        element.playbackRate = data.playbackRate;
-        break;
-    }
-  }
-
-  handleEvent(aEvent) {
-    debug `handleEvent: ${aEvent.type}`;
-
-    switch (aEvent.type) {
-      case "UAWidgetBindToTree":
-        this.handleNewMedia(aEvent.composedTarget);
-        break;
-      case "MozDOMFullscreen:Entered":
-        const element = content && content.document.fullscreenElement;
-        if (this.isMedia(element)) {
-          this.handleFullscreenChange(element);
-        } else {
-          // document.fullscreenElement can be a div container instead of the HTMLMediaElement
-          // in some pages (e.g Vimeo).
-          const childrenMedias = element.getElementsByTagName("video");
-          if (childrenMedias && childrenMedias.length > 0) {
-            this.handleFullscreenChange(childrenMedias[0]);
-          }
-        }
-        break;
-      case "MozDOMFullscreen:Exited":
-        this.handleFullscreenChange(null);
-        break;
-      case "pagehide":
-        if (aEvent.target === content.document) {
-          this.handleWindowUnload();
-        }
-        break;
-    }
-  }
-
-  handleWindowUnload() {
-    for (const weakElement of this._videos.values()) {
-      const element = weakElement.get();
-      if (element) {
-        this.unobserveMedia(element);
-      }
-    }
-    if (this._videos.size > 0) {
-      this.notifyMediaRemoveAll();
-    }
-    this._videos.clear();
-    this._fullscreenMedia = null;
-  }
-
-  handleNewMedia(aElement) {
-    if (this.getState(aElement) || !this.isMedia(aElement)) {
-      return;
-    }
-    const state = {
-      id: ++this._videoIndex,
-      notified: false,
-      observing: false,
-    };
-    aElement[this._stateSymbol] = state;
-    this._videos.set(state.id, Cu.getWeakReference(aElement));
-
-    this.notifyNewMedia(aElement);
-  }
-
-  notifyNewMedia(aElement) {
-    this.getState(aElement).notified = true;
-    const message = {
-      type: "GeckoView:MediaAdd",
-      id: this.getState(aElement).id,
-    };
-
-    this.fillMetadata(aElement, message);
-    this.eventDispatcher.sendRequest(message);
-  }
-
-  observeMedia(aElement) {
-    if (this.isObserving(aElement)) {
-      return;
-    }
-    this.getState(aElement).observing = true;
-
-    for (const name of this._mediaEvents) {
-      aElement.addEventListener(name, this._mediaEventCallback, true);
-    }
-
-    // Notify current state
-    this.notifyTimeChange(aElement);
-    this.notifyVolumeChange(aElement);
-    this.notifyRateChange(aElement);
-    if (aElement.readyState >= 1) {
-      this.notifyMetadataChange(aElement);
-    }
-    this.notifyReadyStateChange(aElement);
-    if (!aElement.paused) {
-      this.notifyPlaybackStateChange(aElement, "play");
-    }
-    if (aElement === this._fullscreenMedia) {
-      this.notifyFullscreenChange(aElement, true);
-    }
-    if (this.hasError(aElement)) {
-      this.notifyMediaError(aElement);
-    }
-  }
-
-  unobserveMedia(aElement) {
-    if (!this.isObserving(aElement)) {
-      return;
-    }
-    this.getState(aElement).observing = false;
-    for (const name of this._mediaEvents) {
-      aElement.removeEventListener(name, this._mediaEventCallback);
-    }
-  }
-
-  isMedia(aElement) {
-    if (!aElement) {
-      return false;
-    }
-    const elementType = ChromeUtils.getClassName(aElement);
-    return (elementType === "HTMLVideoElement") || (elementType === "HTMLAudioElement");
-  }
-
-  isObserving(aElement) {
-    return aElement && this.getState(aElement) && this.getState(aElement).observing;
-  }
-
-  findElement(aId) {
-    for (const weakElement of this._videos.values()) {
-      const element = weakElement.get();
-      if (element && this.getState(element).id === aId) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  getState(aElement) {
-    return aElement[this._stateSymbol];
-  }
-
-  hasError(aElement) {
-    // We either have an explicit error, or networkState is set to NETWORK_NO_SOURCE
-    // after selecting a source.
-    return aElement.error != null ||
-           (aElement.networkState === aElement.NETWORK_NO_SOURCE &&
-            this.hasSources(aElement));
-  }
-
-  hasSources(aElement) {
-    if (aElement.hasAttribute("src") && aElement.getAttribute("src") !== "") {
-      return true;
-    }
-    for (var child = aElement.firstChild; child !== null; child = child.nextElementSibling) {
-      if (child instanceof content.window.HTMLSourceElement) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  fillMetadata(aElement, aOut) {
-    aOut.src = aElement.currentSrc || aElement.src;
-    aOut.width = aElement.videoWidth || 0;
-    aOut.height = aElement.videoHeight || 0;
-    aOut.duration = aElement.duration;
-    aOut.seekable = !!aElement.seekable;
-    if (aElement.audioTracks) {
-      aOut.audioTrackCount = aElement.audioTracks.length;
-    } else {
-      aOut.audioTrackCount = (aElement.mozHasAudio || aElement.webkitAudioDecodedByteCount ||
-        ChromeUtils.getClassName(aElement) === "HTMLAudioElement") ? 1 : 0;
-    }
-    if (aElement.videoTracks) {
-      aOut.videoTrackCount = aElement.videoTracks.length;
-    } else {
-      aOut.videoTrackCount = ChromeUtils.getClassName(aElement) === "HTMLVideoElement" ? 1 : 0;
-    }
-  }
-
-  handleMediaEvent(aEvent) {
-    const element = aEvent.target;
-    if (!this.isObserving(element)) {
-      return;
-    }
-    switch (aEvent.type) {
-      case "timeupdate":
-        this.notifyTimeChange(element);
-        break;
-      case "volumechange":
-        this.notifyVolumeChange(element);
-        break;
-      case "loadedmetadata":
-        this.notifyMetadataChange(element);
-        this.notifyReadyStateChange(element);
-        break;
-      case "ratechange":
-        this.notifyRateChange(element);
-        break;
-      case "error":
-        this.notifyMediaError(element);
-        break;
-      case "progress":
-        this.notifyLoadProgress(element, aEvent);
-        break;
-      case "durationchange": // Fallthrough
-      case "resize":
-        this.notifyMetadataChange(element);
-        break;
-      case "canplay": // Fallthrough
-      case "canplaythrough": // Fallthrough
-      case "loadeddata":
-        this.notifyReadyStateChange(element);
-        break;
-      default:
-        this.notifyPlaybackStateChange(element, aEvent.type);
-        break;
-    }
-  }
-
-  handleFullscreenChange(aElement) {
-    if (aElement === this._fullscreenMedia) {
-      return;
-    }
-
-    if (this.isObserving(this._fullscreenMedia)) {
-      this.notifyFullscreenChange(this._fullscreenMedia, false);
-    }
-    this._fullscreenMedia = aElement;
-
-    if (this.isObserving(aElement)) {
-      this.notifyFullscreenChange(aElement, true);
-    }
-  }
-
-  notifyPlaybackStateChange(aElement, aName) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaPlaybackStateChanged",
-      id: this.getState(aElement).id,
-      playbackState: aName,
-    });
-  }
-
-  notifyReadyStateChange(aElement) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaReadyStateChanged",
-      id: this.getState(aElement).id,
-      readyState: aElement.readyState,
-    });
-  }
-
-  notifyMetadataChange(aElement) {
-    const message = {
-      type: "GeckoView:MediaMetadataChanged",
-      id: this.getState(aElement).id,
-    };
-    this.fillMetadata(aElement, message);
-    this.eventDispatcher.sendRequest(message);
-  }
-
-  notifyLoadProgress(aElement, aEvent) {
-    const message = {
-      type: "GeckoView:MediaProgress",
-      id: this.getState(aElement).id,
-      loadedBytes: aEvent.lengthComputable ? aEvent.loaded : -1,
-      totalBytes: aEvent.lengthComputable ? aEvent.total : -1,
-    };
-    if (aElement.buffered && aElement.buffered.length > 0) {
-      message.timeRangeStarts = [];
-      message.timeRangeEnds = [];
-      for (let i = 0; i < aElement.buffered.length; ++i) {
-        message.timeRangeStarts.push(aElement.buffered.start(i));
-        message.timeRangeEnds.push(aElement.buffered.end(i));
-      }
-    }
-    this.eventDispatcher.sendRequest(message);
-  }
-
-  notifyTimeChange(aElement) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaTimeChanged",
-      id: this.getState(aElement).id,
-      time: aElement.currentTime,
-    });
-  }
-
-  notifyRateChange(aElement) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaRateChanged",
-      id: this.getState(aElement).id,
-      rate: aElement.playbackRate,
-    });
-  }
-
-  notifyVolumeChange(aElement) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaVolumeChanged",
-      id: this.getState(aElement).id,
-      volume: aElement.volume,
-      muted: !!aElement.muted,
-    });
-  }
-
-  notifyFullscreenChange(aElement, aIsFullscreen) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaFullscreenChanged",
-      id: this.getState(aElement).id,
-      fullscreen: aIsFullscreen,
-    });
-  }
-
-  notifyMediaError(aElement) {
-    let code = aElement.error ? aElement.error.code : 0;
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaError",
-      id: this.getState(aElement).id,
-      code: code,
-    });
-  }
-
-  notifyMediaRemove(aElement) {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaRemove",
-      id: this.getState(aElement).id,
-    });
-  }
-
-  notifyMediaRemoveAll() {
-    this.eventDispatcher.sendRequest({
-      type: "GeckoView:MediaRemoveAll",
-    });
-  }
-
-}
-
-const {debug, warn} = GeckoViewMediaChild.initLogging("GeckoViewMedia");
-const module = GeckoViewMediaChild.create(this);
--- a/mobile/android/chrome/geckoview/geckoview.js
+++ b/mobile/android/chrome/geckoview/geckoview.js
@@ -387,22 +387,16 @@ function startup() {
     },
   }, {
     name: "GeckoViewContent",
     onInit: {
       resource: "resource://gre/modules/GeckoViewContent.jsm",
       frameScript: "chrome://geckoview/content/GeckoViewContentChild.js",
     },
   }, {
-    name: "GeckoViewMedia",
-    onEnable: {
-      resource: "resource://gre/modules/GeckoViewMedia.jsm",
-      frameScript: "chrome://geckoview/content/GeckoViewMediaChild.js",
-    },
-  }, {
     name: "GeckoViewNavigation",
     onInit: {
       resource: "resource://gre/modules/GeckoViewNavigation.jsm",
       frameScript: "chrome://geckoview/content/GeckoViewNavigationChild.js",
     },
   }, {
     name: "GeckoViewProgress",
     onEnable: {
--- a/mobile/android/chrome/geckoview/jar.mn
+++ b/mobile/android/chrome/geckoview/jar.mn
@@ -8,15 +8,14 @@ geckoview.jar:
   content/config.xhtml
   content/config.js
 % override chrome://global/content/config.xul chrome://geckoview/content/config.xhtml
 
   content/ErrorPageEventHandler.js
   content/geckoview.xul
   content/geckoview.js
   content/GeckoViewContentChild.js
-  content/GeckoViewMediaChild.js
   content/GeckoViewNavigationChild.js
   content/GeckoViewProgressChild.js
   content/GeckoViewPromptChild.js
   content/GeckoViewScrollChild.js
   content/GeckoViewSettingsChild.js
   content/GeckoViewSelectionActionChild.js
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java
@@ -44,17 +44,16 @@ import android.os.SystemClock;
 import android.support.annotation.AnyThread;
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
 import android.support.annotation.NonNull;
 import android.support.annotation.StringDef;
 import android.support.annotation.UiThread;
 import android.util.Base64;
 import android.util.Log;
-import android.util.LongSparseArray;
 import android.view.Surface;
 import android.view.inputmethod.CursorAnchorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
 
 public class GeckoSession extends LayerSession
         implements Parcelable {
     private static final String LOGTAG = "GeckoSession";
@@ -515,95 +514,20 @@ public class GeckoSession extends LayerS
                         throw new IllegalArgumentException();
                     }
 
                     delegate.onHideAction(GeckoSession.this, reason);
                 }
             }
         };
 
-    private LongSparseArray<MediaElement> mMediaElements = new LongSparseArray<>();
-    /* package */ LongSparseArray<MediaElement> getMediaElements() {
-        return mMediaElements;
-    }
-    private final GeckoSessionHandler<MediaDelegate> mMediaHandler =
-            new GeckoSessionHandler<MediaDelegate>(
-                    "GeckoViewMedia", this,
-                    new String[]{
-                            "GeckoView:MediaAdd",
-                            "GeckoView:MediaRemove",
-                            "GeckoView:MediaRemoveAll",
-                            "GeckoView:MediaReadyStateChanged",
-                            "GeckoView:MediaTimeChanged",
-                            "GeckoView:MediaPlaybackStateChanged",
-                            "GeckoView:MediaMetadataChanged",
-                            "GeckoView:MediaProgress",
-                            "GeckoView:MediaVolumeChanged",
-                            "GeckoView:MediaRateChanged",
-                            "GeckoView:MediaFullscreenChanged",
-                            "GeckoView:MediaError",
-                    }
-            ) {
-                @Override
-                public void handleMessage(final MediaDelegate delegate,
-                                          final String event,
-                                          final GeckoBundle message,
-                                          final EventCallback callback) {
-                    if ("GeckoView:MediaAdd".equals(event)) {
-                        final MediaElement element = new MediaElement(message.getLong("id"), GeckoSession.this);
-                        delegate.onMediaAdd(GeckoSession.this, element);
-                        return;
-                    } else if ("GeckoView:MediaRemoveAll".equals(event)) {
-                        for (int i = 0; i < mMediaElements.size(); i++) {
-                            final long key = mMediaElements.keyAt(i);
-                            delegate.onMediaRemove(GeckoSession.this, mMediaElements.get(key));
-                        }
-                        mMediaElements.clear();
-                        return;
-                    }
-
-                    final long id = message.getLong("id", 0);
-                    final MediaElement element = mMediaElements.get(id);
-                    if (element == null) {
-                        Log.w(LOGTAG, "MediaElement not found for '" + id + "'");
-                        return;
-                    }
-
-                    if ("GeckoView:MediaTimeChanged".equals(event)) {
-                        element.notifyTimeChange(message.getDouble("time"));
-                    } else if ("GeckoView:MediaProgress".equals(event)) {
-                        element.notifyLoadProgress(message);
-                    } else if ("GeckoView:MediaMetadataChanged".equals(event)) {
-                        element.notifyMetadataChange(message);
-                    } else if ("GeckoView:MediaReadyStateChanged".equals(event)) {
-                        element.notifyReadyStateChange(message.getInt("readyState"));
-                    } else if ("GeckoView:MediaPlaybackStateChanged".equals(event)) {
-                        element.notifyPlaybackStateChange(message.getString("playbackState"));
-                    } else if ("GeckoView:MediaVolumeChanged".equals(event)) {
-                        element.notifyVolumeChange(message.getDouble("volume"), message.getBoolean("muted"));
-                    } else if ("GeckoView:MediaRateChanged".equals(event)) {
-                        element.notifyPlaybackRateChange(message.getDouble("rate"));
-                    } else if ("GeckoView:MediaFullscreenChanged".equals(event)) {
-                        element.notifyFullscreenChange(message.getBoolean("fullscreen"));
-                    } else if ("GeckoView:MediaRemove".equals(event)) {
-                        delegate.onMediaRemove(GeckoSession.this, element);
-                        mMediaElements.remove(element.getVideoId());
-                    } else if ("GeckoView:MediaError".equals(event)) {
-                        element.notifyError(message.getInt("code"));
-                    } else {
-                        throw new UnsupportedOperationException(event + " media message not implemented");
-                    }
-                }
-            };
-
-
     /* package */ int handlersCount;
 
     private final GeckoSessionHandler<?>[] mSessionHandlers = new GeckoSessionHandler<?>[] {
-        mContentHandler, mMediaHandler, mNavigationHandler, mProgressHandler, mScrollHandler,
+        mContentHandler, mNavigationHandler, mProgressHandler, mScrollHandler,
         mTrackingProtectionHandler, mPermissionHandler, mSelectionActionDelegate
     };
 
     private static class PermissionCallback implements
         PermissionDelegate.Callback, PermissionDelegate.MediaCallback {
 
         private final String mType;
         private EventCallback mCallback;
@@ -1667,34 +1591,16 @@ public class GeckoSession extends LayerS
             // track of the old delegate, so we can't rely on Gecko to do that for us.
             getSelectionActionDelegate().onHideAction(
                     this, GeckoSession.SelectionActionDelegate.HIDE_REASON_NO_SELECTION);
         }
         mSelectionActionDelegate.setDelegate(delegate, this);
     }
 
     /**
-     * Set the media callback handler.
-     * This will replace the current handler.
-     * @param delegate An implementation of MediaDelegate.
-     */
-    public void setMediaDelegate(final @Nullable MediaDelegate delegate) {
-        mMediaHandler.setDelegate(delegate, this);
-    }
-
-    /**
-     * Get the Media callback handler.
-     * @return The current Media callback handler.
-     */
-    public @Nullable MediaDelegate getMediaDelegate() {
-        return mMediaHandler.getDelegate();
-    }
-
-
-    /**
      * Get the current selection action delegate for this GeckoSession.
      *
      * @return SelectionActionDelegate instance or null if not set.
      */
     public @Nullable SelectionActionDelegate getSelectionActionDelegate() {
         return mSelectionActionDelegate.getDelegate();
     }
 
@@ -3593,27 +3499,9 @@ public class GeckoSession extends LayerS
          *                  applicable. The ID matches one of the virtual IDs provided by {@link
          *                  SessionTextInput#onProvideAutofillVirtualStructure} and can be used
          *                  with {@link SessionTextInput#autofill}.
          */
         @UiThread
         void notifyAutoFill(@NonNull GeckoSession session, @AutoFillNotification int notification,
                             int virtualId);
     }
-
-    /**
-     * GeckoSession applications implement this interface to handle media events.
-     */
-    public interface MediaDelegate {
-        /**
-         * An HTMLMediaElement has been created.
-         * @param session Session instance.
-         * @param element The media element that was just created.
-         */
-        void onMediaAdd(GeckoSession session, MediaElement element);
-        /**
-         * An HTMLMediaElement has been unloaded.
-         * @param session Session instance.
-         * @param element The media element that was unloaded.
-         */
-        void onMediaRemove(GeckoSession session, MediaElement element);
-    }
 }
deleted file mode 100644
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/MediaElement.java
+++ /dev/null
@@ -1,540 +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.IntDef;
-import android.support.annotation.Nullable;
-import android.util.Log;
-
-import org.mozilla.gecko.util.GeckoBundle;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * GeckoSession applications can use this class to handle media events
- * and control the HTMLMediaElement externally.
- **/
-public class MediaElement {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({MEDIA_STATE_PLAY, MEDIA_STATE_PLAYING, MEDIA_STATE_PAUSE,
-             MEDIA_STATE_ENDED, MEDIA_STATE_SEEKING, MEDIA_STATE_SEEKED,
-             MEDIA_STATE_STALLED, MEDIA_STATE_SUSPEND, MEDIA_STATE_WAITING,
-             MEDIA_STATE_ABORT, MEDIA_STATE_EMPTIED})
-    /* package */ @interface MediaStateFlags {}
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({MEDIA_READY_STATE_HAVE_NOTHING, MEDIA_READY_STATE_HAVE_METADATA,
-             MEDIA_READY_STATE_HAVE_CURRENT_DATA, MEDIA_READY_STATE_HAVE_FUTURE_DATA,
-             MEDIA_READY_STATE_HAVE_ENOUGH_DATA})
-
-    /* package */ @interface ReadyStateFlags {}
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({MEDIA_ERROR_NETWORK_NO_SOURCE, MEDIA_ERROR_ABORTED, MEDIA_ERROR_NETWORK,
-             MEDIA_ERROR_DECODE, MEDIA_ERROR_SRC_NOT_SUPPORTED})
-    /* package */ @interface MediaErrorFlags {}
-
-    /**
-     * The media is no longer paused, as a result of the play method, or the autoplay attribute.
-     */
-    public static final int MEDIA_STATE_PLAY = 0;
-    /**
-     * Sent when the media has enough data to start playing, after the play event,
-     * but also when recovering from being stalled, when looping media restarts,
-     * and after seeked, if it was playing before seeking.
-     */
-    public static final int MEDIA_STATE_PLAYING = 1;
-    /**
-     * Sent when the playback state is changed to paused.
-     */
-    public static final int MEDIA_STATE_PAUSE = 2;
-    /**
-     * Sent when playback completes.
-     */
-    public static final int MEDIA_STATE_ENDED = 3;
-    /**
-     * Sent when a seek operation begins.
-     */
-    public static final int MEDIA_STATE_SEEKING = 4;
-    /**
-     * Sent when a seek operation completes.
-     */
-    public static final int MEDIA_STATE_SEEKED = 5;
-    /**
-     * Sent when the user agent is trying to fetch media data,
-     * but data is unexpectedly not forthcoming.
-     */
-    public static final int MEDIA_STATE_STALLED = 6;
-    /**
-     * Sent when loading of the media is suspended. This may happen either because
-     * the download has completed or because it has been paused for any other reason.
-     */
-    public static final int MEDIA_STATE_SUSPEND = 7;
-    /**
-     * Sent when the requested operation (such as playback) is delayed
-     * pending the completion of another operation (such as a seek).
-     */
-    public static final int MEDIA_STATE_WAITING = 8;
-    /**
-     * Sent when playback is aborted; for example, if the media is playing
-     * and is restarted from the beginning, this event is sent.
-     */
-    public static final int MEDIA_STATE_ABORT = 9;
-    /**
-     * The media has become empty. For example, this event is sent if the media
-     * has already been loaded, and the load() method is called to reload it.
-     */
-    public static final int MEDIA_STATE_EMPTIED = 10;
-
-
-    /**
-     * No information is available about the media resource.
-     */
-    public static final int MEDIA_READY_STATE_HAVE_NOTHING = 0;
-    /**
-     * Enough of the media resource has been retrieved that the metadata
-     * attributes are available.
-     */
-    public static final int MEDIA_READY_STATE_HAVE_METADATA = 1;
-    /**
-     * Data is available for the current playback position,
-     * but not enough to actually play more than one frame.
-     */
-    public static final int MEDIA_READY_STATE_HAVE_CURRENT_DATA = 2;
-    /**
-     * Data for the current playback position as well as for at least a little
-     * bit of time into the future is available.
-     */
-    public static final int MEDIA_READY_STATE_HAVE_FUTURE_DATA = 3;
-    /**
-     * Enough data is available—and the download rate is high enough that the media
-     * can be played through to the end without interruption.
-     */
-    public static final int MEDIA_READY_STATE_HAVE_ENOUGH_DATA = 4;
-
-
-    /**
-     * Media source not found or unable to select any of the child elements
-     * for playback during resource selection.
-     */
-    public static final int MEDIA_ERROR_NETWORK_NO_SOURCE = 0;
-    /**
-     * The fetching of the associated resource was aborted by the user's request.
-     */
-    public static final int MEDIA_ERROR_ABORTED = 1;
-    /**
-     * Some kind of network error occurred which prevented the media from being
-     * successfully fetched, despite having previously been available.
-     */
-    public static final int MEDIA_ERROR_NETWORK = 2;
-    /**
-     * Despite having previously been determined to be usable,
-     * an error occurred while trying to decode the media resource, resulting in an error.
-     */
-    public static final int MEDIA_ERROR_DECODE = 3;
-    /**
-     * The associated resource or media provider object has been found to be unsuitable.
-     */
-    public static final int MEDIA_ERROR_SRC_NOT_SUPPORTED = 4;
-
-    /**
-     * Data class with the Metadata associated to a Media Element.
-     **/
-    public static class Metadata {
-        /**
-         * Contains the current media source URI.
-         */
-        public final String currentSource;
-
-        /**
-         * Indicates the duration of the media in seconds.
-         */
-        public final double duration;
-
-        /**
-         * Indicates the width of the video in device pixels.
-         */
-        public final long width;
-
-        /**
-         * Indicates the height of the video in device pixels.
-         */
-        public final long height;
-
-        /**
-         * Indicates if seek operations are compatible with the media.
-         */
-        public final boolean isSeekable;
-
-        /**
-         * Indicates the number of audio tracks included in the media.
-         */
-        public final int audioTrackCount;
-
-        /**
-         * Indicates the number of video tracks included in the media.
-         */
-        public final int videoTrackCount;
-
-        /* package */ Metadata(final GeckoBundle bundle) {
-            currentSource = bundle.getString("src", "");
-            duration = bundle.getDouble("duration", 0);
-            width = bundle.getLong("width", 0);
-            height = bundle.getLong("height", 0);
-            isSeekable = bundle.getBoolean("seekable", false);
-            audioTrackCount = bundle.getInt("audioTrackCount", 0);
-            videoTrackCount = bundle.getInt("videoTrackCount", 0);
-        }
-    }
-
-    /**
-     * Data class that indicates infomation about a media load progress event.
-     **/
-    public static class LoadProgressInfo {
-        /*
-         * Class used to represent a set of time ranges.
-         */
-        public class TimeRange {
-            /* package */ TimeRange(double start, double end) {
-                this.start = start;
-                this.end = end;
-            }
-            /*
-             * The start time of the range in seconds.
-             */
-            public final double start;
-            /*
-             * The end time of the range in seconds.
-             */
-            public final double end;
-        }
-
-        /**
-         * The number of bytes transferred since the beginning of the operation
-         * or -1 if the data is not computable.
-         */
-        public final long loadedBytes;
-
-        /**
-         * The total number of bytes of content that will be transferred during the operation
-         * or -1 if the data is not computable.
-         */
-        public final long totalBytes;
-
-        /**
-         * The ranges of the media source that the browser has currently buffered.
-         * Null if the browser has not buffered any time range or the data is not computable.
-         */
-        public final @Nullable TimeRange[] buffered;
-
-        /* package */ LoadProgressInfo(final GeckoBundle bundle) {
-            loadedBytes = bundle.getLong("loadedBytes", -1);
-            totalBytes = bundle.getLong("loadedBytes", -1);
-            double[] starts = bundle.getDoubleArray("timeRangeStarts");
-            double[] ends = bundle.getDoubleArray("timeRangeEnds");
-            if (starts == null || ends == null) {
-                buffered = null;
-                return;
-            }
-
-            if (starts.length != ends.length) {
-                throw new AssertionError("timeRangeStarts and timeRangeEnds length do not match");
-            }
-
-            buffered = new TimeRange[starts.length];
-            for (int i = 0; i < starts.length; ++i) {
-                buffered[i] = new TimeRange(starts[i], ends[i]);
-            }
-        }
-    }
-
-    /**
-     * This interface allows apps to handle media events.
-     **/
-    public interface Delegate {
-        /**
-         * The media playback state has changed.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param mediaState The playback state of the media.
-         *                   One of the {@link #MEDIA_STATE_PLAY MEDIA_STATE_*} flags.
-         */
-        default void onPlaybackStateChange(MediaElement mediaElement, @MediaStateFlags int mediaState) {}
-
-        /**
-         * The readiness state of the media has changed.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param readyState The readiness state of the media.
-         *                   One of the {@link #MEDIA_READY_STATE_HAVE_NOTHING MEDIA_READY_STATE_*} flags.
-         */
-        default void onReadyStateChange(MediaElement mediaElement, @ReadyStateFlags int readyState) {}
-
-        /**
-         * The media metadata has loaded or changed.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param metaData The MetaData values of the media.
-         */
-        default void onMetadataChange(MediaElement mediaElement, Metadata metaData) {}
-
-        /**
-         * Indicates that a loading operation is in progress for the media.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param progressInfo Information about the load progress and buffered ranges.
-         */
-        default void onLoadProgress(MediaElement mediaElement, LoadProgressInfo progressInfo) {}
-
-        /**
-         * The media audio volume has changed.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param volume The volume of the media.
-         * @param muted True if the media is muted.
-         */
-        default void onVolumeChange(MediaElement mediaElement, double volume, boolean muted) {}
-
-        /**
-         * The current playback time has changed. This event is usually dispatched every 250ms.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param time The current playback time in seconds.
-         */
-        default void onTimeChange(MediaElement mediaElement, double time) {}
-
-        /**
-         * The media playback speed has changed.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param rate The current playback rate. A value of 1.0 indicates normal speed.
-         */
-        default void onPlaybackRateChange(MediaElement mediaElement, double rate) {}
-
-        /**
-         * A media element has entered or exited fullscreen mode.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param fullscreen True if the media has entered full screen mode.
-         */
-        default void onFullscreenChange(MediaElement mediaElement, boolean fullscreen) {}
-
-        /**
-         * An error has occurred.
-         *
-         * @param mediaElement A reference to the MediaElement that dispatched the event.
-         * @param errorCode The error code.
-         *                  One of the {@link #MEDIA_ERROR_NETWORK_NO_SOURCE MEDIA_ERROR_*} flags.
-         */
-        default void onError(MediaElement mediaElement, @MediaErrorFlags int errorCode) {}
-    }
-
-    /* package */ long getVideoId() {
-        return mVideoId;
-    }
-
-    /**
-     * Gets the current the media callback handler.
-     *
-     * @return the current media callback handler.
-     */
-    public @Nullable MediaElement.Delegate getDelegate() {
-        return mDelegate;
-    }
-
-    /**
-     * Sets the media callback handler.
-     * This will replace the current handler.
-     *
-     * @param delegate An implementation of MediaDelegate.
-     */
-    public void setDelegate(final @Nullable MediaElement.Delegate delegate) {
-        if (mDelegate == delegate) {
-            return;
-        }
-        MediaElement.Delegate oldDelegate = mDelegate;
-        mDelegate = delegate;
-        if (oldDelegate != null && mDelegate == null) {
-            mSession.getEventDispatcher().dispatch("GeckoView:MediaUnobserve", createMessage());
-            mSession.getMediaElements().remove(mVideoId);
-        } else if (oldDelegate == null) {
-            mSession.getMediaElements().put(mVideoId, this);
-            mSession.getEventDispatcher().dispatch("GeckoView:MediaObserve", createMessage());
-        }
-    }
-
-    /**
-     * Pauses the media.
-     */
-    public void pause() {
-        mSession.getEventDispatcher().dispatch("GeckoView:MediaPause", createMessage());
-    }
-
-    /**
-     * Plays the media.
-     */
-    public void play() {
-        mSession.getEventDispatcher().dispatch("GeckoView:MediaPlay", createMessage());
-    }
-
-    /**
-     * Seek the media to a given time.
-     *
-     * @param time Seek time in seconds.
-     */
-    public void seek(final double time) {
-        final GeckoBundle message = createMessage();
-        message.putDouble("time", time);
-        mSession.getEventDispatcher().dispatch("GeckoView:MediaSeek", message);
-    }
-
-    /**
-     * Set the volume at which the media will be played.
-     *
-     * @param volume A Volume value. It must fall between 0 and 1, where 0 is effectively muted
-     *               and 1 is the loudest possible value.
-     */
-    public void setVolume(final double volume) {
-        final GeckoBundle message = createMessage();
-        message.putDouble("volume", volume);
-        mSession.getEventDispatcher().dispatch("GeckoView:MediaSetVolume", message);
-    }
-
-    /**
-     * Mutes the media.
-     *
-     * @param muted True in order to mute the audio.
-     */
-    public void setMuted(final boolean muted) {
-        final GeckoBundle message = createMessage();
-        message.putBoolean("muted", muted);
-        mSession.getEventDispatcher().dispatch("GeckoView:MediaSetMuted", message);
-    }
-
-    /**
-     * Sets the playback rate at which the media will be played.
-     *
-     * @param playbackRate The rate at which the media will be played.
-     *                     A value of 1.0 indicates normal speed.
-     */
-    public void setPlaybackRate(final double playbackRate) {
-        final GeckoBundle message = createMessage();
-        message.putDouble("playbackRate", playbackRate);
-        mSession.getEventDispatcher().dispatch("GeckoView:MediaSetPlaybackRate", message);
-    }
-
-    // Helper methods used for event observers to update the current video state
-
-    /* package */ void notifyPlaybackStateChange(final String event) {
-        @MediaStateFlags int state;
-        switch (event.toLowerCase()) {
-            case "play":
-                state = MEDIA_STATE_PLAY;
-                break;
-            case "playing":
-                state = MEDIA_STATE_PLAYING;
-                break;
-            case "pause":
-                state = MEDIA_STATE_PAUSE;
-                break;
-            case "ended":
-                state = MEDIA_STATE_ENDED;
-                break;
-            case "seeking":
-                state = MEDIA_STATE_SEEKING;
-                break;
-            case "seeked":
-                state = MEDIA_STATE_SEEKED;
-                break;
-            case "stalled":
-                state = MEDIA_STATE_STALLED;
-                break;
-            case "suspend":
-                state = MEDIA_STATE_SUSPEND;
-                break;
-            case "waiting":
-                state = MEDIA_STATE_WAITING;
-                break;
-            case "abort":
-                state = MEDIA_STATE_ABORT;
-                break;
-            case "emptied":
-                state = MEDIA_STATE_EMPTIED;
-                break;
-            default:
-                throw new UnsupportedOperationException(event + " HTMLMediaElement event not implemented");
-        }
-
-        if (mDelegate != null) {
-            mDelegate.onPlaybackStateChange(this, state);
-        }
-    }
-
-    /* package */ void notifyReadyStateChange(final int readyState) {
-        if (mDelegate != null) {
-            mDelegate.onReadyStateChange(this, readyState);
-        }
-    }
-
-    /* package */ void notifyLoadProgress(final GeckoBundle message) {
-        if (mDelegate != null) {
-            mDelegate.onLoadProgress(this, new LoadProgressInfo(message));
-        }
-    }
-
-    /* package */ void notifyTimeChange(final double currentTime) {
-        if (mDelegate != null) {
-            mDelegate.onTimeChange(this, currentTime);
-        }
-    }
-
-    /* package */ void notifyVolumeChange(final double volume, final boolean muted) {
-        if (mDelegate != null) {
-            mDelegate.onVolumeChange(this, volume, muted);
-        }
-    }
-
-    /* package */ void notifyPlaybackRateChange(final double rate) {
-        if (mDelegate != null) {
-            mDelegate.onPlaybackRateChange(this, rate);
-        }
-    }
-
-    /* package */ void notifyMetadataChange(final GeckoBundle message) {
-        if (mDelegate != null) {
-            mDelegate.onMetadataChange(this, new Metadata(message));
-        }
-    }
-
-    /* package */ void notifyFullscreenChange(final boolean fullscreen) {
-        if (mDelegate != null) {
-            mDelegate.onFullscreenChange(this, fullscreen);
-        }
-    }
-
-    /* package */ void notifyError(final int aCode) {
-        if (mDelegate != null) {
-            mDelegate.onError(this, aCode);
-        }
-    }
-
-    private GeckoBundle createMessage() {
-        final GeckoBundle bundle = new GeckoBundle();
-        bundle.putLong("id", mVideoId);
-        return bundle;
-    }
-
-    /* package */ MediaElement(final long videoId, final GeckoSession session) {
-        mVideoId = videoId;
-        mSession = session;
-    }
-
-    final protected GeckoSession mSession;
-    final protected long mVideoId;
-    protected MediaElement.Delegate mDelegate;
-}
deleted file mode 100644
--- a/mobile/android/modules/geckoview/GeckoViewMedia.jsm
+++ /dev/null
@@ -1,33 +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 = ["GeckoViewMedia"];
-
-ChromeUtils.import("resource://gre/modules/GeckoViewModule.jsm");
-
-class GeckoViewMedia extends GeckoViewModule {
-  onEnable() {
-    this.registerListener([
-      "GeckoView:MediaObserve",
-      "GeckoView:MediaUnobserve",
-      "GeckoView:MediaPlay",
-      "GeckoView:MediaPause",
-      "GeckoView:MediaSeek",
-      "GeckoView:MediaSetVolume",
-      "GeckoView:MediaSetMuted",
-      "GeckoView:MediaSetPlaybackRate",
-    ]);
-  }
-
-  onDisable() {
-    this.unregisterListener();
-  }
-
-  onEvent(aEvent, aData, aCallback) {
-    debug `onEvent: event=${aEvent}, data=${aData}`;
-    this.messageManager.sendAsyncMessage(aEvent, aData);
-  }
-}
--- a/mobile/android/modules/geckoview/moz.build
+++ b/mobile/android/modules/geckoview/moz.build
@@ -7,17 +7,16 @@
 EXTRA_JS_MODULES += [
     'AndroidLog.jsm',
     'ContentCrashHandler.jsm',
     'GeckoViewAccessibility.jsm',
     'GeckoViewAutoFill.jsm',
     'GeckoViewChildModule.jsm',
     'GeckoViewConsole.jsm',
     'GeckoViewContent.jsm',
-    'GeckoViewMedia.jsm',
     'GeckoViewModule.jsm',
     'GeckoViewNavigation.jsm',
     'GeckoViewProgress.jsm',
     'GeckoViewRemoteDebugger.jsm',
     'GeckoViewSettings.jsm',
     'GeckoViewTab.jsm',
     'GeckoViewTrackingProtection.jsm',
     'GeckoViewUtils.jsm',