Merge m-c to fx-team, a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 18 Aug 2016 16:33:20 -0700
changeset 310229 abac53d4d2476c4ab1816844091989456b8993bf
parent 310182 7bf7d0d47b791df8e9bebe4f29bf9f2ab8f53b3e (current diff)
parent 309986 cf06fbc831754e54c6abb71d3136597488a530e0 (diff)
child 310251 6c02985bc0c8ddc8d1a9df7dca1c6bb894aa664b
push id31532
push userryanvm@gmail.com
push dateFri, 19 Aug 2016 13:59:01 +0000
treeherderautoland@4f1e241f75a2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team, a=merge
browser/components/preferences/in-content/advanced.js
browser/themes/linux/browser.css
browser/themes/windows/browser.css
netwerk/protocol/rtsp/RtspChannelChild.cpp
netwerk/protocol/rtsp/RtspChannelChild.h
netwerk/protocol/rtsp/RtspChannelParent.cpp
netwerk/protocol/rtsp/RtspChannelParent.h
netwerk/protocol/rtsp/RtspHandler.cpp
netwerk/protocol/rtsp/RtspHandler.h
netwerk/protocol/rtsp/controller/RtspController.cpp
netwerk/protocol/rtsp/controller/RtspController.h
netwerk/protocol/rtsp/controller/RtspControllerChild.cpp
netwerk/protocol/rtsp/controller/RtspControllerChild.h
netwerk/protocol/rtsp/controller/RtspControllerParent.cpp
netwerk/protocol/rtsp/controller/RtspControllerParent.h
netwerk/protocol/rtsp/controller/RtspMetaData.cpp
netwerk/protocol/rtsp/controller/RtspMetaData.h
netwerk/protocol/rtsp/moz.build
netwerk/protocol/rtsp/rtsp/AAMRAssembler.cpp
netwerk/protocol/rtsp/rtsp/AAMRAssembler.h
netwerk/protocol/rtsp/rtsp/AAVCAssembler.cpp
netwerk/protocol/rtsp/rtsp/AAVCAssembler.h
netwerk/protocol/rtsp/rtsp/AH263Assembler.cpp
netwerk/protocol/rtsp/rtsp/AH263Assembler.h
netwerk/protocol/rtsp/rtsp/AMPEG4AudioAssembler.cpp
netwerk/protocol/rtsp/rtsp/AMPEG4AudioAssembler.h
netwerk/protocol/rtsp/rtsp/AMPEG4ElementaryAssembler.cpp
netwerk/protocol/rtsp/rtsp/AMPEG4ElementaryAssembler.h
netwerk/protocol/rtsp/rtsp/APacketSource.cpp
netwerk/protocol/rtsp/rtsp/APacketSource.h
netwerk/protocol/rtsp/rtsp/ARTPAssembler.cpp
netwerk/protocol/rtsp/rtsp/ARTPAssembler.h
netwerk/protocol/rtsp/rtsp/ARTPConnection.cpp
netwerk/protocol/rtsp/rtsp/ARTPConnection.h
netwerk/protocol/rtsp/rtsp/ARTPSession.cpp
netwerk/protocol/rtsp/rtsp/ARTPSession.h
netwerk/protocol/rtsp/rtsp/ARTPSource.cpp
netwerk/protocol/rtsp/rtsp/ARTPSource.h
netwerk/protocol/rtsp/rtsp/ARTPWriter.cpp
netwerk/protocol/rtsp/rtsp/ARTPWriter.h
netwerk/protocol/rtsp/rtsp/ARTSPConnection.cpp
netwerk/protocol/rtsp/rtsp/ARTSPConnection.h
netwerk/protocol/rtsp/rtsp/ARawAudioAssembler.cpp
netwerk/protocol/rtsp/rtsp/ARawAudioAssembler.h
netwerk/protocol/rtsp/rtsp/ASessionDescription.cpp
netwerk/protocol/rtsp/rtsp/ASessionDescription.h
netwerk/protocol/rtsp/rtsp/RTSPConnectionHandler.h
netwerk/protocol/rtsp/rtsp/RTSPSource.cpp
netwerk/protocol/rtsp/rtsp/RTSPSource.h
netwerk/protocol/rtsp/rtsp/RTSPTransmitter.h
netwerk/protocol/rtsp/rtsp/RtspPrlog.h
netwerk/protocol/rtsp/rtsp/UDPPusher.cpp
netwerk/protocol/rtsp/rtsp/UDPPusher.h
netwerk/protocol/rtsp/rtsp/VideoSource.h
netwerk/protocol/rtsp/rtsp/rtp_test.cpp
--- a/b2g/config/aries/sources.xml
+++ b/b2g/config/aries/sources.xml
@@ -1,26 +1,15 @@
 <?xml version="1.0" ?><manifest>
   <!--
     Remotes
     -->
-  <!--original fetch url was https://android.googlesource.com/-->
-  <remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
-  <!--original fetch url was git://github.com/apitrace/-->
-  <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
+  <remote fetch="git://github.com/apitrace/" name="apitrace"/>
   <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
-  <!--original fetch url was https://git.mozilla.org/b2g-->
-  <remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
-  <!--original fetch url was git://codeaurora.org/-->
-  <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
-  <!--original fetch url was http://android.git.linaro.org/git-ro/-->
-  <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
-  <remote fetch="git://github.com/mozilla/" name="mozilla"/>
-  <!--original fetch url was https://git.mozilla.org/releases-->
-  <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
+  <remote fetch="git://codeaurora.org/" name="caf"/>
   <!--
     B2G repositories for all targets
     -->
   <project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "a954bd2954c422b7d24d92cfd73000cb455dce44", 
-        "remote": "https://git.mozilla.org/releases/gaia.git", 
+        "git_revision": "90240f7a2e66ae8873e1f1b0e5f1d80a98c2c2db",
+        "remote": "https://github.com/mozilla-b2g/gaia.git",
         "branch": ""
-    }, 
-    "revision": "e9e8c44b43178139fca915cfe97ae3c52a9afe34", 
+    },
+    "revision": "e9e8c44b43178139fca915cfe97ae3c52a9afe34",
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -1,26 +1,15 @@
 <?xml version="1.0" ?><manifest>
   <!--
     Remotes
     -->
-  <!--original fetch url was https://android.googlesource.com/-->
-  <remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
-  <!--original fetch url was git://github.com/apitrace/-->
-  <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
+  <remote fetch="git://github.com/apitrace/" name="apitrace"/>
   <remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
-  <!--original fetch url was https://git.mozilla.org/b2g-->
-  <remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
-  <!--original fetch url was git://codeaurora.org/-->
-  <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
-  <!--original fetch url was http://android.git.linaro.org/git-ro/-->
-  <remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
-  <remote fetch="git://github.com/mozilla/" name="mozilla"/>
-  <!--original fetch url was https://git.mozilla.org/releases-->
-  <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
+  <remote fetch="git://codeaurora.org/" name="caf"/>
   <!--
     B2G repositories for all targets
     -->
   <project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="99003a6e7ecee880330a3fb8b5e49fefdb762374"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
   <project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
   <project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -210,16 +210,19 @@ skip-if = buildapp == 'mulet' # Bug 1066
 [browser_bug555767.js]
 [browser_bug559991.js]
 [browser_bug561636.js]
 skip-if = true # bug 1057615
 [browser_bug563588.js]
 [browser_bug565575.js]
 [browser_bug567306.js]
 subsuite = clipboard
+[browser_bug1261299.js]
+subsuite = clipboard
+skip-if = toolkit != "cocoa" # Because of tests for supporting Service Menu of macOS, bug 1261299
 [browser_bug575561.js]
 [browser_bug575830.js]
 [browser_bug577121.js]
 [browser_bug578534.js]
 [browser_bug579872.js]
 [browser_bug580638.js]
 [browser_bug580956.js]
 [browser_bug581242.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_bug1261299.js
@@ -0,0 +1,73 @@
+/* -*- 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/. */
+
+/**
+ * Tests for Bug 1261299
+ * Test that the service menu code path is called properly and the
+ * current selection (transferable) is cached properly on the parent process.
+ */
+
+add_task(function* test_content_and_chrome_selection()
+{
+  let testPage =
+    'data:text/html,' +
+    '<textarea id="textarea">Write something here</textarea>';
+  let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
+  let selectedText;
+
+  let tab = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage);
+  yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, gBrowser.selectedBrowser);
+  yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
+      {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
+  selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
+  is(selectedText, "Write something here", "The macOS services got the selected content text");
+
+  gURLBar.value = "test.mozilla.org";
+  yield gURLBar.focus();
+  yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
+      {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
+  selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
+  is(selectedText, "test.mozilla.org", "The macOS services got the selected chrome text");
+
+  yield BrowserTestUtils.removeTab(tab);
+});
+
+// Test switching active selection.
+// Each tab has a content selection and when you switch to that tab, its selection becomes
+// active aka the current selection.
+// Expect: The active selection is what is being sent to OSX service menu.
+
+add_task(function* test_active_selection_switches_properly()
+{
+  let testPage1 =
+    'data:text/html,' +
+    '<textarea id="textarea">Write something here</textarea>';
+  let testPage2 =
+    'data:text/html,' +
+    '<textarea id="textarea">Nothing available</textarea>';
+  let DOMWindowUtils = EventUtils._getDOMWindowUtils(window);
+  let selectedText;
+
+  let tab1 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage1);
+  yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, gBrowser.selectedBrowser);
+  yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
+      {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
+
+  let tab2 = yield BrowserTestUtils.openNewForegroundTab(gBrowser, testPage2);
+  yield BrowserTestUtils.synthesizeMouse("#textarea", 0, 0, {}, gBrowser.selectedBrowser);
+  yield BrowserTestUtils.synthesizeKey("KEY_ArrowRight",
+      {shiftKey: true, ctrlKey: true, code: "ArrowRight"}, gBrowser.selectedBrowser);
+
+  yield BrowserTestUtils.switchTab(gBrowser, tab1);
+  selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
+  is(selectedText, "Write something here", "The macOS services got the selected content text");
+
+  yield BrowserTestUtils.switchTab(gBrowser, tab2);
+  selectedText = DOMWindowUtils.GetSelectionAsPlaintext();
+  is(selectedText, "Nothing available", "The macOS services got the selected content text");
+
+  yield BrowserTestUtils.removeTab(tab1);
+  yield BrowserTestUtils.removeTab(tab2);
+});
\ No newline at end of file
--- a/browser/components/extensions/ext-history.js
+++ b/browser/components/extensions/ext-history.js
@@ -110,17 +110,17 @@ function getObserver() {
           typedCount: typed,
         };
         this.emit("visited", data);
       },
       onBeginUpdateBatch: function() {},
       onEndUpdateBatch: function() {},
       onTitleChanged: function() {},
       onClearHistory: function() {
-        this.emit("visitRemoved", {allHistory: true});
+        this.emit("visitRemoved", {allHistory: true, urls: []});
       },
       onPageChanged: function() {},
       onFrecencyChanged: function() {},
       onManyFrecenciesChanged: function() {},
       onDeleteVisits: function(uri, time, guid, reason) {
         this.emit("visitRemoved", {allHistory: false, urls: [uri.spec]});
       },
     };
--- a/browser/components/extensions/schemas/history.json
+++ b/browser/components/extensions/schemas/history.json
@@ -311,17 +311,16 @@
             "type": "object",
             "properties": {
               "allHistory": {
                 "type": "boolean",
                 "description": "True if all history was removed.  If true, then urls will be empty."
               },
               "urls": {
                 "type": "array",
-                "optional": true,
                 "items": {
                   "type": "string"
                 }
               }
             }
           }
         ]
       }
--- a/browser/components/extensions/schemas/tabs.json
+++ b/browser/components/extensions/schemas/tabs.json
@@ -250,16 +250,17 @@
             ]
           }
         ]
       },
       {
         "name": "sendMessage",
         "type": "function",
         "description": "Sends a single message to the content script(s) in the specified tab, with an optional callback to run when a response is sent back.  The $(ref:runtime.onMessage) event is fired in each content script running in the specified tab for the current extension.",
+        "async": "sendResponse",
         "parameters": [
           {
             "type": "integer",
             "name": "tabId",
             "minimum": 0
           },
           {
             "type": "any",
--- a/browser/components/extensions/test/xpcshell/test_ext_history.js
+++ b/browser/components/extensions/test/xpcshell/test_ext_history.js
@@ -12,16 +12,17 @@ XPCOMUtils.defineLazyModuleGetter(this, 
 add_task(function* test_delete() {
   function background() {
     let historyClearedCount = 0;
     let removedUrls = [];
 
     browser.history.onVisitRemoved.addListener(data => {
       if (data.allHistory) {
         historyClearedCount++;
+        browser.test.assertEq(0, data.urls.length, "onVisitRemoved received an empty urls array");
       } else {
         browser.test.assertEq(1, data.urls.length, "onVisitRemoved received one URL");
         removedUrls.push(data.urls[0]);
       }
     });
 
     browser.test.onMessage.addListener((msg, arg) => {
       if (msg === "delete-url") {
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -737,21 +737,17 @@ var gAdvancedPane = {
     }
   },
 
   /**
    * Displays the history of installed updates.
    */
   showUpdates: function ()
   {
-    if (AppConstants.MOZ_UPDATER) {
-      var prompter = Components.classes["@mozilla.org/updates/update-prompt;1"]
-                               .createInstance(Components.interfaces.nsIUpdatePrompt);
-      prompter.showUpdateHistory(window);
-    }
+    gSubDialog.open("chrome://mozapps/content/update/history.xul");
   },
 
   // ENCRYPTION TAB
 
   /*
    * Preferences:
    *
    * security.default_personal_cert
--- a/browser/components/preferences/in-content/tests/browser_advanced_update.js
+++ b/browser/components/preferences/in-content/tests/browser_advanced_update.js
@@ -1,40 +1,163 @@
 /* Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 "use strict";
 
-function test() {
-  waitForExplicitFinish();
-  resetPreferences();
+const { classes: Cc, interfaces: Ci, manager: Cm, utils: Cu, results: Cr } = Components;
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+const uuidGenerator = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
+const dateFormat = Cc["@mozilla.org/intl/scriptabledateformat;1"]
+                      .getService(Components.interfaces.nsIScriptableDateFormat);
+
+const mockUpdateManager = {
+  contractId: "@mozilla.org/updates/update-manager;1",
+
+  _mockClassId: uuidGenerator.generateUUID(),
+
+  _originalClassId: "",
+
+  _originalFactory: null,
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIUpdateManager]),
+
+  createInstance: function(outer, iiD) {
+    if (outer) {
+      throw Cr.NS_ERROR_NO_AGGREGATION;
+    }
+    return this.QueryInterface(iiD);
+  },
+
+  register: function () {
+    let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    if (!registrar.isCIDRegistered(this._mockClassId)) {
+      this._originalClassId = registrar.contractIDToCID(this.contractId);
+      this._originalFactory = Cm.getClassObject(Cc[this.contractId], Ci.nsIFactory);
+      registrar.unregisterFactory(this._originalClassId, this._originalFactory);
+      registrar.registerFactory(this._mockClassId, "Unregister after testing", this.contractId, this);
+    }
+  },
 
-  registerCleanupFunction(resetPreferences);
-  Services.prefs.setBoolPref("browser.search.update", false);
+  unregister: function () {
+    let registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
+    registrar.unregisterFactory(this._mockClassId, this);
+    registrar.registerFactory(this._originalClassId, "", this.contractId, this._originalFactory);
+  },
+
+  get updateCount() {
+    return this._updates.length;
+  },
+
+  getUpdateAt: function (index) {
+    return this._updates[index];
+  },
 
-  open_preferences(runTest);
+  _updates: [
+    {
+      name: "Firefox Developer Edition 49.0a2",
+      statusText: "The Update was successfully installed",
+      buildID: "20160728004010",
+      type: "minor",
+      installDate: 1469763105156,
+      detailsURL: "https://www.mozilla.org/firefox/aurora/"
+    },
+    {
+      name: "Firefox Developer Edition 43.0a2",
+      statusText: "The Update was successfully installed",
+      buildID: "20150929004011",
+      type: "minor",
+      installDate: 1443585886224,
+      detailsURL: "https://www.mozilla.org/firefox/aurora/"
+    },
+    {
+      name: "Firefox Developer Edition 42.0a2",
+      statusText: "The Update was successfully installed",
+      buildID: "20150920004018",
+      type: "major",
+      installDate: 1442818147544,
+      detailsURL: "https://www.mozilla.org/firefox/aurora/"
+    }
+  ]
+};
+
+function resetPreferences() {
+  Services.prefs.clearUserPref("browser.search.update");
 }
 
-function runTest(win) {
-  let doc = win.document;
-  let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
+function formatInstallDate(sec) {
+  var date = new Date(sec);
+  return dateFormat.FormatDateTime("",
+    dateFormat.dateFormatLong,
+    dateFormat.timeFormatSeconds,
+    date.getFullYear(),
+    date.getMonth() + 1,
+    date.getDate(),
+    date.getHours(),
+    date.getMinutes(),
+    date.getSeconds());
+}
 
-  win.gotoPref("paneAdvanced");
+registerCleanupFunction(resetPreferences);
 
-  let advancedPrefs = doc.getElementById("advancedPrefs");
-  let updateTab = doc.getElementById("updateTab");
-  advancedPrefs.selectedTab = updateTab;
+add_task(function*() {
+  yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
+  resetPreferences();
+  Services.prefs.setBoolPref("browser.search.update", false);
 
+  let doc = gBrowser.selectedBrowser.contentDocument;
+  let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
   is_element_visible(enableSearchUpdate, "Check search update preference is visible");
 
   // Ensure that the update pref dialog reflects the actual pref value.
   ok(!enableSearchUpdate.checked, "Ensure search updates are disabled");
   Services.prefs.setBoolPref("browser.search.update", true);
   ok(enableSearchUpdate.checked, "Ensure search updates are enabled");
 
   gBrowser.removeCurrentTab();
-  win.close();
-  finish();
-}
+});
+
+add_task(function*() {
+  mockUpdateManager.register();
+
+  yield openPreferencesViaOpenPreferencesAPI("advanced", "updateTab", { leaveOpen: true });
+  let doc = gBrowser.selectedBrowser.contentDocument;
+
+  let showBtn = doc.getElementById("showUpdateHistory");
+  let dialogOverlay = doc.getElementById("dialogOverlay");
+
+  // Test the dialog window opens
+  is(dialogOverlay.style.visibility, "", "The dialog should be invisible");
+  showBtn.doCommand();
+  yield promiseLoadSubDialog("chrome://mozapps/content/update/history.xul");
+  is(dialogOverlay.style.visibility, "visible", "The dialog should be visible");
+
+  let dialogFrame = doc.getElementById("dialogFrame");
+  let frameDoc = dialogFrame.contentDocument;
+  let updates = frameDoc.querySelectorAll("update");
 
-function resetPreferences() {
-  Services.prefs.clearUserPref("browser.search.update");
-}
+  // Test the update history numbers are correct
+  is(updates.length, mockUpdateManager.updateCount, "The update count is incorrect.");
+
+  // Test the updates are displayed correctly
+  let update = null;
+  let updateData = null;
+  for (let i = 0; i < updates.length; ++i) {
+    update = updates[i];
+    updateData = mockUpdateManager.getUpdateAt(i);
+
+    is(update.name, updateData.name + " (" + updateData.buildID + ")", "Wrong update name");
+    is(update.type, updateData.type == "major" ? "New Version" : "Security Update", "Wrong update type");
+    is(update.installDate, formatInstallDate(updateData.installDate), "Wrong update installDate");
+    is(update.detailsURL, updateData.detailsURL, "Wrong update detailsURL");
+    is(update.status, updateData.statusText, "Wrong update status");
+  }
+
+  // Test the dialog window closes
+  let closeBtn = doc.getElementById("dialogClose");
+  closeBtn.doCommand();
+  is(dialogOverlay.style.visibility, "", "The dialog should be invisible");
+
+  mockUpdateManager.unregister();
+  gBrowser.removeCurrentTab();
+});
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -948,20 +948,23 @@ toolbaritem[cui-areatype="menu-panel"] >
   /* 16x16 icon with border-box sizing */
   width: 22px;
   height: 16px;
 }
 
 /* ::::: URL Bar Zoom Reset Button ::::: */
 @keyframes urlbar-zoom-reset-pulse {
   0% {
-  transform: scale(0);
+    transform: scale(0);
+  }
+  75% {
+    transform: scale(1.5);
   }
   100% {
-  transform: scale(1.5);
+    transform: scale(1.0);
   }
 }
 
 #urlbar-zoom-button {
   -moz-appearance: none;
   margin: 0 3px;
   font-size: .8em;
   padding: 0 8px;
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -1657,18 +1657,21 @@ toolbar .toolbarbutton-1 > .toolbarbutto
   height: 16px;
 }
 
 /* ::::: URL Bar Zoom Reset Button ::::: */
 @keyframes urlbar-zoom-reset-pulse {
   0% {
     transform: scale(0);
   }
+  75% {
+    transform: scale(1.5);
+  }
   100% {
-    transform: scale(1.5);
+    transform: scale(1.0);
   }
 }
 
 #urlbar-zoom-button {
   margin: 0 3px;
   font-size: .8em;
   padding: 0 8px;
   border-radius: 1em;
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -1387,20 +1387,23 @@ html|*.urlbar-input:-moz-lwtheme::-moz-p
   /* 16x16 icon with border-box sizing */
   width: 22px;
   height: 16px;
 }
 
 /* ::::: URL Bar Zoom Reset Button ::::: */
 @keyframes urlbar-zoom-reset-pulse {
   0% {
-  transform: scale(0);
+    transform: scale(0);
+  }
+  75% {
+    transform: scale(1.5);
   }
   100% {
-  transform: scale(1.5);
+    transform: scale(1.0);
   }
 }
 
 #urlbar-zoom-button {
   -moz-appearance: none;
   margin: 0 3px;
   font-size: .8em;
   padding: 0 8px;
--- a/devtools/client/responsive.html/index.css
+++ b/devtools/client/responsive.html/index.css
@@ -240,16 +240,21 @@ html, body {
 .browser-container {
   width: inherit;
   height: inherit;
 }
 
 .browser {
   display: block;
   border: 0;
+  -moz-user-select: none;
+}
+
+.browser:-moz-focusring {
+  outline: none;
 }
 
 /**
  * Viewport Resize Handles
  */
 
 .viewport-resize-handle {
   position: absolute;
--- a/dom/base/nsCopySupport.cpp
+++ b/dom/base/nsCopySupport.cpp
@@ -303,16 +303,25 @@ nsCopySupport::HTMLCopy(nsISelection* aS
   uint32_t flags = nsIDocumentEncoder::SkipInvisibleContent;
   if (aWithRubyAnnotation) {
     flags |= nsIDocumentEncoder::OutputRubyAnnotation;
   }
   return SelectionCopyHelper(aSel, aDoc, true, aClipboardID, flags, nullptr);
 }
 
 nsresult
+nsCopySupport::ClearSelectionCache()
+{
+  nsresult rv;
+  nsCOMPtr<nsIClipboard> clipboard = do_GetService(kCClipboardCID, &rv);
+  clipboard->EmptyClipboard(nsIClipboard::kSelectionCache);
+  return rv;
+}
+
+nsresult
 nsCopySupport::GetTransferableForSelection(nsISelection* aSel,
                                            nsIDocument* aDoc,
                                            nsITransferable** aTransferable)
 {
   return SelectionCopyHelper(aSel, aDoc, false, 0,
                              nsIDocumentEncoder::SkipInvisibleContent,
                              aTransferable);
 }
--- a/dom/base/nsCopySupport.h
+++ b/dom/base/nsCopySupport.h
@@ -20,16 +20,17 @@ class nsACString;
 class nsAString;
 class nsIPresShell;
 class nsILoadContext;
 
 class nsCopySupport
 {
   // class of static helper functions for copy support
   public:
+    static nsresult ClearSelectionCache();
     static nsresult HTMLCopy(nsISelection *aSel, nsIDocument *aDoc,
                              int16_t aClipboardID, bool aWithRubyAnnotation);
     static nsresult DoHooks(nsIDocument *aDoc, nsITransferable *aTrans,
                             bool *aDoPutOnClipboard);
 
     // Get the selection, or entire document, in the format specified by the mime type
     // (text/html or text/plain). If aSel is non-null, use it, otherwise get the entire
     // doc.
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1242,16 +1242,28 @@ nsDOMWindowUtils::ForceUpdateNativeMenuA
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (!widget)
     return NS_ERROR_FAILURE;
 
   return widget->ForceUpdateNativeMenuAt(indexString);
 }
 
+NS_IMETHODIMP
+nsDOMWindowUtils::GetSelectionAsPlaintext(nsAString& aResult)
+{
+  // Get the widget to send the event to.
+  nsCOMPtr<nsIWidget> widget = GetWidget();
+  if (!widget) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return widget->GetSelectionAsPlaintext(aResult);
+}
+
 nsIWidget*
 nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
 {
   nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryReferent(mWindow);
   if (window) {
     nsIDocShell *docShell = window->GetDocShell();
     if (docShell) {
       nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -1951,16 +1951,19 @@ GK_ATOM(onuserproximity, "onuserproximit
 
 // light sensor support
 GK_ATOM(ondevicelight, "ondevicelight")
 
 // Audio channel events
 GK_ATOM(onmozinterruptbegin, "onmozinterruptbegin")
 GK_ATOM(onmozinterruptend, "onmozinterruptend")
 
+// MediaDevices device change event
+GK_ATOM(ondevicechange, "ondevicechange")
+
 //---------------------------------------------------------------------------
 // Special atoms
 //---------------------------------------------------------------------------
 
 // Node types
 GK_ATOM(cdataTagName, "#cdata-section")
 GK_ATOM(commentTagName, "#comment")
 GK_ATOM(documentNodeName, "#document")
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -5096,16 +5096,17 @@ EventStateManager::FlushPendingEvents(ns
     shell->FlushPendingNotifications(Flush_InterruptibleLayout);
   }
 }
 
 nsIContent*
 EventStateManager::GetFocusedContent()
 {
   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
+  EnsureDocument(mPresContext);
   if (!fm || !mDocument)
     return nullptr;
 
   nsCOMPtr<nsPIDOMWindowOuter> focusedWindow;
   return nsFocusManager::GetFocusedDescendant(mDocument->GetWindow(), false,
                                               getter_AddRefs(focusedWindow));
 }
 
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -1717,17 +1717,17 @@ HTMLMediaElement::Seek(double aTime,
   if (EventStateManager::IsHandlingUserInput() || nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
     mHasUserInteraction = true;
   }
 
   StopSuspendingAfterFirstFrame();
 
   if (mSrcStream) {
     // do nothing since media streams have an empty Seekable range.
-    promise->MaybeRejectWithUndefined();
+    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   if (mPlayed && mCurrentPlayRangeStart != -1.0) {
     double rangeEndTime = CurrentTime();
     LOG(LogLevel::Debug, ("%p Adding \'played\' a range : [%f, %f]", this, mCurrentPlayRangeStart, rangeEndTime));
     // Multiple seek without playing, or seek while playing.
     if (mCurrentPlayRangeStart != rangeEndTime) {
@@ -1735,39 +1735,39 @@ HTMLMediaElement::Seek(double aTime,
     }
     // Reset the current played range start time. We'll re-set it once
     // the seek completes.
     mCurrentPlayRangeStart = -1.0;
   }
 
   if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
     mDefaultPlaybackStartPosition = aTime;
-    promise->MaybeRejectWithUndefined();
+    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   if (!mDecoder) {
     // mDecoder must always be set in order to reach this point.
     NS_ASSERTION(mDecoder, "SetCurrentTime failed: no decoder");
-    promise->MaybeRejectWithUndefined();
+    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   // Clamp the seek target to inside the seekable ranges.
   RefPtr<dom::TimeRanges> seekable = new dom::TimeRanges(ToSupports(OwnerDoc()));
   media::TimeIntervals seekableIntervals = mDecoder->GetSeekable();
   if (seekableIntervals.IsInvalid()) {
     aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); // This will reject the promise.
     return promise.forget();
   }
   seekableIntervals.ToTimeRanges(seekable);
   uint32_t length = 0;
   seekable->GetLength(&length);
   if (!length) {
-    promise->MaybeRejectWithUndefined();
+    promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
     return promise.forget();
   }
 
   // If the position we want to seek to is not in a seekable range, we seek
   // to the closest position in the seekable ranges instead. If two positions
   // are equally close, we seek to the closest position from the currentTime.
   // See seeking spec, point 7 :
   // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#seeking
--- a/dom/interfaces/base/nsIDOMWindowUtils.idl
+++ b/dom/interfaces/base/nsIDOMWindowUtils.idl
@@ -778,16 +778,25 @@ interface nsIDOMWindowUtils : nsISupport
    * See nsIWidget::ForceUpdateNativeMenuAt
    *
    * Cannot be accessed from unprivileged context (not content-accessible)
    * Will throw a DOM security error if called without chrome privileges.
    */
   void forceUpdateNativeMenuAt(in AString indexString);
 
   /**
+   * Returns the current selection as plaintext. Note that the result may be
+   * different from the result of sendQueryContentEvent(QUERY_SELECTED_TEXT).
+   * This result is computed by native API with transferable data. In other
+   * words, when the OS treats the selection as plaintext, it treats current
+   * selection as this result.
+   */
+  AString GetSelectionAsPlaintext();
+
+  /**
    * Focus the element aElement. The element should be in the same document
    * that the window is displaying. Pass null to blur the element, if any,
    * that currently has focus, and focus the document.
    *
    * Cannot be accessed from unprivileged context (not content-accessible)
    * Will throw a DOM security error if called without chrome privileges.
    *
    * @param aElement the element to focus
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -827,17 +827,17 @@ MediaDecoder::AsyncResolveSeekDOMPromise
 
 void
 MediaDecoder::AsyncRejectSeekDOMPromiseIfExists()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mSeekDOMPromise) {
     RefPtr<dom::Promise> promise = mSeekDOMPromise;
     nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
-      promise->MaybeRejectWithUndefined();
+      promise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
     });
     AbstractThread::MainThread()->Dispatch(r.forget());
     mSeekDOMPromise = nullptr;
   }
 }
 
 void
 MediaDecoder::DiscardOngoingSeekIfExists()
--- a/dom/media/MediaDevices.cpp
+++ b/dom/media/MediaDevices.cpp
@@ -174,16 +174,82 @@ MediaDevices::EnumerateDevices(ErrorResu
 }
 
 NS_IMPL_ADDREF_INHERITED(MediaDevices, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(MediaDevices, DOMEventTargetHelper)
 NS_INTERFACE_MAP_BEGIN(MediaDevices)
   NS_INTERFACE_MAP_ENTRY(MediaDevices)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
+void
+MediaDevices::OnDeviceChange()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  nsresult rv = CheckInnerWindowCorrectness();
+  if (NS_FAILED(rv))
+    return;
+
+  if (!(MediaManager::Get()->IsActivelyCapturingOrHasAPermission(GetOwner()->WindowID()) ||
+    Preferences::GetBool("media.navigator.permission.disabled", false))) {
+    return;
+  }
+
+  DispatchTrustedEvent(NS_LITERAL_STRING("devicechange"));
+}
+
+mozilla::dom::EventHandlerNonNull*
+MediaDevices::GetOndevicechange()
+{
+  if (NS_IsMainThread()) {
+    return GetEventHandler(nsGkAtoms::ondevicechange, EmptyString());
+  }
+  return GetEventHandler(nullptr, NS_LITERAL_STRING("devicechange"));
+}
+
+void
+MediaDevices::SetOndevicechange(mozilla::dom::EventHandlerNonNull* aCallback)
+{
+  if (NS_IsMainThread()) {
+    SetEventHandler(nsGkAtoms::ondevicechange, EmptyString(), aCallback);
+  } else {
+    SetEventHandler(nullptr, NS_LITERAL_STRING("devicechange"), aCallback);
+  }
+
+  MediaManager::Get()->AddDeviceChangeCallback(this);
+}
+
+nsresult
+MediaDevices::AddEventListener(const nsAString& aType,
+  nsIDOMEventListener* aListener,
+  bool aUseCapture, bool aWantsUntrusted,
+  uint8_t optional_argc)
+{
+  MediaManager::Get()->AddDeviceChangeCallback(this);
+
+  return mozilla::DOMEventTargetHelper::AddEventListener(aType, aListener,
+    aUseCapture,
+    aWantsUntrusted,
+    optional_argc);
+}
+
+void
+MediaDevices::AddEventListener(const nsAString& aType,
+  dom::EventListener* aListener,
+  const dom::AddEventListenerOptionsOrBoolean& aOptions,
+  const dom::Nullable<bool>& aWantsUntrusted,
+  ErrorResult& aRv)
+{
+  MediaManager::Get()->AddDeviceChangeCallback(this);
+
+  return mozilla::DOMEventTargetHelper::AddEventListener(aType, aListener,
+    aOptions,
+    aWantsUntrusted,
+    aRv);
+}
+
 JSObject*
 MediaDevices::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return MediaDevicesBinding::Wrap(aCx, this, aGivenProto);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/media/MediaDevices.h
+++ b/dom/media/MediaDevices.h
@@ -5,29 +5,31 @@
 #ifndef mozilla_dom_MediaDevices_h
 #define mozilla_dom_MediaDevices_h
 
 #include "mozilla/ErrorResult.h"
 #include "nsISupportsImpl.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/BindingUtils.h"
 #include "nsPIDOMWindow.h"
+#include "DeviceChangeCallback.h"
 
 namespace mozilla {
 namespace dom {
 
 class Promise;
 struct MediaStreamConstraints;
 struct MediaTrackSupportedConstraints;
 
 #define MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID \
 { 0x2f784d8a, 0x7485, 0x4280, \
  { 0x9a, 0x36, 0x74, 0xa4, 0xd6, 0x71, 0xa6, 0xc8 } }
 
 class MediaDevices final : public DOMEventTargetHelper
+                          ,public DeviceChangeCallback
 {
 public:
   explicit MediaDevices(nsPIDOMWindowInner* aWindow) :
     DOMEventTargetHelper(aWindow) {}
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIADEVICES_IMPLEMENTATION_IID)
 
@@ -37,16 +39,33 @@ public:
   void GetSupportedConstraints(MediaTrackSupportedConstraints& aResult) {};
 
   already_AddRefed<Promise>
   GetUserMedia(const MediaStreamConstraints& aConstraints, ErrorResult &aRv);
 
   already_AddRefed<Promise>
   EnumerateDevices(ErrorResult &aRv);
 
+  virtual void OnDeviceChange() override;
+
+  mozilla::dom::EventHandlerNonNull* GetOndevicechange();
+
+  void SetOndevicechange(mozilla::dom::EventHandlerNonNull* aCallback);
+
+  NS_IMETHOD AddEventListener(const nsAString& aType,
+    nsIDOMEventListener* aListener,
+    bool aUseCapture, bool aWantsUntrusted,
+    uint8_t optional_argc) override;
+
+  virtual void AddEventListener(const nsAString& aType,
+                                dom::EventListener* aListener,
+                                const dom::AddEventListenerOptionsOrBoolean& aOptions,
+                                const dom::Nullable<bool>& aWantsUntrusted,
+                                ErrorResult& aRv) override;
+
 private:
   class GumResolver;
   class EnumDevResolver;
   class GumRejecter;
 
   virtual ~MediaDevices() {}
 };
 
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -39,16 +39,17 @@
 #include "mozilla/Types.h"
 #include "mozilla/PeerIdentity.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/MediaStreamBinding.h"
 #include "mozilla/dom/MediaStreamTrackBinding.h"
 #include "mozilla/dom/GetUserMediaRequestBinding.h"
 #include "mozilla/dom/Promise.h"
+#include "mozilla/dom/MediaDevices.h"
 #include "mozilla/Base64.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/media/MediaChild.h"
 #include "mozilla/media/MediaTaskUtils.h"
 #include "MediaTrackConstraints.h"
 #include "VideoUtils.h"
 #include "Latency.h"
 #include "nsProxyRelease.h"
@@ -1703,16 +1704,17 @@ MediaManager::MediaManager()
   mPrefs.mHeight       = 0; // adaptive default
   mPrefs.mFPS          = MediaEngine::DEFAULT_VIDEO_FPS;
   mPrefs.mMinFPS       = MediaEngine::DEFAULT_VIDEO_MIN_FPS;
   mPrefs.mAecOn        = false;
   mPrefs.mAgcOn        = false;
   mPrefs.mNoiseOn      = false;
   mPrefs.mExtendedFilter = true;
   mPrefs.mDelayAgnostic = true;
+  mPrefs.mFakeDeviceChangeEventOn = false;
 #ifdef MOZ_WEBRTC
   mPrefs.mAec          = webrtc::kEcUnchanged;
   mPrefs.mAgc          = webrtc::kAgcUnchanged;
   mPrefs.mNoise        = webrtc::kNsUnchanged;
 #else
   mPrefs.mAec          = 0;
   mPrefs.mAgc          = 0;
   mPrefs.mNoise        = 0;
@@ -1801,16 +1803,17 @@ MediaManager::Get() {
 #ifdef MOZ_WEBRTC
       prefs->AddObserver("media.getusermedia.aec_enabled", sSingleton, false);
       prefs->AddObserver("media.getusermedia.aec", sSingleton, false);
       prefs->AddObserver("media.getusermedia.agc_enabled", sSingleton, false);
       prefs->AddObserver("media.getusermedia.agc", sSingleton, false);
       prefs->AddObserver("media.getusermedia.noise_enabled", sSingleton, false);
       prefs->AddObserver("media.getusermedia.noise", sSingleton, false);
       prefs->AddObserver("media.getusermedia.playout_delay", sSingleton, false);
+      prefs->AddObserver("media.ondevicechange.fakeDeviceChangeEvent.enabled", sSingleton, false);
 #endif
     }
 
     // Prepare async shutdown
 
     nsCOMPtr<nsIAsyncShutdownClient> shutdownPhase = GetShutdownPhase();
 
     class Blocker : public media::ShutdownBlocker
@@ -1991,16 +1994,38 @@ bool MediaManager::IsLoop(nsIURI* aDocUR
 
 bool MediaManager::IsPrivateBrowsing(nsPIDOMWindowInner* window)
 {
   nsCOMPtr<nsIDocument> doc = window->GetDoc();
   nsCOMPtr<nsILoadContext> loadContext = doc->GetLoadContext();
   return loadContext && loadContext->UsePrivateBrowsing();
 }
 
+int MediaManager::AddDeviceChangeCallback(DeviceChangeCallback* aCallback)
+{
+  bool fakeDeviceChangeEventOn = mPrefs.mFakeDeviceChangeEventOn;
+  MediaManager::PostTask(NewTaskFrom([fakeDeviceChangeEventOn]() {
+    RefPtr<MediaManager> manager = MediaManager_GetInstance();
+    manager->GetBackend(0)->AddDeviceChangeCallback(manager);
+    if (fakeDeviceChangeEventOn)
+      manager->GetBackend(0)->SetFakeDeviceChangeEvents();
+  }));
+
+  return DeviceChangeCallback::AddDeviceChangeCallback(aCallback);
+}
+
+void MediaManager::OnDeviceChange() {
+  RefPtr<MediaManager> self(this);
+  NS_DispatchToMainThread(media::NewRunnableFrom([self,this]() mutable {
+    MOZ_ASSERT(NS_IsMainThread());
+    DeviceChangeCallback::OnDeviceChange();
+    return NS_OK;
+  }));
+}
+
 nsresult MediaManager::GenerateUUID(nsAString& aResult)
 {
   nsresult rv;
   nsCOMPtr<nsIUUIDGenerator> uuidgen =
       do_GetService("@mozilla.org/uuid-generator;1", &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Generate a call ID.
@@ -2720,16 +2745,35 @@ MediaManager::OnNavigation(uint64_t aWin
   // This is safe since we're on main-thread, and the windowlist can only
   // be added to from the main-thread
   auto* window = nsGlobalWindow::GetInnerWindowWithId(aWindowID);
   if (window) {
     IterateWindowListeners(window->AsInner(), StopSharingCallback, nullptr);
   } else {
     RemoveWindowID(aWindowID);
   }
+
+  RemoveMediaDevicesCallback(aWindowID);
+}
+
+void
+MediaManager::RemoveMediaDevicesCallback(uint64_t aWindowID)
+{
+  for (DeviceChangeCallback* observer : mDeviceChangeCallbackList)
+  {
+    dom::MediaDevices* mediadevices = static_cast<dom::MediaDevices *>(observer);
+    MOZ_ASSERT(mediadevices);
+    if (mediadevices) {
+      nsPIDOMWindowInner* window = mediadevices->GetOwner();
+      MOZ_ASSERT(window);
+      if (window && window->WindowID() == aWindowID)
+        DeviceChangeCallback::RemoveDeviceChangeCallback(observer);
+        return;
+    }
+  }
 }
 
 StreamListeners*
 MediaManager::AddWindowID(uint64_t aWindowId)
 {
   MOZ_ASSERT(NS_IsMainThread());
   // Store the WindowID in a hash table and mark as active. The entry is removed
   // when this window is closed or navigated away from.
@@ -2831,16 +2875,17 @@ MediaManager::GetPrefs(nsIPrefBranch *aB
   GetPrefBool(aBranch, "media.getusermedia.agc_enabled", aData, &mPrefs.mAgcOn);
   GetPrefBool(aBranch, "media.getusermedia.noise_enabled", aData, &mPrefs.mNoiseOn);
   GetPref(aBranch, "media.getusermedia.aec", aData, &mPrefs.mAec);
   GetPref(aBranch, "media.getusermedia.agc", aData, &mPrefs.mAgc);
   GetPref(aBranch, "media.getusermedia.noise", aData, &mPrefs.mNoise);
   GetPref(aBranch, "media.getusermedia.playout_delay", aData, &mPrefs.mPlayoutDelay);
   GetPrefBool(aBranch, "media.getusermedia.aec_extended_filter", aData, &mPrefs.mExtendedFilter);
   GetPrefBool(aBranch, "media.getusermedia.aec_aec_delay_agnostic", aData, &mPrefs.mDelayAgnostic);
+  GetPrefBool(aBranch, "media.ondevicechange.fakeDeviceChangeEvent.enabled", aData, &mPrefs.mFakeDeviceChangeEventOn);
 #endif
   GetPrefBool(aBranch, "media.navigator.audio.full_duplex", aData, &mPrefs.mFullDuplex);
 }
 
 void
 MediaManager::Shutdown()
 {
   MOZ_ASSERT(NS_IsMainThread());
@@ -2867,16 +2912,17 @@ MediaManager::Shutdown()
 #ifdef MOZ_WEBRTC
     prefs->RemoveObserver("media.getusermedia.aec_enabled", this);
     prefs->RemoveObserver("media.getusermedia.aec", this);
     prefs->RemoveObserver("media.getusermedia.agc_enabled", this);
     prefs->RemoveObserver("media.getusermedia.agc", this);
     prefs->RemoveObserver("media.getusermedia.noise_enabled", this);
     prefs->RemoveObserver("media.getusermedia.noise", this);
     prefs->RemoveObserver("media.getusermedia.playout_delay", this);
+    prefs->RemoveObserver("media.ondevicechange.fakeDeviceChangeEvent.enabled", this);
 #endif
     prefs->RemoveObserver("media.navigator.audio.full_duplex", this);
   }
 
   // Close off any remaining active windows.
   GetActiveWindows()->Clear();
   mActiveCallbacks.Clear();
   mCallIds.Clear();
@@ -2899,16 +2945,17 @@ MediaManager::Shutdown()
     Run() override
     {
       LOG(("MediaManager Thread Shutdown"));
       MOZ_ASSERT(MediaManager::IsInMediaThread());
       // Must shutdown backend on MediaManager thread, since that's where we started it from!
       {
         if (mManager->mBackend) {
           mManager->mBackend->Shutdown(); // ok to invoke multiple times
+          mManager->mBackend->RemoveDeviceChangeCallback(mManager);
         }
       }
       mozilla::ipc::BackgroundChild::CloseForCurrentThread();
       // must explicitly do this before dispatching the reply, since the reply may kill us with Stop()
       mManager->mBackend = nullptr; // last reference, will invoke Shutdown() again
 
       if (NS_FAILED(NS_DispatchToMainThread(mReply.forget()))) {
         LOG(("Will leak thread: DispatchToMainthread of reply runnable failed in MediaManager shutdown"));
--- a/dom/media/MediaManager.h
+++ b/dom/media/MediaManager.h
@@ -1,16 +1,17 @@
 /* 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 MOZILLA_MEDIAMANAGER_H
 #define MOZILLA_MEDIAMANAGER_H
 
 #include "MediaEngine.h"
+#include "DeviceChangeCallback.h"
 #include "mozilla/Services.h"
 #include "mozilla/unused.h"
 #include "nsAutoPtr.h"
 #include "nsIMediaManager.h"
 
 #include "nsHashKeys.h"
 #include "nsGlobalWindow.h"
 #include "nsClassHashtable.h"
@@ -182,16 +183,17 @@ typedef nsClassHashtable<nsUint64HashKey
 // we could add MediaManager if needed
 typedef void (*WindowListenerCallback)(MediaManager *aThis,
                                        uint64_t aWindowID,
                                        StreamListeners *aListeners,
                                        void *aData);
 
 class MediaManager final : public nsIMediaManagerService,
                            public nsIObserver
+                          ,public DeviceChangeCallback
 {
   friend GetUserMediaCallbackMediaStreamListener;
 public:
   static already_AddRefed<MediaManager> GetInstance();
 
   // NOTE: never Dispatch(....,NS_DISPATCH_SYNC) to the MediaManager
   // thread from the MainThread, as we NS_DISPATCH_SYNC to MainThread
   // from MediaManager thread.
@@ -251,16 +253,19 @@ public:
   nsresult EnumerateDevices(nsPIDOMWindowInner* aWindow, dom::Promise& aPromise);
   void OnNavigation(uint64_t aWindowID);
   bool IsActivelyCapturingOrHasAPermission(uint64_t aWindowId);
 
   MediaEnginePrefs mPrefs;
 
   typedef nsTArray<RefPtr<MediaDevice>> SourceSet;
   static bool IsPrivateBrowsing(nsPIDOMWindowInner* window);
+
+  virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback) override;
+  virtual void OnDeviceChange() override;
 private:
   typedef media::Pledge<SourceSet*, dom::MediaStreamError*> PledgeSourceSet;
   typedef media::Pledge<const char*, dom::MediaStreamError*> PledgeChar;
   typedef media::Pledge<bool, dom::MediaStreamError*> PledgeVoid;
 
   static bool IsPrivileged();
   static bool IsLoop(nsIURI* aDocURI);
   static nsresult GenerateUUID(nsAString& aResult);
@@ -303,16 +308,17 @@ private:
   void Shutdown();
 
   void StopScreensharing(uint64_t aWindowID);
   void IterateWindowListeners(nsPIDOMWindowInner *aWindow,
                               WindowListenerCallback aCallback,
                               void *aData);
 
   void StopMediaStreams();
+  void RemoveMediaDevicesCallback(uint64_t aWindowID);
 
   // ONLY access from MainThread so we don't need to lock
   WindowTable mActiveWindows;
   nsRefPtrHashtable<nsStringHashKey, GetUserMediaTask> mActiveCallbacks;
   nsClassHashtable<nsUint64HashKey, nsTArray<nsString>> mCallIds;
 
   // Always exists
   nsAutoPtr<base::Thread> mMediaThread;
--- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
+++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp
@@ -140,17 +140,18 @@ FFmpegVideoDecoder<LIBAV_VER>::InitCodec
   if (mInfo.mDisplay.width >= 2048) {
     decode_threads = 8;
   } else if (mInfo.mDisplay.width >= 1024) {
     decode_threads = 4;
   } else if (mInfo.mDisplay.width >= 320) {
     decode_threads = 2;
   }
 
-  decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors());
+  decode_threads = std::min(decode_threads, PR_GetNumberOfProcessors() - 1);
+  decode_threads = std::max(decode_threads, 1);
   mCodecContext->thread_count = decode_threads;
   if (decode_threads > 1) {
     mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME;
   }
 
   // FFmpeg will call back to this to negotiate a video pixel format.
   mCodecContext->get_format = ChoosePixelFormat;
 
--- a/dom/media/systemservices/CamerasChild.cpp
+++ b/dom/media/systemservices/CamerasChild.cpp
@@ -20,30 +20,61 @@
 #include "nsThreadUtils.h"
 
 #undef LOG
 #undef LOG_ENABLED
 mozilla::LazyLogModule gCamerasChildLog("CamerasChild");
 #define LOG(args) MOZ_LOG(gCamerasChildLog, mozilla::LogLevel::Debug, args)
 #define LOG_ENABLED() MOZ_LOG_TEST(gCamerasChildLog, mozilla::LogLevel::Debug)
 
+#define FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS 5000
+#define FAKE_ONDEVICECHANGE_EVENT_REPEAT_COUNT 30
+
 namespace mozilla {
 namespace camera {
 
 CamerasSingleton::CamerasSingleton()
   : mCamerasMutex("CamerasSingleton::mCamerasMutex"),
     mCameras(nullptr),
     mCamerasChildThread(nullptr) {
   LOG(("CamerasSingleton: %p", this));
 }
 
 CamerasSingleton::~CamerasSingleton() {
   LOG(("~CamerasSingleton: %p", this));
 }
 
+class FakeOnDeviceChangeEventRunnable : public Runnable
+{
+public:
+  explicit FakeOnDeviceChangeEventRunnable(uint8_t counter)
+    : mCounter(counter) {}
+
+  NS_IMETHOD Run() override
+  {
+    OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
+
+    CamerasChild* child = CamerasSingleton::Child();
+    if (child) {
+      child->OnDeviceChange();
+
+      if (mCounter++ < FAKE_ONDEVICECHANGE_EVENT_REPEAT_COUNT) {
+        RefPtr<FakeOnDeviceChangeEventRunnable> evt = new FakeOnDeviceChangeEventRunnable(mCounter);
+        CamerasSingleton::Thread()->DelayedDispatch(evt.forget(),
+          FAKE_ONDEVICECHANGE_EVENT_PERIOD_IN_MS);
+      }
+    }
+
+    return NS_OK;
+  }
+
+private:
+  uint8_t mCounter;
+};
+
 class InitializeIPCThread : public Runnable
 {
 public:
   InitializeIPCThread()
     : mCamerasChild(nullptr) {}
 
   NS_IMETHOD Run() override {
     // Try to get the PBackground handle
@@ -103,16 +134,22 @@ GetCamerasChild() {
     CamerasSingleton::Child() = runnable->GetCamerasChild();
   }
   if (!CamerasSingleton::Child()) {
     LOG(("Failed to set up CamerasChild, are we in shutdown?"));
   }
   return CamerasSingleton::Child();
 }
 
+CamerasChild*
+GetCamerasChildIfExists() {
+  OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
+  return CamerasSingleton::Child();
+}
+
 bool
 CamerasChild::RecvReplyFailure(void)
 {
   LOG((__PRETTY_FUNCTION__));
   MonitorAutoLock monitor(mReplyMonitor);
   mReceivedReply = true;
   mReplySuccess = false;
   monitor.Notify();
@@ -575,16 +612,36 @@ CamerasChild::RecvDeliverFrame(const int
   } else {
     LOG(("DeliverFrame called with dead callback"));
   }
   SendReleaseFrame(shmem);
   return true;
 }
 
 bool
+CamerasChild::RecvDeviceChange()
+{
+  this->OnDeviceChange();
+  return true;
+}
+
+int
+CamerasChild::SetFakeDeviceChangeEvents()
+{
+  CamerasSingleton::Mutex().AssertCurrentThreadOwns();
+
+  // To simulate the devicechange event in mochitest,
+  // we fire a fake devicechange event in Camera IPC thread periodically
+  RefPtr<FakeOnDeviceChangeEventRunnable> evt = new FakeOnDeviceChangeEventRunnable(0);
+  CamerasSingleton::Thread()->Dispatch(evt.forget(), NS_DISPATCH_NORMAL);
+
+  return 0;
+}
+
+bool
 CamerasChild::RecvFrameSizeChange(const int& capEngine,
                                   const int& capId,
                                   const int& w, const int& h)
 {
   LOG((__PRETTY_FUNCTION__));
   MutexAutoLock lock(mCallbackMutex);
   CaptureEngine capEng = static_cast<CaptureEngine>(capEngine);
   if (Callback(capEng, capId)) {
--- a/dom/media/systemservices/CamerasChild.h
+++ b/dom/media/systemservices/CamerasChild.h
@@ -7,16 +7,17 @@
 #ifndef mozilla_CamerasChild_h
 #define mozilla_CamerasChild_h
 
 #include "mozilla/Move.h"
 #include "mozilla/Pair.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/camera/PCamerasChild.h"
 #include "mozilla/camera/PCamerasParent.h"
+#include "DeviceChangeCallback.h"
 #include "mozilla/Mutex.h"
 #include "base/singleton.h"
 #include "nsCOMPtr.h"
 
 // conflicts with #include of scoped_ptr.h
 #undef FF
 #include "webrtc/common.h"
 // Video Engine
@@ -113,16 +114,18 @@ private:
 
 // Get a pointer to a CamerasChild object we can use to do IPC with.
 // This does everything needed to set up, including starting the IPC
 // channel with PBackground, blocking until thats done, and starting the
 // thread to do IPC on. This will fail if we're in shutdown. On success
 // it will set up the CamerasSingleton.
 CamerasChild* GetCamerasChild();
 
+CamerasChild* GetCamerasChildIfExists();
+
 // Shut down the IPC channel and everything associated, like WebRTC.
 // This is a static call because the CamerasChild object may not even
 // be alive when we're called.
 void Shutdown(void);
 
 // Obtain the CamerasChild object (if possible, i.e. not shutting down),
 // and maintain a grip on the object for the duration of the call.
 template <class MEM_FUN, class... ARGS>
@@ -133,16 +136,17 @@ int GetChildAndCall(MEM_FUN&& f, ARGS&&.
   if (child) {
     return (child->*f)(mozilla::Forward<ARGS>(args)...);
   } else {
     return -1;
   }
 }
 
 class CamerasChild final : public PCamerasChild
+                          ,public DeviceChangeCallback
 {
   friend class mozilla::ipc::BackgroundChildImpl;
   template <class T> friend class mozilla::camera::LockAndDispatch;
 
 public:
   // We are owned by the PBackground thread only. CamerasSingleton
   // takes a non-owning reference.
   NS_INLINE_DECL_REFCOUNTING(CamerasChild)
@@ -150,16 +154,19 @@ public:
   // IPC messages recevied, received on the PBackground thread
   // these are the actual callbacks with data
   virtual bool RecvDeliverFrame(const int&, const int&, mozilla::ipc::Shmem&&,
                                 const size_t&, const uint32_t&, const int64_t&,
                                 const int64_t&) override;
   virtual bool RecvFrameSizeChange(const int&, const int&,
                                    const int& w, const int& h) override;
 
+  virtual bool RecvDeviceChange() override;
+  int SetFakeDeviceChangeEvents();
+
   // these are response messages to our outgoing requests
   virtual bool RecvReplyNumberOfCaptureDevices(const int&) override;
   virtual bool RecvReplyNumberOfCapabilities(const int&) override;
   virtual bool RecvReplyAllocateCaptureDevice(const int&) override;
   virtual bool RecvReplyGetCaptureCapability(const CaptureCapability& capability) override;
   virtual bool RecvReplyGetCaptureDevice(const nsCString& device_name,
                                          const nsCString& device_id) override;
   virtual bool RecvReplyFailure(void) override;
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -34,16 +34,34 @@ namespace camera {
 // - the main thread for some setups, and occassionally for video capture setup
 //   calls that don't work correctly elsewhere.
 // - the IPC thread on which PBackground is running and which receives and
 //   sends messages
 // - a thread which will execute the actual (possibly slow) camera access
 //   called "VideoCapture". On Windows this is a thread with an event loop
 //   suitable for UI access.
 
+void InputObserver::DeviceChange() {
+  LOG((__PRETTY_FUNCTION__));
+  MOZ_ASSERT(mParent);
+
+  RefPtr<nsIRunnable> ipc_runnable =
+    media::NewRunnableFrom([this]() -> nsresult {
+      if (mParent->IsShuttingDown()) {
+        return NS_ERROR_FAILURE;
+      }
+      Unused << mParent->SendDeviceChange();
+      return NS_OK;
+    });
+
+  nsIThread* thread = mParent->GetBackgroundThread();
+  MOZ_ASSERT(thread != nullptr);
+  thread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
+};
+
 class FrameSizeChangeRunnable : public Runnable {
 public:
   FrameSizeChangeRunnable(CamerasParent *aParent, CaptureEngine capEngine,
                           int cap_id, unsigned int aWidth, unsigned int aHeight)
     : mParent(aParent), mCapEngine(capEngine), mCapId(cap_id),
       mWidth(aWidth), mHeight(aHeight) {}
 
   NS_IMETHOD Run() override {
@@ -394,16 +412,25 @@ CamerasParent::SetupEngine(CaptureEngine
   }
 
   helper->mPtrViECapture = webrtc::ViECapture::GetInterface(helper->mEngine);
   if (!helper->mPtrViECapture) {
     LOG(("ViECapture::GetInterface failed"));
     return false;
   }
 
+  InputObserver** observer = mObservers.AppendElement(
+          new InputObserver(this));
+
+#ifdef DEBUG
+  MOZ_ASSERT(0 == helper->mPtrViECapture->RegisterInputObserver(*observer));
+#else
+  helper->mPtrViECapture->RegisterInputObserver(*observer);
+#endif
+
   helper->mPtrViERender = webrtc::ViERender::GetInterface(helper->mEngine);
   if (!helper->mPtrViERender) {
     LOG(("ViERender::GetInterface failed"));
     return false;
   }
 
   return true;
 }
@@ -430,30 +457,41 @@ CamerasParent::CloseEngines()
     if (mEngines[i].mEngineIsRunning) {
       LOG(("Being closed down while engine %d is running!", i));
     }
     if (mEngines[i].mPtrViERender) {
       mEngines[i].mPtrViERender->Release();
       mEngines[i].mPtrViERender = nullptr;
     }
     if (mEngines[i].mPtrViECapture) {
+#ifdef DEBUG
+      MOZ_ASSERT(0 == mEngines[i].mPtrViECapture->DeregisterInputObserver());
+#else
+      mEngines[i].mPtrViECapture->DeregisterInputObserver();
+#endif
+
       mEngines[i].mPtrViECapture->Release();
         mEngines[i].mPtrViECapture = nullptr;
     }
     if(mEngines[i].mPtrViEBase) {
       mEngines[i].mPtrViEBase->Release();
       mEngines[i].mPtrViEBase = nullptr;
     }
     if (mEngines[i].mEngine) {
       mEngines[i].mEngine->SetTraceCallback(nullptr);
       webrtc::VideoEngine::Delete(mEngines[i].mEngine);
       mEngines[i].mEngine = nullptr;
     }
   }
 
+  for (InputObserver* observer : mObservers) {
+    delete observer;
+  }
+  mObservers.Clear();
+
   mWebRTCAlive = false;
 }
 
 bool
 CamerasParent::EnsureInitialized(int aEngine)
 {
   LOG((__PRETTY_FUNCTION__));
   // We're shutting down, don't try to do new WebRTC ops.
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -71,16 +71,29 @@ public:
 
   // The webrtc code keeps a reference to this one.
   webrtc::Config mConfig;
 
   // Engine alive
   bool mEngineIsRunning;
 };
 
+class InputObserver :  public webrtc::ViEInputObserver
+{
+public:
+  explicit InputObserver(CamerasParent* aParent)
+    : mParent(aParent) {};
+  virtual void DeviceChange();
+
+  friend CamerasParent;
+
+private:
+  RefPtr<CamerasParent> mParent;
+};
+
 class CamerasParent :  public PCamerasParent,
                        public nsIObserver
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
 public:
   static already_AddRefed<CamerasParent> Create();
@@ -148,16 +161,17 @@ protected:
   base::Thread* mVideoCaptureThread;
 
   // Shutdown handling
   bool mChildIsAlive;
   bool mDestroyed;
   // Above 2 are PBackground only, but this is potentially
   // read cross-thread.
   mozilla::Atomic<bool> mWebRTCAlive;
+  nsTArray<InputObserver*> mObservers;
 };
 
 PCamerasParent* CreateCamerasParent();
 
 } // namespace camera
 } // namespace mozilla
 
 #endif  // mozilla_CameraParent_h
new file mode 100644
--- /dev/null
+++ b/dom/media/systemservices/DeviceChangeCallback.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* 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 mozilla_DeviceChangeCallback_h
+#define mozilla_DeviceChangeCallback_h
+
+namespace mozilla {
+
+class DeviceChangeCallback
+{
+public:
+  virtual void OnDeviceChange()
+  {
+    MutexAutoLock lock(mCallbackMutex);
+    for (DeviceChangeCallback* observer : mDeviceChangeCallbackList)
+    {
+      observer->OnDeviceChange();
+    }
+  }
+
+  virtual int AddDeviceChangeCallback(DeviceChangeCallback* aCallback)
+  {
+    MutexAutoLock lock(mCallbackMutex);
+    if (mDeviceChangeCallbackList.IndexOf(aCallback) == mDeviceChangeCallbackList.NoIndex)
+      mDeviceChangeCallbackList.AppendElement(aCallback);
+    return 0;
+  }
+
+  virtual int RemoveDeviceChangeCallback(DeviceChangeCallback* aCallback)
+  {
+    MutexAutoLock lock(mCallbackMutex);
+    if (mDeviceChangeCallbackList.IndexOf(aCallback) != mDeviceChangeCallbackList.NoIndex)
+      mDeviceChangeCallbackList.RemoveElement(aCallback);
+    return 0;
+  }
+
+  DeviceChangeCallback() : mCallbackMutex("mozilla::media::DeviceChangeCallback::mCallbackMutex")
+  {
+    mDeviceChangeCallbackList.Clear();
+  }
+
+  virtual ~DeviceChangeCallback()
+  {
+    mDeviceChangeCallbackList.Clear();
+  }
+
+protected:
+  nsTArray<DeviceChangeCallback*> mDeviceChangeCallbackList;
+  Mutex mCallbackMutex;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_DeviceChangeCallback_h
--- a/dom/media/systemservices/PCameras.ipdl
+++ b/dom/media/systemservices/PCameras.ipdl
@@ -24,16 +24,17 @@ async protocol PCameras
   manager PBackground;
 
 child:
   async FrameSizeChange(int capEngine, int cap_id, int w, int h);
   // transfers ownership of |buffer| from parent to child
   async DeliverFrame(int capEngine, int cap_id,
                      Shmem buffer, size_t size, uint32_t time_stamp,
                      int64_t ntp_time, int64_t render_time);
+  async DeviceChange();
   async ReplyNumberOfCaptureDevices(int numdev);
   async ReplyNumberOfCapabilities(int numdev);
   async ReplyAllocateCaptureDevice(int numdev);
   async ReplyGetCaptureCapability(CaptureCapability cap);
   async ReplyGetCaptureDevice(nsCString device_name, nsCString device_id);
   async ReplyFailure();
   async ReplySuccess();
   async __delete__();
--- a/dom/media/systemservices/moz.build
+++ b/dom/media/systemservices/moz.build
@@ -3,16 +3,17 @@
 # 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/.
 
 if CONFIG['MOZ_WEBRTC']:
     EXPORTS += [
         'CamerasChild.h',
         'CamerasParent.h',
+        'DeviceChangeCallback.h',
         'LoadManager.h',
         'LoadManagerFactory.h',
         'LoadMonitor.h',
     ]
     UNIFIED_SOURCES += [
         'CamerasChild.cpp',
         'CamerasParent.cpp',
         'LoadManager.cpp',
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -504,21 +504,19 @@ var gInfoLeakTests = [
     src: 'http://example.com/tests/dom/media/test/test_info_leak.html'
   }, {
     type: 'audio/ogg',
     src: 'http://example.com/tests/dom/media/test/test_info_leak.html'
   }
 ];
 
 // These are files that must fire an error during load or playback, and do not
-// cause a crash.  Put files of the same type together in this list so if
-// something crashes we have some idea of which backend is responsible.  Used
-// by test_playback_errors, which expects one error event and no ended event.
-// Put files of the same type together in this list so if something crashes
-// we have some idea of which backend is responsible.
+// cause a crash. Used by test_playback_errors, which expects one error event
+// and no ended event. Put files of the same type together in this list so if
+// something crashes we have some idea of which backend is responsible.
 var gErrorTests = [
   { name:"bogus.wav", type:"audio/x-wav" },
   { name:"bogus.ogv", type:"video/ogg" },
   { name:"448636.ogv", type:"video/ogg" },
   { name:"bug504843.ogv", type:"video/ogg" },
   { name:"bug501279.ogg", type:"audio/ogg" },
   { name:"bug580982.webm", type:"video/webm" },
   { name:"bug603918.webm", type:"video/webm" },
--- a/dom/media/test/mochitest.ini
+++ b/dom/media/test/mochitest.ini
@@ -665,19 +665,17 @@ tags=msg capturestream
 skip-if = toolkit == 'android' || toolkit == 'gonk' # android: bug 1149374; gonk: bug 1193351
 [test_eme_stream_capture_blocked_case2.html]
 tags=msg capturestream
 skip-if = toolkit == 'android' || toolkit == 'gonk' # android: bug 1149374; gonk: bug 1193351
 [test_eme_stream_capture_blocked_case3.html]
 tags=msg capturestream
 skip-if = toolkit == 'android' || toolkit == 'gonk' # android: bug 1149374; gonk: bug 1193351
 [test_empty_resource.html]
-skip-if = os == 'win' && debug #win debug : Bug 1202683
 [test_error_in_video_document.html]
-skip-if = toolkit == 'android' || (os == 'win' && !debug) || (os == 'mac' && !debug) # bug 608634
 [test_error_on_404.html]
 [test_fastSeek.html]
 [test_fastSeek-forwards.html]
 [test_gmp_playback.html]
 skip-if = (os != 'win' || os_version == '5.1') # Only gmp-clearkey on Windows Vista and later decodes
 [test_imagecapture.html]
 [test_info_leak.html]
 [test_invalid_reject.html]
--- a/dom/media/test/test_error_in_video_document.html
+++ b/dom/media/test/test_error_in_video_document.html
@@ -51,16 +51,17 @@ if (!t) {
 
   var f = document.createElement("iframe");
   f.src = t.name;
   f.addEventListener("load", function() {
     if (documentVideo().error) {
       info("Error occured by the time we got |load| - checking directly.");
       check();
     } else {
+      //TODO: Fix this todo in Bug 1295923.
       todo(false, "Error hasn't occurred yet - adding |error| event listener. This shouldn't happen, see bug 608634.");
       documentVideo().addEventListener("error", check);
     }
   }, false);
   document.body.appendChild(f);
 }
 
 </script>
--- a/dom/media/test/test_playback.html
+++ b/dom/media/test/test_playback.html
@@ -58,17 +58,16 @@ function startTest(test, token) {
       finish();
     }
   }
 
   var checkEnded = function(test, v) { return function() {
     is(test.name, v.name, test.name + ": Name should match #2");
     checkMetadata(test.name, v, test);
     is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
-    is(v.networkState, v.NETWORK_IDLE, test.name + " checking networkState");
     ok(v.ended, test.name + " checking playback has ended");
     ok(!v.finished, test.name + " shouldn't be finished");
     ok(!v.seenEnded, test.name + " shouldn't be ended");
 
     v.seenEnded = true;
     mayFinish();
   }}(test, v);
 
--- a/dom/media/test/test_playback_reactivate.html
+++ b/dom/media/test/test_playback_reactivate.html
@@ -58,17 +58,16 @@ function startTest(test, token) {
     removeNodeAndSource(v);
     manager.finished(v.token);
   }
 
   var checkEnded = function(test, v) { return function() {
     is(test.name, v.name, test.name + ": Name should match #2");
     checkMetadata(test.name, v, test);
     is(v.readyState, v.HAVE_CURRENT_DATA, test.name + " checking readyState");
-    is(v.networkState, v.NETWORK_IDLE, test.name + " checking networkState");
     ok(v.ended, test.name + " checking playback has ended");
 
     finish();
   }}(test, v);
 
 
   v.addEventListener("loadedmetadata", check, false);
   v.addEventListener("ended", checkEnded, false);
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -35,16 +35,18 @@ skip-if = toolkit == 'gonk' || buildapp 
 [test_dataChannel_basicDataOnly.html]
 [test_dataChannel_basicVideo.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g(Bug 960442, video support for WebRTC is disabled on b2g), android(Bug 1189784, timeouts on 4.3 emulator)
 [test_dataChannel_bug1013809.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' # b2g emulator seems to be too slow (Bug 1016498 and 1008080)
 [test_dataChannel_noOffer.html]
 [test_enumerateDevices.html]
 skip-if = buildapp == 'mulet'
+[test_ondevicechange.html]
+skip-if = toolkit == 'gonk' || buildapp == 'mulet' || os == 'linux' || os == 'win' || os == 'android'
 [test_getUserMedia_audioCapture.html]
 skip-if = toolkit == 'gonk' || buildapp == 'mulet' || android_version == '18' # b2g emulator seems to be too slow (Bug 1016498 and 1008080), android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_addTrackRemoveTrack.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_addtrack_removetrack_events.html]
 [test_getUserMedia_basicAudio.html]
 skip-if = (toolkit == 'gonk' || buildapp == 'mulet' && debug) # debug-only failure
 [test_getUserMedia_basicVideo.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_ondevicechange.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1041393
+-->
+<head>
+  <meta charset="utf-8">
+  <title>onndevicechange tests</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1152383">ondevicechange tests</a>
+<script type="application/javascript">
+
+const RESPONSE_WAIT_TIME_MS = 10000;
+
+function wait(time, message) {
+  return new Promise(r => setTimeout(() => r(message), time));
+}
+
+function OnDeviceChangeEvent() {
+  return new Promise(resolve => navigator.mediaDevices.ondevicechange = resolve);
+}
+
+function OnDeviceChangeEventReceived() {
+  return Promise.race([
+    OnDeviceChangeEvent(),
+    wait(RESPONSE_WAIT_TIME_MS).then(() => Promise.reject("Timed out while waiting for devicechange event"))
+  ]);
+}
+
+function OnDeviceChangeEventNotReceived() {
+  return Promise.race([
+    OnDeviceChangeEvent().then(() => Promise.reject("ondevicechange event is fired unexpectedly.")),
+    wait(RESPONSE_WAIT_TIME_MS)
+  ]);
+}
+
+var pushPrefs = (...p) => new Promise(r => SpecialPowers.pushPrefEnv({set: p}, r));
+
+var videoTracks;
+
+SimpleTest.requestCompleteLog();
+SimpleTest.waitForExplicitFinish();
+SimpleTest.requestFlakyTimeout("Fake devicechange event is fired periodically, \
+so we need to wait a while to make sure the event is fired or not as we expect.");
+
+var videoTracks;
+
+function wait(time, message) {
+  return new Promise(r => setTimeout(() => r(message), time));
+}
+
+pushPrefs(["media.ondevicechange.fakeDeviceChangeEvent.enabled", true])
+.then(() => pushPrefs(["media.navigator.permission.disabled", false]))
+.then(() => pushPrefs(["media.ondevicechange.enabled", true]))
+.then(() => info("assure devicechange event is NOT fired when gUM is NOT in use and permanent permission is NOT granted"))
+.then(() => OnDeviceChangeEventNotReceived())
+.then(() => ok(true, "devicechange event is NOT fired when gUM is NOT in use and permanent permission is NOT granted"))
+.then(() => pushPrefs(['media.navigator.permission.disabled', true]))
+.then(() => info("assure devicechange event is fired when gUM is NOT in use and permanent permission is granted"))
+.then(() => OnDeviceChangeEventReceived())
+.then(() => ok(true, "devicechange event is fired when gUM is NOT in use and permanent permission is granted"))
+.then(() => navigator.mediaDevices.getUserMedia({video: true, fake: true}))
+.then(st => {videoTracks = st.getVideoTracks();})
+.then(() => info("assure devicechange event is fired when gUM is in use"))
+.then(() => OnDeviceChangeEventReceived())
+.then(() => ok(true, "devicechange event is fired when gUM is in use"))
+.catch(e => ok(false, "Error: " + e))
+.then(() => {
+  if(videoTracks)
+    videoTracks.forEach(track => track.stop());
+})
+.then(() => SimpleTest.finish());
+
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/webrtc/MediaEngine.h
+++ b/dom/media/webrtc/MediaEngine.h
@@ -6,16 +6,17 @@
 #define MEDIAENGINE_H_
 
 #include "mozilla/RefPtr.h"
 #include "DOMMediaStream.h"
 #include "MediaStreamGraph.h"
 #include "MediaTrackConstraints.h"
 #include "mozilla/dom/MediaStreamTrackBinding.h"
 #include "mozilla/dom/VideoStreamTrack.h"
+#include "DeviceChangeCallback.h"
 
 namespace mozilla {
 
 namespace dom {
 class Blob;
 } // namespace dom
 
 enum {
@@ -36,17 +37,17 @@ class MediaEngineAudioSource;
 
 enum MediaEngineState {
   kAllocated,
   kStarted,
   kStopped,
   kReleased
 };
 
-class MediaEngine
+class MediaEngine : public DeviceChangeCallback
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngine)
 
   static const int DEFAULT_VIDEO_FPS = 30;
   static const int DEFAULT_VIDEO_MIN_FPS = 10;
   static const int DEFAULT_43_VIDEO_WIDTH = 640;
   static const int DEFAULT_43_VIDEO_HEIGHT = 480;
@@ -70,16 +71,18 @@ public:
 
   /* Populate an array of audio sources in the nsTArray. Also include devices
    * that are currently unavailable. */
   virtual void EnumerateAudioDevices(dom::MediaSourceEnum,
                                      nsTArray<RefPtr<MediaEngineAudioSource> >*) = 0;
 
   virtual void Shutdown() = 0;
 
+  virtual void SetFakeDeviceChangeEvents() {}
+
 protected:
   virtual ~MediaEngine() {}
 };
 
 /**
  * Video source and friends.
  */
 class MediaEnginePrefs {
@@ -95,16 +98,17 @@ public:
     , mNoiseOn(false)
     , mAec(0)
     , mAgc(0)
     , mNoise(0)
     , mPlayoutDelay(0)
     , mFullDuplex(false)
     , mExtendedFilter(false)
     , mDelayAgnostic(false)
+    , mFakeDeviceChangeEventOn(false)
   {}
 
   int32_t mWidth;
   int32_t mHeight;
   int32_t mFPS;
   int32_t mMinFPS;
   int32_t mFreq; // for test tones (fake:true)
   bool mAecOn;
@@ -112,16 +116,17 @@ public:
   bool mNoiseOn;
   int32_t mAec;
   int32_t mAgc;
   int32_t mNoise;
   int32_t mPlayoutDelay;
   bool mFullDuplex;
   bool mExtendedFilter;
   bool mDelayAgnostic;
+  bool mFakeDeviceChangeEventOn;
 
   // mWidth and/or mHeight may be zero (=adaptive default), so use functions.
 
   int32_t GetWidth(bool aHD = false) const {
     return mWidth? mWidth : (mHeight?
                              (mHeight * GetDefWidth(aHD)) / GetDefHeight(aHD) :
                              GetDefWidth(aHD));
   }
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -121,16 +121,27 @@ MediaEngineWebRTC::MediaEngineWebRTC(Med
   }
 #else
 #ifdef MOZ_WIDGET_GONK
   AsyncLatencyLogger::Get()->AddRef();
 #endif
 #endif
   // XXX
   gFarendObserver = new AudioOutputObserver();
+
+  camera::GetChildAndCall(
+    &camera::CamerasChild::AddDeviceChangeCallback,
+    this);
+}
+
+void
+MediaEngineWebRTC::SetFakeDeviceChangeEvents()
+{
+  camera::GetChildAndCall(
+    &camera::CamerasChild::SetFakeDeviceChangeEvents);
 }
 
 void
 MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
                                          nsTArray<RefPtr<MediaEngineVideoSource> >* aVSources)
 {
   // We spawn threads to handle gUM runnables, so we must protect the member vars
   MutexAutoLock lock(mMutex);
@@ -416,16 +427,21 @@ MediaEngineWebRTC::EnumerateAudioDevices
 }
 
 void
 MediaEngineWebRTC::Shutdown()
 {
   // This is likely paranoia
   MutexAutoLock lock(mMutex);
 
+  if (camera::GetCamerasChildIfExists()) {
+    camera::GetChildAndCall(
+      &camera::CamerasChild::RemoveDeviceChangeCallback, this);
+  }
+
   LOG(("%s", __FUNCTION__));
   // Shutdown all the sources, since we may have dangling references to the
   // sources in nsDOMUserMediaStreams waiting for GC/CC
   for (auto iter = mVideoSources.Iter(); !iter.Done(); iter.Next()) {
     MediaEngineVideoSource* source = iter.UserData();
     if (source) {
       source->Shutdown();
     }
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -566,16 +566,18 @@ private:
 };
 
 class MediaEngineWebRTC : public MediaEngine
 {
   typedef MediaEngine Super;
 public:
   explicit MediaEngineWebRTC(MediaEnginePrefs& aPrefs);
 
+  virtual void SetFakeDeviceChangeEvents() override;
+
   // Clients should ensure to clean-up sources video/audio sources
   // before invoking Shutdown on this class.
   void Shutdown() override;
 
   // Returns whether the host supports duplex audio stream.
   bool SupportsDuplex();
 
   void EnumerateVideoDevices(dom::MediaSourceEnum,
--- a/dom/webidl/MediaDevices.webidl
+++ b/dom/webidl/MediaDevices.webidl
@@ -7,17 +7,18 @@
  * http://dev.w3.org/2011/webrtc/editor/getusermedia.html
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
 [Func="Navigator::HasUserMediaSupport"]
 interface MediaDevices : EventTarget {
-//  attribute EventHandler ondevicechange;
+  [Pref="media.ondevicechange.enabled"]
+  attribute EventHandler ondevicechange;
   MediaTrackSupportedConstraints getSupportedConstraints();
 
   [Throws]
   Promise<sequence<MediaDeviceInfo>> enumerateDevices();
 
   [Throws]
   Promise<MediaStream> getUserMedia(optional MediaStreamConstraints constraints);
 };
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -139,16 +139,23 @@ GPUParent::RecvNewContentImageBridge(End
 }
 
 bool
 GPUParent::RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint)
 {
   return VRManagerParent::CreateForContent(Move(aEndpoint));
 }
 
+bool
+GPUParent::RecvDeallocateLayerTreeId(const uint64_t& aLayersId)
+{
+  CompositorBridgeParent::DeallocateLayerTreeId(aLayersId);
+  return true;
+}
+
 void
 GPUParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (AbnormalShutdown == aWhy) {
     NS_WARNING("Shutting down GPU process early due to a crash!");
     ProcessChild::QuickExit();
   }
 
--- a/gfx/ipc/GPUParent.h
+++ b/gfx/ipc/GPUParent.h
@@ -35,16 +35,17 @@ public:
     Endpoint<PCompositorBridgeParent>&& aEndpoint,
     const CSSToLayoutDeviceScale& aScale,
     const TimeDuration& aVsyncRate,
     const bool& aUseExternalSurface,
     const IntSize& aSurfaceSize) override;
   bool RecvNewContentCompositorBridge(Endpoint<PCompositorBridgeParent>&& aEndpoint) override;
   bool RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
   bool RecvNewContentVRManager(Endpoint<PVRManagerParent>&& aEndpoint) override;
+  bool RecvDeallocateLayerTreeId(const uint64_t& aLayersId) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
 
 private:
   RefPtr<VsyncBridgeParent> mVsyncBridge;
 };
 
 } // namespace gfx
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -499,16 +499,20 @@ GPUProcessManager::AllocateLayerTreeId()
 {
   MOZ_ASSERT(NS_IsMainThread());
   return ++mNextLayerTreeId;
 }
 
 void
 GPUProcessManager::DeallocateLayerTreeId(uint64_t aLayersId)
 {
+  if (mGPUChild) {
+    mGPUChild->SendDeallocateLayerTreeId(aLayersId);
+    return;
+  }
   CompositorBridgeParent::DeallocateLayerTreeId(aLayersId);
 }
 
 void
 GPUProcessManager::RequestNotifyLayerTreeReady(uint64_t aLayersId, CompositorUpdateObserver* aObserver)
 {
   CompositorBridgeParent::RequestNotifyLayerTreeReady(aLayersId, aObserver);
 }
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -48,12 +48,14 @@ parent:
                             TimeDuration vsyncRate,
                             bool useExternalSurface,
                             IntSize surfaceSize);
 
   // Create a new content-process compositor bridge.
   async NewContentCompositorBridge(Endpoint<PCompositorBridgeParent> endpoint);
   async NewContentImageBridge(Endpoint<PImageBridgeParent> endpoint);
   async NewContentVRManager(Endpoint<PVRManagerParent> endpoint);
+
+  async DeallocateLayerTreeId(uint64_t layersId);
 };
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -43,16 +43,17 @@ class nsIWidget;
 
 namespace mozilla {
 
 class CancelableRunnable;
 
 namespace gfx {
 class DrawTarget;
 class GPUProcessManager;
+class GPUParent;
 } // namespace gfx
 
 namespace ipc {
 class Shmem;
 } // namespace ipc
 
 namespace layers {
 
@@ -205,16 +206,17 @@ class CompositorBridgeParent final : pub
                                      public ShadowLayersManager,
                                      public CompositorBridgeParentIPCAllocator,
                                      public ShmemAllocator
 {
   friend class CompositorVsyncScheduler;
   friend class CompositorThreadHolder;
   friend class InProcessCompositorSession;
   friend class gfx::GPUProcessManager;
+  friend class gfx::GPUParent;
 
 public:
   explicit CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
                                   const TimeDuration& aVsyncRate,
                                   bool aUseExternalSurfaceSize,
                                   const gfx::IntSize& aSurfaceSize);
 
   // Must only be called by CompositorBridgeChild. After invoking this, the
new file mode 100644
--- /dev/null
+++ b/ipc/mscom/DispatchForwarder.cpp
@@ -0,0 +1,167 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "mozilla/Move.h"
+#include "mozilla/mscom/DispatchForwarder.h"
+#include "mozilla/mscom/MainThreadInvoker.h"
+
+#include <oleauto.h>
+
+namespace mozilla {
+namespace mscom {
+
+/* static */ HRESULT
+DispatchForwarder::Create(IInterceptor* aInterceptor,
+                          STAUniquePtr<IDispatch>& aTarget, IUnknown** aOutput)
+{
+  MOZ_ASSERT(aInterceptor && aOutput);
+  if (!aOutput) {
+    return E_INVALIDARG;
+  }
+  *aOutput = nullptr;
+  if (!aInterceptor) {
+    return E_INVALIDARG;
+  }
+  DispatchForwarder* forwarder = new DispatchForwarder(aInterceptor, aTarget);
+  HRESULT hr = forwarder->QueryInterface(IID_IDispatch, (void**) aOutput);
+  forwarder->Release();
+  return hr;
+}
+
+DispatchForwarder::DispatchForwarder(IInterceptor* aInterceptor,
+                                     STAUniquePtr<IDispatch>& aTarget)
+  : mRefCnt(1)
+  , mInterceptor(aInterceptor)
+  , mTarget(Move(aTarget))
+{
+}
+
+DispatchForwarder::~DispatchForwarder()
+{
+}
+
+HRESULT
+DispatchForwarder::QueryInterface(REFIID riid, void** ppv)
+{
+  if (!ppv) {
+    return E_INVALIDARG;
+  }
+
+  // Since this class implements a tearoff, any interfaces that are not
+  // IDispatch must be routed to the original object's QueryInterface.
+  // This is especially important for IUnknown since COM uses that interface
+  // to determine object identity.
+  if (riid != IID_IDispatch) {
+    return mInterceptor->QueryInterface(riid, ppv);
+  }
+
+  IUnknown* punk = static_cast<IDispatch*>(this);
+  *ppv = punk;
+  if (!punk) {
+    return E_NOINTERFACE;
+  }
+
+  punk->AddRef();
+  return S_OK;
+}
+
+ULONG
+DispatchForwarder::AddRef()
+{
+  return (ULONG) InterlockedIncrement((LONG*)&mRefCnt);
+}
+
+ULONG
+DispatchForwarder::Release()
+{
+  ULONG newRefCnt = (ULONG) InterlockedDecrement((LONG*)&mRefCnt);
+  if (newRefCnt == 0) {
+    delete this;
+  }
+  return newRefCnt;
+}
+
+HRESULT
+DispatchForwarder::GetTypeInfoCount(UINT *pctinfo)
+{
+  if (!pctinfo) {
+    return E_INVALIDARG;
+  }
+  *pctinfo = 1;
+  return S_OK;
+}
+
+HRESULT
+DispatchForwarder::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
+{
+  // ITypeInfo as implemented by COM is apartment-neutral, so we don't need
+  // to wrap it (yay!)
+  if (mTypeInfo) {
+    *ppTInfo = mTypeInfo.get();
+    mTypeInfo->AddRef();
+    return S_OK;
+  }
+  HRESULT hr = E_UNEXPECTED;
+  auto fn = [&]() -> void {
+    hr = mTarget->GetTypeInfo(iTInfo, lcid, ppTInfo);
+  };
+  MainThreadInvoker invoker;
+  if (!invoker.Invoke(NS_NewRunnableFunction(fn))) {
+    return E_UNEXPECTED;
+  }
+  if (FAILED(hr)) {
+    return hr;
+  }
+  mTypeInfo = *ppTInfo;
+  return hr;
+}
+
+HRESULT
+DispatchForwarder::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
+                                 LCID lcid, DISPID *rgDispId)
+{
+  HRESULT hr = E_UNEXPECTED;
+  auto fn = [&]() -> void {
+    hr = mTarget->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
+  };
+  MainThreadInvoker invoker;
+  if (!invoker.Invoke(NS_NewRunnableFunction(fn))) {
+    return E_UNEXPECTED;
+  }
+  return hr;
+}
+
+HRESULT
+DispatchForwarder::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
+                          WORD wFlags, DISPPARAMS *pDispParams,
+                          VARIANT *pVarResult, EXCEPINFO *pExcepInfo,
+                          UINT *puArgErr)
+{
+  HRESULT hr;
+  if (!mInterface) {
+    if (!mTypeInfo) {
+      return E_UNEXPECTED;
+    }
+    TYPEATTR* typeAttr = nullptr;
+    hr = mTypeInfo->GetTypeAttr(&typeAttr);
+    if (FAILED(hr)) {
+      return hr;
+    }
+    hr = mInterceptor->QueryInterface(typeAttr->guid,
+                                      (void**)getter_AddRefs(mInterface));
+    mTypeInfo->ReleaseTypeAttr(typeAttr);
+    if (FAILED(hr)) {
+      return hr;
+    }
+  }
+  // We don't invoke IDispatch on the target, but rather on the interceptor!
+  hr = ::DispInvoke(mInterface.get(), mTypeInfo, dispIdMember, wFlags,
+                    pDispParams, pVarResult, pExcepInfo, puArgErr);
+  return hr;
+}
+
+} // namespace mscom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/ipc/mscom/DispatchForwarder.h
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 mozilla_mscom_DispatchForwarder_h
+#define mozilla_mscom_DispatchForwarder_h
+
+#include <oaidl.h>
+
+#include "mozilla/mscom/Interceptor.h"
+#include "mozilla/mscom/Ptr.h"
+
+namespace mozilla {
+namespace mscom {
+
+class DispatchForwarder : public IDispatch
+{
+public:
+  static HRESULT Create(IInterceptor* aInterceptor,
+                        STAUniquePtr<IDispatch>& aTarget, IUnknown** aOutput);
+
+  // IUnknown
+  STDMETHODIMP QueryInterface(REFIID riid, void** ppv) override;
+  STDMETHODIMP_(ULONG) AddRef() override;
+  STDMETHODIMP_(ULONG) Release() override;
+
+  // IDispatch
+  STDMETHODIMP GetTypeInfoCount(
+      /* [out] */ __RPC__out UINT *pctinfo) override;
+
+  STDMETHODIMP GetTypeInfo(
+      /* [in] */ UINT iTInfo,
+      /* [in] */ LCID lcid,
+      /* [out] */ __RPC__deref_out_opt ITypeInfo **ppTInfo) override;
+
+  STDMETHODIMP GetIDsOfNames(
+      /* [in] */ __RPC__in REFIID riid,
+      /* [size_is][in] */ __RPC__in_ecount_full(cNames) LPOLESTR *rgszNames,
+      /* [range][in] */ __RPC__in_range(0,16384) UINT cNames,
+      /* [in] */ LCID lcid,
+      /* [size_is][out] */ __RPC__out_ecount_full(cNames) DISPID *rgDispId)
+    override;
+
+  STDMETHODIMP Invoke(
+      /* [annotation][in] */
+      _In_  DISPID dispIdMember,
+      /* [annotation][in] */
+      _In_  REFIID riid,
+      /* [annotation][in] */
+      _In_  LCID lcid,
+      /* [annotation][in] */
+      _In_  WORD wFlags,
+      /* [annotation][out][in] */
+      _In_  DISPPARAMS *pDispParams,
+      /* [annotation][out] */
+      _Out_opt_  VARIANT *pVarResult,
+      /* [annotation][out] */
+      _Out_opt_  EXCEPINFO *pExcepInfo,
+      /* [annotation][out] */
+      _Out_opt_  UINT *puArgErr) override;
+
+private:
+  DispatchForwarder(IInterceptor* aInterceptor,
+                    STAUniquePtr<IDispatch>& aTarget);
+  ~DispatchForwarder();
+
+private:
+  ULONG mRefCnt;
+  RefPtr<IInterceptor> mInterceptor;
+  STAUniquePtr<IDispatch> mTarget;
+  RefPtr<ITypeInfo> mTypeInfo;
+  RefPtr<IUnknown> mInterface;
+};
+
+} // namespace mscom
+} // namespace mozilla
+
+#endif // mozilla_mscom_DispatchForwarder_h
+
--- a/ipc/mscom/Interceptor.cpp
+++ b/ipc/mscom/Interceptor.cpp
@@ -3,16 +3,17 @@
 /* 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/. */
 
 #define INITGUID
 #include "mozilla/mscom/Interceptor.h"
 #include "mozilla/mscom/InterceptorLog.h"
 
+#include "mozilla/mscom/DispatchForwarder.h"
 #include "mozilla/mscom/MainThreadInvoker.h"
 #include "mozilla/mscom/Registration.h"
 #include "mozilla/mscom/utils.h"
 #include "MainThreadUtils.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/DebugOnly.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
@@ -269,16 +270,27 @@ HRESULT
 Interceptor::ThreadSafeQueryInterface(REFIID aIid, IUnknown** aOutInterface)
 {
   if (aIid == IID_IInterceptor) {
     *aOutInterface = static_cast<IInterceptor*>(this);
     (*aOutInterface)->AddRef();
     return S_OK;
   }
 
+  if (aIid == IID_IDispatch) {
+    STAUniquePtr<IDispatch> disp;
+    IDispatch* rawDisp = nullptr;
+    HRESULT hr = QueryInterfaceTarget(aIid, (void**)&rawDisp);
+    if (FAILED(hr)) {
+      return hr;
+    }
+    disp.reset(rawDisp);
+    return DispatchForwarder::Create(this, disp, aOutInterface);
+  }
+
   return GetInterceptorForIID(aIid, (void**)aOutInterface);
 }
 
 ULONG
 Interceptor::AddRef()
 {
   return WeakReferenceSupport::AddRef();
 }
--- a/ipc/mscom/moz.build
+++ b/ipc/mscom/moz.build
@@ -2,16 +2,17 @@
 # vim: set filetype=python:
 # 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/.
 
 EXPORTS.mozilla.mscom += [
     'COMApartmentRegion.h',
     'COMPtrHolder.h',
+    'DispatchForwarder.h',
     'EnsureMTA.h',
     'Interceptor.h',
     'InterceptorLog.h',
     'MainThreadHandoff.h',
     'MainThreadInvoker.h',
     'MainThreadRuntime.h',
     'ProxyStream.h',
     'Ptr.h',
@@ -23,16 +24,17 @@ EXPORTS.mozilla.mscom += [
 SOURCES += [
     'Interceptor.cpp',
     'Registration.cpp',
     'Utils.cpp',
     'WeakRef.cpp',
 ]
 
 UNIFIED_SOURCES += [
+    'DispatchForwarder.cpp',
     'EnsureMTA.cpp',
     'InterceptorLog.cpp',
     'MainThreadHandoff.cpp',
     'MainThreadInvoker.cpp',
     'MainThreadRuntime.cpp',
     'ProxyStream.cpp',
 ]
 
--- a/layout/generic/nsAutoCopyListener.h
+++ b/layout/generic/nsAutoCopyListener.h
@@ -11,37 +11,42 @@
 #include "mozilla/Attributes.h"
 
 class nsAutoCopyListener final : public nsISelectionListener
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISELECTIONLISTENER
 
+  explicit nsAutoCopyListener(int16_t aClipboardID)
+    : mCachedClipboard(aClipboardID)
+  {}
+
   void Listen(nsISelectionPrivate *aSelection)
   {
       NS_ASSERTION(aSelection, "Null selection passed to Listen()");
       aSelection->AddSelectionListener(this);
   }
 
-  static nsAutoCopyListener* GetInstance()
+  static nsAutoCopyListener* GetInstance(int16_t aClipboardID)
   {
     if (!sInstance) {
-      sInstance = new nsAutoCopyListener();
+      sInstance = new nsAutoCopyListener(aClipboardID);
 
       NS_ADDREF(sInstance);
     }
 
     return sInstance;
   }
 
   static void Shutdown()
   {
     NS_IF_RELEASE(sInstance);
   }
 
 private:
   ~nsAutoCopyListener() {}
 
   static nsAutoCopyListener* sInstance;
+  int16_t mCachedClipboard;
 };
 
 #endif
--- a/layout/generic/nsFrameSelection.h
+++ b/layout/generic/nsFrameSelection.h
@@ -368,17 +368,17 @@ public:
   nsresult ScrollSelectionIntoView(mozilla::SelectionType aSelectionType,
                                    SelectionRegion aRegion,
                                    int16_t aFlags) const;
 
   /** RepaintSelection repaints the selected frames that are inside the selection
    *  specified by aSelectionType.
    * @param aSelectionType The selection type what you want to repaint.
    */
-  nsresult RepaintSelection(mozilla::SelectionType aSelectionType) const;
+  nsresult RepaintSelection(mozilla::SelectionType aSelectionType);
 
   /** GetFrameForNodeOffset given a node and its child offset, return the nsIFrame and
    *  the offset into that frame. 
    * @param aNode input parameter for the node to look at
    * @param aOffset offset into above node.
    * @param aReturnOffset will contain offset into frame.
    */
   virtual nsIFrame* GetFrameForNodeOffset(nsIContent*        aNode,
@@ -676,16 +676,20 @@ private:
 
   uint32_t     GetBatching() const {return mBatching; }
   bool         GetNotifyFrames() const { return mNotifyFrames; }
   void         SetDirty(bool aDirty=true){if (mBatching) mChangesDuringBatching = aDirty;}
 
   // nsFrameSelection may get deleted when calling this,
   // so remember to use nsCOMPtr when needed.
   nsresult     NotifySelectionListeners(mozilla::SelectionType aSelectionType);
+  // Update the selection cache on repaint when the
+  // selection being repainted is not empty.
+  nsresult     UpdateSelectionCacheOnRepaintSelection(mozilla::dom::
+                                                      Selection* aSel);
 
   RefPtr<mozilla::dom::Selection>
     mDomSelections[mozilla::kPresentSelectionTypeCount];
 
   // Table selection support.
   nsITableCellLayout* GetCellLayout(nsIContent *aCellContent) const;
 
   nsresult SelectBlockOfCells(nsIContent *aStartNode, nsIContent *aEndNode);
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -79,16 +79,17 @@ static NS_DEFINE_CID(kFrameTraversalCID,
 #include "mozilla/dom/SelectionBinding.h"
 #include "mozilla/AsyncEventDispatcher.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/layers/ScrollInputMethods.h"
 #include "nsViewManager.h"
 
 #include "nsIEditor.h"
 #include "nsIHTMLEditor.h"
+#include "nsFocusManager.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using mozilla::layers::ScrollInputMethod;
 
 //#define DEBUG_TABLE 1
 
 static bool IsValidSelectionPoint(nsFrameSelection *aFrameSel, nsINode *aNode);
@@ -544,26 +545,32 @@ nsFrameSelection::nsFrameSelection()
   mHint = CARET_ASSOCIATE_BEFORE;
   mCaretBidiLevel = BIDI_LEVEL_UNDEFINED;
   mKbdBidiLevel = NSBIDI_LTR;
 
   mDragSelectingCells = false;
   mSelectingTableCellMode = 0;
   mSelectedCellIndex = 0;
 
+  nsAutoCopyListener *autoCopy = nullptr;
+  // On macOS, cache the current selection to send to osx service menu.
+#ifdef XP_MACOSX
+  autoCopy = nsAutoCopyListener::GetInstance(nsIClipboard::kSelectionCache);
+#endif
+
   // Check to see if the autocopy pref is enabled
   //   and add the autocopy listener if it is
   if (Preferences::GetBool("clipboard.autocopy")) {
-    nsAutoCopyListener *autoCopy = nsAutoCopyListener::GetInstance();
-
-    if (autoCopy) {
-      int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
-      if (mDomSelections[index]) {
-        autoCopy->Listen(mDomSelections[index]);
-      }
+    autoCopy = nsAutoCopyListener::GetInstance(nsIClipboard::kSelectionClipboard);
+  }
+
+  if (autoCopy) {
+    int8_t index = GetIndexFromSelectionType(SelectionType::eNormal);
+    if (mDomSelections[index]) {
+      autoCopy->Listen(mDomSelections[index]);
     }
   }
 
   mDisplaySelection = nsISelectionController::SELECTION_OFF;
   mSelectionChangeReason = nsISelectionListener::NO_REASON;
 
   mDelayedMouseEventValid = false;
   // These values are not used since they are only valid when
@@ -1953,24 +1960,35 @@ nsFrameSelection::ScrollSelectionIntoVie
   // flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
   return mDomSelections[index]->ScrollIntoView(aRegion,
                                                verticalScroll,
                                                nsIPresShell::ScrollAxis(),
                                                flags);
 }
 
 nsresult
-nsFrameSelection::RepaintSelection(SelectionType aSelectionType) const
+nsFrameSelection::RepaintSelection(SelectionType aSelectionType)
 {
   int8_t index = GetIndexFromSelectionType(aSelectionType);
   if (index < 0)
     return NS_ERROR_INVALID_ARG;
   if (!mDomSelections[index])
     return NS_ERROR_NULL_POINTER;
   NS_ENSURE_STATE(mShell);
+
+// On macOS, update the selection cache to the new active selection
+// aka the current selection.
+#ifdef XP_MACOSX
+  nsFocusManager* fm = nsFocusManager::GetFocusManager();
+  // Check an active window exists otherwise there cannot be a current selection
+  // and that it's a normal selection.
+  if (fm->GetActiveWindow() && aSelectionType == SelectionType::eNormal) {
+    UpdateSelectionCacheOnRepaintSelection(mDomSelections[index]);
+  }
+#endif
   return mDomSelections[index]->Repaint(mShell->GetPresContext());
 }
  
 nsIFrame*
 nsFrameSelection::GetFrameForNodeOffset(nsIContent*        aNode,
                                         int32_t            aOffset,
                                         CaretAssociateHint aHint,
                                         int32_t*           aReturnOffset) const
@@ -6462,43 +6480,100 @@ NS_IMPL_ISUPPORTS(nsAutoCopyListener, ns
  *   selections (or simple clicks, which currently cause a selection
  *   notification, regardless of if they're in the document which currently has
  *   selection!) don't lose the contents of the ``application''?  Or should we
  *   just put some intelligence in the ``is this a real selection?'' code to
  *   protect our selection against clicks in other documents that don't create
  *   selections?
  * - maybe we should just never clear the X clipboard?  That would make this 
  *   problem just go away, which is very tempting.
+ *
+ * On macOS,
+ * nsIClipboard::kSelectionCache is the flag for current selection cache.
+ * Set the current selection cache on the parent process in
+ * widget cocoa nsClipboard whenever selection changes.
  */
 
 NS_IMETHODIMP
 nsAutoCopyListener::NotifySelectionChanged(nsIDOMDocument *aDoc,
                                            nsISelection *aSel, int16_t aReason)
 {
+  if (mCachedClipboard == nsIClipboard::kSelectionCache) {
+    nsFocusManager* fm = nsFocusManager::GetFocusManager();
+    // If no active window, do nothing because a current selection changed
+    // cannot occur unless it is in the active window.
+    if (!fm->GetActiveWindow()) {
+      return NS_OK;
+    }
+  }
+
   if (!(aReason & nsISelectionListener::MOUSEUP_REASON   || 
         aReason & nsISelectionListener::SELECTALL_REASON ||
         aReason & nsISelectionListener::KEYPRESS_REASON))
     return NS_OK; //dont care if we are still dragging
 
   bool collapsed;
   if (!aDoc || !aSel ||
       NS_FAILED(aSel->GetIsCollapsed(&collapsed)) || collapsed) {
 #ifdef DEBUG_CLIPBOARD
     fprintf(stderr, "CLIPBOARD: no selection/collapsed selection\n");
 #endif
+    // If on macOS, clear the current selection transferable cached
+    // on the parent process (nsClipboard) when the selection is empty.
+    if (mCachedClipboard == nsIClipboard::kSelectionCache) {
+      return nsCopySupport::ClearSelectionCache();
+    }
     /* clear X clipboard? */
     return NS_OK;
   }
 
   nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDoc);
   NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
 
   // call the copy code
   return nsCopySupport::HTMLCopy(aSel, doc,
-                                 nsIClipboard::kSelectionClipboard, false);
+                                 mCachedClipboard, false);
+}
+
+/**
+ * See Bug 1288453.
+ *
+ * Update the selection cache on repaint to handle when a pre-existing
+ * selection becomes active aka the current selection.
+ *
+ * 1. Change the current selection by click n dragging another selection.
+ *   - Make a selection on content page. Make a selection in a text editor.
+ *   - You can click n drag the content selection to make it active again.
+ * 2. Change the current selection when switching to a tab with a selection.
+ *   - Make selection in tab.
+ *   - Switching tabs will make its respective selection active.
+ *
+ * Therefore, we only update the selection cache on a repaint
+ * if the current selection being repainted is not an empty selection.
+ *
+ * If the current selection is empty. The current selection cache
+ * would be cleared by nsAutoCopyListener::NotifySelectionChanged.
+ */
+nsresult
+nsFrameSelection::UpdateSelectionCacheOnRepaintSelection(Selection* aSel)
+{
+  nsIPresShell* ps = aSel->GetPresShell();
+  if (!ps) {
+    return NS_OK;
+  }
+  nsCOMPtr<nsIDocument> aDoc = ps->GetDocument();
+
+  bool collapsed;
+  if (aDoc && aSel &&
+      NS_SUCCEEDED(aSel->GetIsCollapsed(&collapsed)) && !collapsed) {
+    return nsCopySupport::HTMLCopy(aSel, aDoc,
+                                   nsIClipboard::kSelectionCache, false);
+  }
+
+  return NS_OK;
 }
 
 // SelectionChangeListener
 
 SelectionChangeListener::RawRangeData::RawRangeData(const nsRange* aRange)
 {
   mozilla::ErrorResult rv;
   mStartParent = aRange->GetStartContainer(rv);
--- a/media/webrtc/trunk/webrtc/modules/video_capture/include/video_capture.h
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/include/video_capture.h
@@ -16,27 +16,45 @@
 #include "webrtc/modules/video_capture/include/video_capture_defines.h"
 
 #if defined(ANDROID) && !defined(WEBRTC_GONK)
 #include <jni.h>
 #endif
 
 namespace webrtc {
 
+class VideoInputFeedBack
+{
+public:
+    virtual void OnDeviceChange() = 0;
+protected:
+    virtual ~VideoInputFeedBack(){}
+};
+
 #if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD) && !defined(WEBRTC_GONK)
   int32_t SetCaptureAndroidVM(JavaVM* javaVM);
 #endif
 
 class VideoCaptureModule: public RefCountedModule {
  public:
   // Interface for receiving information about available camera devices.
   class DeviceInfo {
    public:
     virtual uint32_t NumberOfDevices() = 0;
     virtual int32_t Refresh() = 0;
+    virtual void DeviceChange() {
+     if (_inputCallBack)
+      _inputCallBack->OnDeviceChange();
+    }
+    virtual void RegisterVideoInputFeedBack(VideoInputFeedBack& callBack) {
+     _inputCallBack = &callBack;
+    }
+    virtual void DeRegisterVideoInputFeedBack() {
+     _inputCallBack = NULL;
+    }
 
     // Returns the available capture devices.
     // deviceNumber   - Index of capture device.
     // deviceNameUTF8 - Friendly name of the capture device.
     // deviceUniqueIdUTF8 - Unique name of the capture device if it exist.
     //                      Otherwise same as deviceNameUTF8.
     // productUniqueIdUTF8 - Unique product id if it exist.
     //                       Null terminated otherwise.
@@ -77,16 +95,18 @@ class VideoCaptureModule: public RefCoun
     virtual int32_t DisplayCaptureSettingsDialogBox(
         const char* deviceUniqueIdUTF8,
         const char* dialogTitleUTF8,
         void* parentWindow,
         uint32_t positionX,
         uint32_t positionY) = 0;
 
     virtual ~DeviceInfo() {}
+   private:
+    VideoInputFeedBack* _inputCallBack = NULL;
   };
 
   class VideoCaptureEncodeInterface {
    public:
     virtual int32_t ConfigureEncoder(const VideoCodec& codec,
                                      uint32_t maxPayloadSize) = 0;
     // Inform the encoder about the new target bit rate.
     //  - newBitRate       : New target bit rate in Kbit/s.
--- a/media/webrtc/trunk/webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info.mm
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info.mm
@@ -19,21 +19,23 @@ namespace webrtc
 namespace videocapturemodule
 {
 
 VideoCaptureMacAVFoundationInfo::VideoCaptureMacAVFoundationInfo(const int32_t id) :
     DeviceInfoImpl(id)
 {
     nsAutoreleasePool localPool;
     _captureInfo = [[VideoCaptureMacAVFoundationInfoObjC alloc] init];
+    [_captureInfo registerOwner:this];
 }
 
 VideoCaptureMacAVFoundationInfo::~VideoCaptureMacAVFoundationInfo()
 {
     nsAutoreleasePool localPool;
+    [_captureInfo registerOwner:nil];
     [_captureInfo release];
 }
 
 int32_t VideoCaptureMacAVFoundationInfo::Init()
 {
 
     return 0;
 }
--- a/media/webrtc/trunk/webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info_objc.h
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info_objc.h
@@ -21,16 +21,19 @@
 
 #include "webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info.h"
 #include "webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_utility.h"
 
 @interface VideoCaptureMacAVFoundationInfoObjC : NSObject{
     bool                                _OSSupportedInfo;
     NSArray*                            _captureDevicesInfo;
     int                                    _captureDeviceCountInfo;
+    NSArray*                            _observers;
+    NSLock*                             _lock;
+    webrtc::videocapturemodule::VideoCaptureMacAVFoundationInfo* _owner;
 
 }
 
 /**************************************************************************
  *
  *   The following functions are considered to be private
  *
  ***************************************************************************/
@@ -41,16 +44,18 @@
 
 
 /**************************************************************************
  *
  *   The following functions are considered to be public and called by VideoCaptureMacAVFoundationInfo class
  *
  ***************************************************************************/
 
+- (void)registerOwner:(webrtc::videocapturemodule::VideoCaptureMacAVFoundationInfo*)owner;
+
 - (NSNumber*)getCaptureDeviceCount;
 
 - (NSNumber*)getCaptureCapabilityCount:(const char*)uniqueId;
 
 - (NSNumber*)getCaptureCapability:(const char*)uniqueId
                      CapabilityId:(uint32_t)capabilityId
                  Capability_width:(int32_t*)width
                 Capability_height:(int32_t*)height
--- a/media/webrtc/trunk/webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info_objc.mm
+++ b/media/webrtc/trunk/webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info_objc.mm
@@ -10,16 +10,17 @@
 
 #pragma mark **** imports/includes
 
 #import "webrtc/modules/video_capture/mac/avfoundation/video_capture_avfoundation_info_objc.h"
 
 #include "webrtc/system_wrappers/interface/trace.h"
 
 using namespace webrtc;
+using namespace videocapturemodule;
 
 #pragma mark **** hidden class interface
 
 @implementation VideoCaptureMacAVFoundationInfoObjC
 
 // ****************** over-written OS methods ***********************
 #pragma mark **** over-written OS methods
 
@@ -33,22 +34,35 @@ using namespace webrtc;
     }
     else
     {
         return nil;
     }
     return self;
 }
 
+- (void)registerOwner:(VideoCaptureMacAVFoundationInfo*)owner {
+    [_lock lock];
+    _owner = owner;
+    [_lock unlock];
+}
+
 /// ***** Objective-C. Similar to C++ destructor
 /// ***** Returns nothing
 - (void)dealloc {
 
     [_captureDevicesInfo release];
 
+    // Remove Observers
+    NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter];
+    for (id observer in _observers)
+        [notificationCenter removeObserver:observer];
+    [_observers release];
+    [_lock release];
+
     [super dealloc];
 }
 
 // ****************** public methods ******************
 #pragma mark **** public method implementations
 
 /// ***** Creates a message box with Cocoa framework
 /// ***** Returns 0 on success, -1 otherwise.
@@ -218,16 +232,43 @@ using namespace webrtc;
     if(NO == _OSSupportedInfo)
     {
         return [NSNumber numberWithInt:0];
     }
 
     _captureDeviceCountInfo = 0;
     [self getCaptureDevices];
 
+    _lock = [[NSLock alloc] init];
+
+    //register device connected / disconnected event
+    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+
+    id deviceWasConnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification
+        object:nil
+        queue:[NSOperationQueue mainQueue]
+        usingBlock:^(NSNotification *note) {
+            [_lock lock];
+            if(_owner)
+                _owner->DeviceChange();
+            [_lock unlock];
+        }];
+
+    id deviceWasDisconnectedObserver = [notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification
+        object:nil
+        queue:[NSOperationQueue mainQueue]
+        usingBlock:^(NSNotification *note) {
+            [_lock lock];
+            if(_owner)
+                _owner->DeviceChange();
+            [_lock unlock];
+        }];
+
+    _observers = [[NSArray alloc] initWithObjects:deviceWasConnectedObserver, deviceWasDisconnectedObserver, nil];
+
     return [NSNumber numberWithInt:0];
 }
 
 // ***** Checks to see if the AVCaptureSession framework is available in the OS
 // ***** If it is not, isOSSupprted = NO
 // ***** Throughout the rest of the class isOSSupprted is checked and functions
 // ***** are/aren't called depending
 // ***** The user can use weak linking to the AVFoundation framework and run on older
--- a/media/webrtc/trunk/webrtc/video_engine/include/vie_capture.h
+++ b/media/webrtc/trunk/webrtc/video_engine/include/vie_capture.h
@@ -22,16 +22,27 @@
 #include "webrtc/common_video/interface/i420_video_frame.h"
 #include "webrtc/common_video/rotation.h"
 
 namespace webrtc {
 
 class VideoEngine;
 class VideoCaptureModule;
 
+// The observer is registered using RegisterInputObserver() and
+// deregistered using DeregisterInputObserver().
+class WEBRTC_DLLEXPORT ViEInputObserver {
+ public:
+  // This method is called if an input device is connected or disconnected .
+  virtual void DeviceChange() = 0;
+
+ protected:
+  virtual ~ViEInputObserver() {}
+};
+
 // This structure describes one set of the supported capabilities for a capture
 // device.
 struct CaptureCapability {
   unsigned int width;
   unsigned int height;
   unsigned int maxFPS;
   RawVideoType rawType;
   VideoCodecType codecType;
@@ -211,19 +222,23 @@ class WEBRTC_DLLEXPORT ViECapture {
   // Enables brightness alarm detection and the brightness alarm callback.
   virtual int EnableBrightnessAlarm(const int capture_id,
                                     const bool enable) = 0;
 
   // Registers an instance of a user implementation of the ViECaptureObserver.
   virtual int RegisterObserver(const int capture_id,
                                ViECaptureObserver& observer) = 0;
 
+  virtual int RegisterInputObserver(ViEInputObserver* observer) = 0;
+
   // Removes an already registered instance of ViECaptureObserver.
   virtual int DeregisterObserver(const int capture_id) = 0;
 
+  virtual int DeregisterInputObserver() = 0;
+
  protected:
   ViECapture() {}
   virtual ~ViECapture() {}
 };
 
 }  // namespace webrtc
 
 #endif  // WEBRTC_VIDEO_ENGINE_INCLUDE_VIE_CAPTURE_H_
--- a/media/webrtc/trunk/webrtc/video_engine/vie_capture_impl.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_capture_impl.cc
@@ -368,16 +368,24 @@ int ViECaptureImpl::RegisterObserver(con
   }
   if (vie_capture->RegisterObserver(&observer) != 0) {
     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
     return -1;
   }
   return 0;
 }
 
+int ViECaptureImpl::RegisterInputObserver(ViEInputObserver* observer) {
+  if (shared_data_->input_manager()->RegisterObserver(observer) != 0) {
+    shared_data_->SetLastError(kViECaptureDeviceUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
 int ViECaptureImpl::DeregisterObserver(const int capture_id) {
   ViEInputManagerScoped is(*(shared_data_->input_manager()));
   ViECapturer* vie_capture = is.Capture(capture_id);
   if (!vie_capture) {
     shared_data_->SetLastError(kViECaptureDeviceDoesNotExist);
     return -1;
   }
   if (!vie_capture->IsObserverRegistered()) {
@@ -387,9 +395,17 @@ int ViECaptureImpl::DeregisterObserver(c
 
   if (vie_capture->DeRegisterObserver() != 0) {
     shared_data_->SetLastError(kViECaptureDeviceUnknownError);
     return -1;
   }
   return 0;
 }
 
+int ViECaptureImpl::DeregisterInputObserver() {
+  if (shared_data_->input_manager()->DeRegisterObserver() != 0) {
+    shared_data_->SetLastError(kViECaptureDeviceUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
 }  // namespace webrtc
--- a/media/webrtc/trunk/webrtc/video_engine/vie_capture_impl.h
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_capture_impl.h
@@ -61,17 +61,19 @@ class ViECaptureImpl
     const char* unique_idUTF8, const unsigned int unique_idUTF8Length,
     const char* dialog_title, void* parent_window = NULL,
     const unsigned int x = 200, const unsigned int y = 200);
   virtual int GetOrientation(const char* unique_idUTF8,
                              VideoRotation& orientation);
   virtual int EnableBrightnessAlarm(const int capture_id, const bool enable);
   virtual int RegisterObserver(const int capture_id,
                                ViECaptureObserver& observer);
+  virtual int RegisterInputObserver(ViEInputObserver* observer);
   virtual int DeregisterObserver(const int capture_id);
+  virtual int DeregisterInputObserver();
 
  protected:
   explicit ViECaptureImpl(ViESharedData* shared_data);
   virtual ~ViECaptureImpl();
 
  private:
   ViESharedData* shared_data_;
 };
--- a/media/webrtc/trunk/webrtc/video_engine/vie_input_manager.cc
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_input_manager.cc
@@ -27,16 +27,18 @@
 
 namespace webrtc {
 
 ViEInputManager::ViEInputManager(const int engine_id, const Config& config)
     : config_(config),
       engine_id_(engine_id),
       map_cs_(CriticalSectionWrapper::CreateCriticalSection()),
       device_info_cs_(CriticalSectionWrapper::CreateCriticalSection()),
+      observer_cs_(CriticalSectionWrapper::CreateCriticalSection()),
+      observer_(NULL),
       vie_frame_provider_map_(),
       capture_device_info_(NULL),
       module_process_thread_(NULL) {
   for (int idx = 0; idx < kViEMaxCaptureDevices; idx++) {
     free_capture_device_id_[idx] = true;
   }
 }
 
@@ -329,16 +331,23 @@ ViECapturer* ViEInputManager::ViECapture
         capture_id <= kViECaptureIdBase + kViEMaxCaptureDevices)) {
     LOG(LS_ERROR) << "Capture device doesn't exist " << capture_id << ".";
     return NULL;
   }
 
   return static_cast<ViECapturer*>(ViEFrameProvider(capture_id));
 }
 
+void ViEInputManager::OnDeviceChange() {
+  CriticalSectionScoped cs(observer_cs_.get());
+  if (observer_) {
+    observer_->DeviceChange();
+  }
+}
+
 // Create different DeviceInfo by _config;
 VideoCaptureModule::DeviceInfo* ViEInputManager::GetDeviceInfo() {
   CaptureDeviceType type = config_.Get<CaptureDeviceInfo>().type;
 
   if (capture_device_info_ == NULL) {
     switch (type) {
       case CaptureDeviceType::Screen:
       case CaptureDeviceType::Application:
@@ -356,16 +365,45 @@ VideoCaptureModule::DeviceInfo* ViEInput
         break;
       default:
         // Don't try to build anything for unknown/unsupported types
         break;
     }
   }
   return capture_device_info_;
 }
+
+int32_t ViEInputManager::RegisterObserver(ViEInputObserver* observer) {
+  {
+    CriticalSectionScoped cs(observer_cs_.get());
+    if (observer_) {
+      LOG_F(LS_ERROR) << "Observer already registered.";
+      return -1;
+    }
+    observer_ = observer;
+  }
+
+  if (!GetDeviceInfo())
+    return -1;
+
+  if (capture_device_info_ != NULL)
+    capture_device_info_->RegisterVideoInputFeedBack(*this);
+
+  return 0;
+}
+
+int32_t ViEInputManager::DeRegisterObserver() {
+  if (capture_device_info_ != NULL)
+    capture_device_info_->DeRegisterVideoInputFeedBack();
+
+  CriticalSectionScoped cs(observer_cs_.get());
+  observer_ = NULL;
+  return 0;
+}
+
 ViEInputManagerScoped::ViEInputManagerScoped(
     const ViEInputManager& vie_input_manager)
     : ViEManagerScopedBase(vie_input_manager) {
 }
 
 ViECapturer* ViEInputManagerScoped::Capture(int capture_id) const {
   return static_cast<const ViEInputManager*>(vie_manager_)->ViECapturePtr(
       capture_id);
--- a/media/webrtc/trunk/webrtc/video_engine/vie_input_manager.h
+++ b/media/webrtc/trunk/webrtc/video_engine/vie_input_manager.h
@@ -27,17 +27,18 @@ namespace webrtc {
 class Config;
 class CriticalSectionWrapper;
 class ProcessThread;
 class RWLockWrapper;
 class ViECapturer;
 class ViEExternalCapture;
 class VoiceEngine;
 
-class ViEInputManager : private ViEManagerBase {
+class ViEInputManager : private ViEManagerBase,
+                        protected VideoInputFeedBack {
   friend class ViEInputManagerScoped;
  public:
   ViEInputManager(int engine_id, const Config& config);
   ~ViEInputManager();
 
   void SetModuleProcessThread(ProcessThread* module_process_thread);
 
   // Returns number of capture devices.
@@ -73,18 +74,22 @@ class ViEInputManager : private ViEManag
   int CreateCaptureDevice(const char* device_unique_idUTF8,
                           const uint32_t device_unique_idUTF8Length,
                           int& capture_id);
   int CreateCaptureDevice(VideoCaptureModule* capture_module,
                           int& capture_id);
   int CreateExternalCaptureDevice(ViEExternalCapture*& external_capture,
                                   int& capture_id);
   int DestroyCaptureDevice(int capture_id);
+  int32_t RegisterObserver(ViEInputObserver* observer);
+  int32_t DeRegisterObserver();
  protected:
   VideoCaptureModule::DeviceInfo* GetDeviceInfo();
+  // Implements VideoInputFeedBack.
+  virtual void OnDeviceChange();
  private:
   // Gets and allocates a free capture device id. Assumed protected by caller.
   bool GetFreeCaptureId(int* freecapture_id);
 
   // Frees a capture id assigned in GetFreeCaptureId.
   void ReturnCaptureId(int capture_id);
 
   // Gets the ViEFrameProvider for this capture observer.
@@ -96,16 +101,18 @@ class ViEInputManager : private ViEManag
 
   // Gets the ViECapturer for the capture device id.
   ViECapturer* ViECapturePtr(int capture_id) const;
 
   const Config& config_;
   int engine_id_;
   rtc::scoped_ptr<CriticalSectionWrapper> map_cs_;
   rtc::scoped_ptr<CriticalSectionWrapper> device_info_cs_;
+  rtc::scoped_ptr<CriticalSectionWrapper> observer_cs_;
+  ViEInputObserver* observer_ GUARDED_BY(observer_cs_.get());
 
   typedef std::map<int, ViEFrameProviderBase*> FrameProviderMap;
   FrameProviderMap vie_frame_provider_map_;
 
   // Capture devices.
   VideoCaptureModule::DeviceInfo* capture_device_info_;
   int free_capture_device_id_[kViEMaxCaptureDevices];
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -4784,16 +4784,22 @@ pref("dom.w3c_touch_events.enabled", 2);
 #endif
 
 // W3C draft pointer events
 pref("dom.w3c_pointer_events.enabled", false);
 
 // W3C draft ImageCapture API
 pref("dom.imagecapture.enabled", false);
 
+// W3C MediaDevices devicechange event
+pref("media.ondevicechange.enabled", false);
+
+// W3C MediaDevices devicechange fake event
+pref("media.ondevicechange.fakeDeviceChangeEvent.enabled", false);
+
 // W3C touch-action css property (related to touch and pointer events)
 // Note that we turn this on even on platforms/configurations where touch
 // events are not supported (e.g. OS X, or Windows with e10s disabled). For
 // those platforms we don't handle touch events anyway so it's conceptually
 // a no-op.
 #ifdef NIGHTLY_BUILD
 pref("layout.css.touch_action.enabled", true);
 #else
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelChild.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "nsContentSecurityManager.h"
-#include "nsContentUtils.h"
-#include "RtspChannelChild.h"
-#include "mozilla/ipc/URIUtils.h"
-#include "nsServiceManagerUtils.h"
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// RtspChannelChild
-//-----------------------------------------------------------------------------
-RtspChannelChild::RtspChannelChild(nsIURI *aUri)
-  : mIPCOpen(false)
-  , mCanceled(false)
-{
-  nsBaseChannel::SetURI(aUri);
-  DisallowThreadRetargeting();
-}
-
-RtspChannelChild::~RtspChannelChild()
-{
-}
-
-nsIStreamingProtocolController*
-RtspChannelChild::GetController()
-{
-  return mMediaStreamController;
-}
-
-void
-RtspChannelChild::ReleaseController()
-{
-  if (mMediaStreamController) {
-    mMediaStreamController = nullptr;
-  }
-}
-
-//-----------------------------------------------------------------------------
-// IPDL
-//-----------------------------------------------------------------------------
-void
-RtspChannelChild::AddIPDLReference()
-{
-  MOZ_ASSERT(!mIPCOpen,
-             "Attempt to retain more than one IPDL reference");
-  mIPCOpen = true;
-  AddRef();
-}
-
-void
-RtspChannelChild::ReleaseIPDLReference()
-{
-  MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
-  mIPCOpen = false;
-  Release();
-}
-
-//-----------------------------------------------------------------------------
-// nsISupports
-//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED(RtspChannelChild,
-                            nsBaseChannel,
-                            nsIChannel,
-                            nsIChildChannel)
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelChild::GetContentType(nsACString& aContentType)
-{
-  aContentType.AssignLiteral("RTSP");
-  return NS_OK;
-}
-
-class CallListenerOnStartRequestEvent : public Runnable
-{
-public:
-  CallListenerOnStartRequestEvent(nsIStreamListener *aListener,
-                                  nsIRequest *aRequest, nsISupports *aContext)
-    : mListener(aListener)
-    , mRequest(aRequest)
-    , mContext(aContext)
-  {
-    MOZ_RELEASE_ASSERT(aListener);
-  }
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mListener->OnStartRequest(mRequest, mContext);
-    return NS_OK;
-  }
-private:
-  RefPtr<nsIStreamListener> mListener;
-  RefPtr<nsIRequest> mRequest;
-  RefPtr<nsISupports> mContext;
-};
-
-NS_IMETHODIMP
-RtspChannelChild::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
-{
-  MOZ_ASSERT(!mLoadInfo ||
-             mLoadInfo->GetSecurityMode() == 0 ||
-             mLoadInfo->GetInitialSecurityCheckDone() ||
-             (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
-              nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
-             "security flags in loadInfo but asyncOpen2() not called");
-
-  // Precondition checks.
-  MOZ_ASSERT(aListener);
-  nsCOMPtr<nsIURI> uri = nsBaseChannel::URI();
-  NS_ENSURE_TRUE(uri, NS_ERROR_ILLEGAL_VALUE);
-
-  // Create RtspController.
-  nsCOMPtr<nsIStreamingProtocolControllerService> mediaControllerService =
-    do_GetService(MEDIASTREAMCONTROLLERSERVICE_CONTRACTID);
-  MOZ_RELEASE_ASSERT(mediaControllerService,
-    "Cannot proceed if media controller service is unavailable!");
-  mediaControllerService->Create(this, getter_AddRefs(mMediaStreamController));
-  MOZ_ASSERT(mMediaStreamController);
-
-  // Add ourselves to the load group.
-  if (mLoadGroup) {
-    mLoadGroup->AddRequest(this, nullptr);
-  }
-
-  // Dispatch mListener's OnStartRequest directly. mListener is expected to
-  // create an RtspMediaResource and use the RtspController we just created to
-  // manage the control and data streams to and from the network.
-  mListener = aListener;
-  mListenerContext = aContext;
-  NS_DispatchToMainThread(
-    new CallListenerOnStartRequestEvent(mListener, this, mListenerContext));
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelChild::AsyncOpen2(nsIStreamListener *aListener)
-{
-  nsCOMPtr<nsIStreamListener> listener = aListener;
-  nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
-  NS_ENSURE_SUCCESS(rv, rv);
-  return AsyncOpen(listener, nullptr);
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIStreamListener::nsIRequestObserver
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelChild::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-NS_IMETHODIMP
-RtspChannelChild::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
-                                nsresult aStatusCode)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIStreamListener
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelChild::OnDataAvailable(nsIRequest *aRequest,
-                                  nsISupports *aContext,
-                                  nsIInputStream *aInputStream,
-                                  uint64_t aOffset,
-                                  uint32_t aCount)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIChannel::nsIRequest
-//-----------------------------------------------------------------------------
-class CallListenerOnStopRequestEvent : public Runnable
-{
-public:
-  CallListenerOnStopRequestEvent(nsIStreamListener *aListener,
-                                 nsIRequest *aRequest,
-                                 nsISupports *aContext, nsresult aStatus)
-    : mListener(aListener)
-    , mRequest(aRequest)
-    , mContext(aContext)
-    , mStatus(aStatus)
-  {
-    MOZ_RELEASE_ASSERT(aListener);
-  }
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mListener->OnStopRequest(mRequest, mContext, mStatus);
-    return NS_OK;
-  }
-private:
-  RefPtr<nsIStreamListener> mListener;
-  RefPtr<nsIRequest> mRequest;
-  RefPtr<nsISupports> mContext;
-  nsresult mStatus;
-};
-
-NS_IMETHODIMP
-RtspChannelChild::Cancel(nsresult status)
-{
-  if (mCanceled) {
-    return NS_OK;
-  }
-
-  mCanceled = true;
-  // Stop RtspController.
-  if (mMediaStreamController) {
-    mMediaStreamController->Stop();
-  }
-
-  // Call mListener's OnStopRequest to do clean up.
-  NS_DispatchToMainThread(
-    new CallListenerOnStopRequestEvent(mListener, this,
-                                       mListenerContext, status));
-  mListener = nullptr;
-  mListenerContext = nullptr;
-
-  // Remove ourselves from the load group.
-  if (mLoadGroup) {
-    mLoadGroup->RemoveRequest(this, nullptr, status);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelChild::Suspend()
-{
-  MOZ_CRASH("Should never be called");
-}
-
-NS_IMETHODIMP
-RtspChannelChild::Resume()
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelChild::OpenContentStream(bool aAsync,
-                                    nsIInputStream **aStream,
-                                    nsIChannel **aChannel)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsIChildChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelChild::ConnectParent(uint32_t id)
-{
-  // Create RtspChannelParent for redirection.
-  AddIPDLReference();
-  RtspChannelConnectArgs connectArgs;
-  SerializeURI(nsBaseChannel::URI(), connectArgs.uri());
-  connectArgs.channelId() = id;
-  if (!gNeckoChild->SendPRtspChannelConstructor(this, connectArgs)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
-                                        nsISupports *aContext)
-{
-  if (mLoadInfo && mLoadInfo->GetEnforceSecurity()) {
-    MOZ_ASSERT(!aContext, "aContext should be null!");
-    return AsyncOpen2(aListener);
-  }
-  return AsyncOpen(aListener, aContext);
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelChild.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspChannelChild_h
-#define RtspChannelChild_h
-
-#include "mozilla/net/PRtspChannelChild.h"
-#include "mozilla/net/NeckoChild.h"
-#include "nsBaseChannel.h"
-#include "nsIChildChannel.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsIStreamingProtocolService.h"
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// RtspChannelChild is a dummy channel used to aid MediaResource creation in
-// HTMLMediaElement. Network control and data flows are managed by an
-// RtspController object, which is created by us and manipulated by
-// RtspMediaResource. This object is also responsible for inter-process
-// communication with the parent process.
-// When RtspChannelChild::AsyncOpen is called, it should create an
-// RtspController object, dispatch an OnStartRequest and immediately return.
-// We expect an RtspMediaResource object will be created in the calling context
-// and it will use the RtpController we create.
-
-class RtspChannelChild : public PRtspChannelChild
-                       , public nsBaseChannel
-                       , public nsIChildChannel
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSICHILDCHANNEL
-
-  RtspChannelChild(nsIURI *aUri);
-
-  // nsBaseChannel::nsIChannel
-  NS_IMETHOD GetContentType(nsACString & aContentType) override final;
-  NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext)
-                       override final;
-  NS_IMETHOD AsyncOpen2(nsIStreamListener *listener) override final;
-
-  // nsBaseChannel::nsIStreamListener::nsIRequestObserver
-  NS_IMETHOD OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
-                            override final;
-  NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
-                           nsISupports *aContext,
-                           nsresult aStatusCode) override final;
-
-  // nsBaseChannel::nsIStreamListener
-  NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
-                             nsISupports *aContext,
-                             nsIInputStream *aInputStream,
-                             uint64_t aOffset,
-                             uint32_t aCount) override final;
-
-  // nsBaseChannel::nsIChannel::nsIRequest
-  NS_IMETHOD Cancel(nsresult status) override final;
-  NS_IMETHOD Suspend() override final;
-  NS_IMETHOD Resume() override final;
-
-  // nsBaseChannel
-  NS_IMETHOD OpenContentStream(bool aAsync,
-                               nsIInputStream **aStream,
-                               nsIChannel **aChannel) override final;
-
-  // IPDL
-  void AddIPDLReference();
-  void ReleaseIPDLReference();
-
-  // RtspChannelChild
-  nsIStreamingProtocolController* GetController();
-  void ReleaseController();
-
-protected:
-  ~RtspChannelChild();
-
-private:
-  bool mIPCOpen;
-  bool mCanceled;
-  nsCOMPtr<nsIStreamingProtocolController> mMediaStreamController;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspChannelChild_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelParent.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "RtspChannelParent.h"
-#include "nsContentSecurityManager.h"
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// RtspChannelParent
-//-----------------------------------------------------------------------------
-RtspChannelParent::RtspChannelParent(nsIURI *aUri)
-  : mIPCClosed(false)
-{
-  nsBaseChannel::SetURI(aUri);
-  DisallowThreadRetargeting();
-}
-
-RtspChannelParent::~RtspChannelParent()
-{
-}
-
-void
-RtspChannelParent::ActorDestroy(ActorDestroyReason why)
-{
-  mIPCClosed = true;
-}
-
-//-----------------------------------------------------------------------------
-// nsISupports
-//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS_INHERITED(RtspChannelParent,
-                            nsBaseChannel,
-                            nsIParentChannel)
-
-//-----------------------------------------------------------------------------
-// RtspChannelParent methods
-//-----------------------------------------------------------------------------
-bool
-RtspChannelParent::Init(const RtspChannelConnectArgs& aArgs)
-{
-  return ConnectChannel(aArgs.channelId());
-}
-
-bool
-RtspChannelParent::ConnectChannel(const uint32_t& channelId)
-{
-  nsCOMPtr<nsIChannel> channel;
-  NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
-
-  return true;
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelParent::GetContentType(nsACString& aContentType)
-{
-  aContentType.AssignLiteral("RTSP");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::AsyncOpen(nsIStreamListener *aListener, nsISupports *aContext)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::AsyncOpen2(nsIStreamListener *aListener)
-{
-  return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIStreamListener::nsIRequestObserver
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelParent::OnStartRequest(nsIRequest *aRequest,
-                            nsISupports *aContext)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-NS_IMETHODIMP
-RtspChannelParent::OnStopRequest(nsIRequest *aRequest,
-                           nsISupports *aContext,
-                           nsresult aStatusCode)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIStreamListener
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelParent::OnDataAvailable(nsIRequest *aRequest,
-                             nsISupports *aContext,
-                             nsIInputStream *aInputStream,
-                             uint64_t aOffset,
-                             uint32_t aCount)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel::nsIChannel::nsIRequeset
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelParent::Cancel(nsresult status)
-{
-  // FIXME: This method will be called by
-  // nsXMLHttpRequest::CloseRequestWithError while closing the browser app.
-  // However, the root cause is RtspChannelParent will be created by
-  // nsXMLHttpRequest::Open when we navigate away from an RTSP web page.
-  // We should find out why it happens and decide how to fix it.
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::Suspend()
-{
-  MOZ_CRASH("Should never be called");
-}
-
-NS_IMETHODIMP
-RtspChannelParent::Resume()
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsBaseChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelParent::OpenContentStream(bool aAsync,
-                               nsIInputStream **aStream,
-                               nsIChannel **aChannel)
-{
-  MOZ_CRASH("Should never be called");
-}
-
-//-----------------------------------------------------------------------------
-// nsIParentChannel
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspChannelParent::SetParentListener(HttpChannelParentListener *aListener)
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::NotifyTrackingProtectionDisabled()
-{
-  // One day, this should probably be filled in.
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspChannelParent::Delete()
-{
-  return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspChannelParent.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspChannelParent_h
-#define RtspChannelParent_h
-
-#include "mozilla/net/PRtspChannelParent.h"
-#include "mozilla/net/NeckoParent.h"
-#include "nsBaseChannel.h"
-#include "nsIParentChannel.h"
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// Note: RtspChannel doesn't transport streams as normal channel does.
-// (See RtspChannelChild.h for detail).
-// The reason for the existence of RtspChannelParent is to support HTTP->RTSP
-// redirection.
-// When redirection happens, two instances of RtspChannelParent will be created:
-// - One will be created when HTTP creates the new channel for redirects, and
-//   will be registered as an nsIChannel.
-// - The other will be created via IPDL by RtspChannelChild, and will be
-//   registered as an nsIParentChannel.
-class RtspChannelParent : public PRtspChannelParent
-                        , public nsBaseChannel
-                        , public nsIParentChannel
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIPARENTCHANNEL
-
-  RtspChannelParent(nsIURI *aUri);
-
-  // nsBaseChannel::nsIChannel
-  NS_IMETHOD GetContentType(nsACString & aContentType) override final;
-  NS_IMETHOD AsyncOpen(nsIStreamListener *listener,
-                       nsISupports *aContext) override final;
-  NS_IMETHOD AsyncOpen2(nsIStreamListener *listener) override final;
-
-  // nsBaseChannel::nsIStreamListener::nsIRequestObserver
-  NS_IMETHOD OnStartRequest(nsIRequest *aRequest,
-                            nsISupports *aContext) override final;
-  NS_IMETHOD OnStopRequest(nsIRequest *aRequest,
-                           nsISupports *aContext,
-                           nsresult aStatusCode) override final;
-
-  // nsBaseChannel::nsIStreamListener
-  NS_IMETHOD OnDataAvailable(nsIRequest *aRequest,
-                             nsISupports *aContext,
-                             nsIInputStream *aInputStream,
-                             uint64_t aOffset,
-                             uint32_t aCount) override final;
-
-  // nsBaseChannel::nsIChannel::nsIRequest
-  NS_IMETHOD Cancel(nsresult status) override final;
-  NS_IMETHOD Suspend() override final;
-  NS_IMETHOD Resume() override final;
-
-  // nsBaseChannel
-  NS_IMETHOD OpenContentStream(bool aAsync,
-                               nsIInputStream **aStream,
-                               nsIChannel **aChannel) override final;
-
-  // RtspChannelParent
-  bool Init(const RtspChannelConnectArgs& aArgs);
-
-protected:
-  ~RtspChannelParent();
-
-  // Used to connect redirected-to channel in parent with just created
-  // ChildChannel. Used during HTTP->RTSP redirection.
-  bool ConnectChannel(const uint32_t& channelId);
-
-private:
-  bool mIPCClosed;
-  virtual void ActorDestroy(ActorDestroyReason why) override;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspChannelParent_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspHandler.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "RtspChannelChild.h"
-#include "RtspChannelParent.h"
-#include "RtspHandler.h"
-#include "nsILoadGroup.h"
-#include "nsIInterfaceRequestor.h"
-#include "nsIURI.h"
-#include "nsAutoPtr.h"
-#include "nsStandardURL.h"
-#include "mozilla/net/NeckoChild.h"
-
-namespace mozilla {
-namespace net {
-
-NS_IMPL_ISUPPORTS(RtspHandler, nsIProtocolHandler)
-
-//-----------------------------------------------------------------------------
-// RtspHandler::nsIProtocolHandler
-//-----------------------------------------------------------------------------
-
-NS_IMETHODIMP
-RtspHandler::GetScheme(nsACString &aScheme)
-{
-  aScheme.AssignLiteral("rtsp");
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::GetDefaultPort(int32_t *aDefaultPort)
-{
-  *aDefaultPort = kDefaultRtspPort;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::GetProtocolFlags(uint32_t *aProtocolFlags)
-{
-  *aProtocolFlags = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_ANYONE |
-    URI_NON_PERSISTABLE | URI_SYNC_LOAD_IS_OK;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::NewURI(const nsACString & aSpec,
-                    const char *aOriginCharset,
-                    nsIURI *aBaseURI, nsIURI **aResult)
-{
-  int32_t port;
-
-  nsresult rv = GetDefaultPort(&port);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  RefPtr<nsStandardURL> url = new nsStandardURL();
-  rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY, port, aSpec,
-                 aOriginCharset, aBaseURI);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  url.forget(aResult);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::NewChannel2(nsIURI* aURI,
-                         nsILoadInfo* aLoadInfo,
-                         nsIChannel** aResult)
-{
-  bool isRtsp = false;
-  RefPtr<nsBaseChannel> rtspChannel;
-
-  nsresult rv = aURI->SchemeIs("rtsp", &isRtsp);
-  NS_ENSURE_SUCCESS(rv, rv);
-  NS_ENSURE_TRUE(isRtsp, NS_ERROR_UNEXPECTED);
-
-  if (IsNeckoChild()) {
-    rtspChannel = new RtspChannelChild(aURI);
-  } else {
-    rtspChannel = new RtspChannelParent(aURI);
-  }
-
-  rv = rtspChannel->Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // set the loadInfo on the new channel
-  rv = rtspChannel->SetLoadInfo(aLoadInfo);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rtspChannel.forget(aResult);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspHandler::NewChannel(nsIURI *aURI, nsIChannel **aResult)
-{
-  return NewChannel2(aURI, nullptr, aResult);
-}
-
-NS_IMETHODIMP
-RtspHandler::AllowPort(int32_t port, const char *scheme, bool *aResult)
-{
-  // Do not override any blacklisted ports.
-  *aResult = false;
-  return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/RtspHandler.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspHandler_h
-#define RtspHandler_h
-
-#include "nsIProtocolHandler.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace net {
-
-
-class RtspHandler final : public nsIProtocolHandler
-{
- public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIPROTOCOLHANDLER
-
-  RtspHandler() { }
-  const static int32_t kDefaultRtspPort = 554;
-
-protected:
-  ~RtspHandler() { }
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspHandler_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspController.cpp
+++ /dev/null
@@ -1,382 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "RtspController.h"
-#include "RtspMetaData.h"
-#include "nsIURI.h"
-#include "nsICryptoHash.h"
-#include "nsIRunnable.h"
-#include "nsIPrefBranch.h"
-#include "nsIPrefService.h"
-#include "nsICancelable.h"
-#include "nsIStreamConverterService.h"
-#include "nsIIOService2.h"
-#include "nsIProtocolProxyService.h"
-#include "nsIProxyInfo.h"
-#include "nsIProxiedChannel.h"
-#include "nsIHttpProtocolHandler.h"
-
-#include "nsAutoPtr.h"
-#include "nsStandardURL.h"
-#include "nsNetCID.h"
-#include "nsServiceManagerUtils.h"
-#include "nsXPIDLString.h"
-#include "nsCRT.h"
-#include "nsThreadUtils.h"
-#include "nsError.h"
-#include "nsStringStream.h"
-#include "nsAlgorithm.h"
-#include "nsProxyRelease.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/Telemetry.h"
-#include "mozilla/TimeStamp.h"
-#include "mozilla/Logging.h"
-
-#include "plbase64.h"
-#include "prmem.h"
-#include "prnetdb.h"
-#include "zlib.h"
-#include <algorithm>
-#include "nsDebug.h"
-
-namespace mozilla {
-namespace net {
-extern LazyLogModule gRtspLog;
-#undef LOG
-#define LOG(args) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Debug, args)
-
-//-----------------------------------------------------------------------------
-// RtspController
-//-----------------------------------------------------------------------------
-NS_IMPL_ISUPPORTS(RtspController,
-                  nsIStreamingProtocolController)
-
-RtspController::RtspController(nsIChannel *channel)
-  : mState(INIT)
-{
-  LOG(("RtspController::RtspController()"));
-}
-
-RtspController::~RtspController()
-{
-  LOG(("RtspController::~RtspController()"));
-  if (mRtspSource.get()) {
-    mRtspSource.clear();
-  }
-}
-
-//-----------------------------------------------------------------------------
-// nsIStreamingProtocolController
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspController::GetTrackMetaData(uint8_t index,
-                                 nsIStreamingProtocolMetaData * *_retval)
-{
-  LOG(("RtspController::GetTrackMetaData()"));
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Play(void)
-{
-  LOG(("RtspController::Play()"));
-  if (!mRtspSource.get()) {
-    MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  if (mState != CONNECTED) {
-    return NS_ERROR_NOT_CONNECTED;
-  }
-
-  mRtspSource->play();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Pause(void)
-{
-  LOG(("RtspController::Pause()"));
-  if (!mRtspSource.get()) {
-    MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  if (mState != CONNECTED) {
-    return NS_ERROR_NOT_CONNECTED;
-  }
-
-  mRtspSource->pause();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Resume(void)
-{
-  return Play();
-}
-
-NS_IMETHODIMP
-RtspController::Suspend(void)
-{
-  return Pause();
-}
-
-NS_IMETHODIMP
-RtspController::Seek(uint64_t seekTimeUs)
-{
-  LOG(("RtspController::Seek() %llu", seekTimeUs));
-  if (!mRtspSource.get()) {
-    MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  if (mState != CONNECTED) {
-    return NS_ERROR_NOT_CONNECTED;
-  }
-
-  mRtspSource->seek(seekTimeUs);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::Stop()
-{
-  LOG(("RtspController::Stop()"));
-  mState = INIT;
-  if (!mRtspSource.get()) {
-    MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  mRtspSource->stop();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::GetTotalTracks(uint8_t *aTracks)
-{
-  LOG(("RtspController::GetTotalTracks()"));
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-RtspController::AsyncOpen(nsIStreamingProtocolListener *aListener)
-{
-  if (!aListener) {
-    LOG(("RtspController::AsyncOpen() illegal listener"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  mListener = aListener;
-
-  if (!mURI) {
-    LOG(("RtspController::AsyncOpen() illegal URI"));
-    return NS_ERROR_ILLEGAL_VALUE;
-  }
-
-  nsAutoCString uriSpec;
-  mURI->GetSpec(uriSpec);
-  LOG(("RtspController AsyncOpen uri=%s", uriSpec.get()));
-
-  if (!mRtspSource.get()) {
-    mRtspSource = new android::RTSPSource(this, uriSpec.get(),
-                                          mUserAgent.get(), false, 0);
-  }
-  // Connect to Rtsp Server.
-  mRtspSource->start();
-
-  return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// nsIStreamingProtocolListener
-//-----------------------------------------------------------------------------
-class SendMediaDataTask : public Runnable
-{
-public:
-  SendMediaDataTask(nsIStreamingProtocolListener *listener,
-                    uint8_t index,
-                    const nsACString & data,
-                    uint32_t length,
-                    uint32_t offset,
-                    nsIStreamingProtocolMetaData *meta)
-    : mIndex(index)
-    , mLength(length)
-    , mOffset(offset)
-    , mMetaData(meta)
-    , mListener(listener)
-  {
-    mData.Assign(data);
-  }
-
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mListener->OnMediaDataAvailable(mIndex, mData, mLength,
-                                    mOffset, mMetaData);
-    return NS_OK;
-  }
-
-private:
-  uint8_t mIndex;
-  nsCString mData;
-  uint32_t mLength;
-  uint32_t mOffset;
-  RefPtr<nsIStreamingProtocolMetaData> mMetaData;
-  nsCOMPtr<nsIStreamingProtocolListener> mListener;
-};
-
-NS_IMETHODIMP
-RtspController::OnMediaDataAvailable(uint8_t index,
-                                     const nsACString & data,
-                                     uint32_t length,
-                                     uint32_t offset,
-                                     nsIStreamingProtocolMetaData *meta)
-{
-  if (mListener && mState == CONNECTED) {
-    RefPtr<SendMediaDataTask> task =
-      new SendMediaDataTask(mListener, index, data, length, offset, meta);
-    return NS_DispatchToMainThread(task);
-  }
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-class SendOnConnectedTask : public Runnable
-{
-public:
-  SendOnConnectedTask(nsIStreamingProtocolListener *listener,
-                      uint8_t index,
-                      nsIStreamingProtocolMetaData *meta)
-    : mListener(listener)
-    , mIndex(index)
-    , mMetaData(meta)
-  { }
-
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mListener->OnConnected(mIndex, mMetaData);
-    return NS_OK;
-  }
-
-private:
-  nsCOMPtr<nsIStreamingProtocolListener> mListener;
-  uint8_t mIndex;
-  RefPtr<nsIStreamingProtocolMetaData> mMetaData;
-};
-
-
-NS_IMETHODIMP
-RtspController::OnConnected(uint8_t index,
-                            nsIStreamingProtocolMetaData *meta)
-{
-  LOG(("RtspController::OnConnected()"));
-  mState = CONNECTED;
-  if (mListener) {
-    RefPtr<SendOnConnectedTask> task =
-      new SendOnConnectedTask(mListener, index, meta);
-    return NS_DispatchToMainThread(task);
-  }
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-class SendOnDisconnectedTask : public Runnable
-{
-public:
-  SendOnDisconnectedTask(nsIStreamingProtocolListener *listener,
-                         uint8_t index,
-                         nsresult reason)
-    : mListener(listener)
-    , mIndex(index)
-    , mReason(reason)
-  { }
-
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    mListener->OnDisconnected(mIndex, mReason);
-    return NS_OK;
-  }
-
-private:
-  nsCOMPtr<nsIStreamingProtocolListener> mListener;
-  uint8_t mIndex;
-  nsresult mReason;
-};
-
-NS_IMETHODIMP
-RtspController::OnDisconnected(uint8_t index,
-                               nsresult reason)
-{
-  LOG(("RtspController::OnDisconnected() for track %d reason = 0x%x", index, reason));
-  mState = DISCONNECTED;
-
-  if (mListener) {
-    RefPtr<SendOnDisconnectedTask> task =
-      new SendOnDisconnectedTask(mListener, index, reason);
-    // Break the cycle reference between the Listener (RtspControllerParent) and
-    // us.
-    mListener = nullptr;
-    return NS_DispatchToMainThread(task);
-  }
-  return NS_ERROR_NOT_AVAILABLE;
-}
-
-NS_IMETHODIMP
-RtspController::Init(nsIURI *aURI)
-{
-  nsresult rv;
-
-  if (!aURI) {
-    LOG(("RtspController::Init() - invalid URI"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  nsAutoCString host;
-  int32_t port = -1;
-
-  rv = aURI->GetAsciiHost(host);
-  if (NS_FAILED(rv)) return rv;
-
-  // Reject the URL if it doesn't specify a host
-  if (host.IsEmpty())
-    return NS_ERROR_MALFORMED_URI;
-
-  rv = aURI->GetPort(&port);
-  if (NS_FAILED(rv)) return rv;
-
-  rv = aURI->GetAsciiSpec(mSpec);
-  if (NS_FAILED(rv)) return rv;
-
-  mURI = aURI;
-
-  // Get User-Agent.
-  nsCOMPtr<nsIHttpProtocolHandler>
-    service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
-  rv = service->GetUserAgent(mUserAgent);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return rv;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspController::PlaybackEnded()
-{
-  LOG(("RtspController::PlaybackEnded()"));
-  if (!mRtspSource.get()) {
-    MOZ_ASSERT(mRtspSource.get(), "mRtspSource should not be null!");
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  mRtspSource->playbackEnded();
-  return NS_OK;
-}
-
-} // namespace mozilla::net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspController.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspController_h
-#define RtspController_h
-
-#include "nsIStreamingProtocolController.h"
-#include "nsIChannel.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "RTSPSource.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspController final : public nsIStreamingProtocolController
-                           , public nsIStreamingProtocolListener
-{
-public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSISTREAMINGPROTOCOLCONTROLLER
-  NS_DECL_NSISTREAMINGPROTOCOLLISTENER
-
-  RtspController(nsIChannel *channel);
-
-protected:
-  ~RtspController();
-
-private:
-  enum State {
-    INIT,
-    CONNECTED,
-    DISCONNECTED
-  };
-
-  // RTSP URL refer to a stream or an aggregate of streams.
-  nsCOMPtr<nsIURI> mURI;
-  // The nsIStreamingProtocolListener implementation.
-  nsCOMPtr<nsIStreamingProtocolListener> mListener;
-  // ASCII encoded URL spec.
-  nsCString mSpec;
-  // UserAgent string.
-  nsCString mUserAgent;
-  // Indicate the connection state between the
-  // media streaming server and the Rtsp client.
-  State mState;
-  // Rtsp Streaming source.
-  android::sp<android::RTSPSource> mRtspSource;
-};
-
-}
-
-} // namespace mozilla::net
-
-#endif
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerChild.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "RtspControllerChild.h"
-#include "RtspMetaData.h"
-#include "mozilla/dom/TabChild.h"
-#include "mozilla/net/NeckoChild.h"
-#include "nsITabChild.h"
-#include "nsILoadContext.h"
-#include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/URIUtils.h"
-#include "nsStringStream.h"
-#include "mozilla/Logging.h"
-
-const uint32_t kRtspTotalTracks = 2;
-const unsigned long kRtspCommandDelayMs = 200;
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-static LazyLogModule gRtspChildLog("nsRtspChild");
-#undef LOG
-#define LOG(args) MOZ_LOG(mozilla::net::gRtspChildLog, mozilla::LogLevel::Debug, args)
-
-NS_IMPL_ADDREF(RtspControllerChild)
-
-NS_IMETHODIMP_(nsrefcnt) RtspControllerChild::Release()
-{
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
-  // Enable this to find non-threadsafe destructors:
-  // NS_ASSERT_OWNINGTHREAD(RtspControllerChild);
-  --mRefCnt;
-  NS_LOG_RELEASE(this, mRefCnt, "RtspControllerChild");
-
-  if (mRefCnt == 1 && mIPCOpen) {
-    Send__delete__(this);
-    return mRefCnt;
-  }
-
-  if (mRefCnt == 0) {
-    mRefCnt = 1; /* stabilize */
-    delete this;
-    return 0;
-  }
-  return mRefCnt;
-}
-
-NS_INTERFACE_MAP_BEGIN(RtspControllerChild)
-  NS_INTERFACE_MAP_ENTRY(nsIStreamingProtocolController)
-  NS_INTERFACE_MAP_ENTRY(nsIStreamingProtocolListener)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamingProtocolController)
-NS_INTERFACE_MAP_END
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild methods
-//-----------------------------------------------------------------------------
-RtspControllerChild::RtspControllerChild(nsIChannel *channel)
-  : mIPCOpen(false)
-  , mIPCAllowed(false)
-  , mChannel(channel)
-  , mTotalTracks(0)
-  , mSuspendCount(0)
-  , mTimerLock("RtspControllerChild.mTimerLock")
-  , mPlayTimer(nullptr)
-  , mPauseTimer(nullptr)
-{
-  AddIPDLReference();
-  gNeckoChild->SendPRtspControllerConstructor(this);
-}
-
-RtspControllerChild::~RtspControllerChild()
-{
-  LOG(("RtspControllerChild::~RtspControllerChild()"));
-}
-
-void
-RtspControllerChild::ReleaseChannel()
-{
-  static_cast<RtspChannelChild*>(mChannel.get())->ReleaseController();
-}
-
-bool
-RtspControllerChild::OKToSendIPC()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  if (mIPCOpen == false) {
-    return false;
-  }
-  return mIPCAllowed;
-}
-
-void
-RtspControllerChild::AllowIPC()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  mIPCAllowed = true;
-}
-
-void
-RtspControllerChild::DisallowIPC()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  mIPCAllowed = false;
-}
-
-void
-RtspControllerChild::StopPlayAndPauseTimer()
-{
-  MutexAutoLock lock(mTimerLock);
-  if (mPlayTimer) {
-    mPlayTimer->Cancel();
-    mPlayTimer = nullptr;
-  }
-  if (mPauseTimer) {
-    mPauseTimer->Cancel();
-    mPauseTimer = nullptr;
-  }
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::PRtspControllerChild
-//-----------------------------------------------------------------------------
-bool
-RtspControllerChild::RecvOnMediaDataAvailable(
-                       const uint8_t& index,
-                       const nsCString& data,
-                       const uint32_t& length,
-                       const uint32_t& offset,
-                       InfallibleTArray<RtspMetadataParam>&& metaArray)
-{
-  RefPtr<RtspMetaData> meta = new RtspMetaData();
-  nsresult rv = meta->DeserializeRtspMetaData(metaArray);
-  NS_ENSURE_SUCCESS(rv, true);
-
-  if (mListener) {
-    mListener->OnMediaDataAvailable(index, data, length, offset, meta.get());
-  }
-  return true;
-}
-
-void
-RtspControllerChild::AddMetaData(
-                       already_AddRefed<nsIStreamingProtocolMetaData>&& meta)
-{
-  mMetaArray.AppendElement(mozilla::Move(meta));
-}
-
-int
-RtspControllerChild::GetMetaDataLength()
-{
-  return mMetaArray.Length();
-}
-
-bool
-RtspControllerChild::RecvOnConnected(
-                       const uint8_t& index,
-                       InfallibleTArray<RtspMetadataParam>&& metaArray)
-{
-  // Deserialize meta data.
-  RefPtr<RtspMetaData> meta = new RtspMetaData();
-  nsresult rv = meta->DeserializeRtspMetaData(metaArray);
-  NS_ENSURE_SUCCESS(rv, true);
-  meta->GetTotalTracks(&mTotalTracks);
-  if (mTotalTracks <= 0) {
-    LOG(("RtspControllerChild::RecvOnConnected invalid tracks %d", mTotalTracks));
-    // Set the default value.
-    mTotalTracks = kRtspTotalTracks;
-  }
-  AddMetaData(meta.forget().downcast<nsIStreamingProtocolMetaData>());
-
-  // Notify the listener when meta data of tracks are available.
-  if ((static_cast<uint32_t>(index) + 1) == mTotalTracks) {
-    // The controller provide |GetTrackMetaData| method for his client.
-    if (mListener) {
-      mListener->OnConnected(index, nullptr);
-    }
-  }
-  return true;
-}
-
-bool
-RtspControllerChild::RecvOnDisconnected(
-                       const uint8_t& index,
-                       const nsresult& reason)
-{
-  StopPlayAndPauseTimer();
-  DisallowIPC();
-  LOG(("RtspControllerChild::RecvOnDisconnected for track %d reason = 0x%x", index, reason));
-  if (mListener) {
-    mListener->OnDisconnected(index, reason);
-  }
-  ReleaseChannel();
-  return true;
-}
-
-bool
-RtspControllerChild::RecvAsyncOpenFailed(const nsresult& reason)
-{
-  StopPlayAndPauseTimer();
-  DisallowIPC();
-  LOG(("RtspControllerChild::RecvAsyncOpenFailed reason = 0x%x", reason));
-  if (mListener) {
-    mListener->OnDisconnected(0, NS_ERROR_CONNECTION_REFUSED);
-  }
-  ReleaseChannel();
-  return true;
-}
-
-void
-RtspControllerChild::AddIPDLReference()
-{
-  MOZ_ASSERT(!mIPCOpen,
-             "Attempt to retain more than one IPDL reference");
-  mIPCOpen = true;
-  AllowIPC();
-  AddRef();
-}
-
-void
-RtspControllerChild::ReleaseIPDLReference()
-{
-  MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
-  mIPCOpen = false;
-  DisallowIPC();
-  Release();
-}
-
-NS_IMETHODIMP
-RtspControllerChild::GetTrackMetaData(
-                       uint8_t index,
-                       nsIStreamingProtocolMetaData **result)
-{
-  if (GetMetaDataLength() <= 0 || index >= GetMetaDataLength()) {
-    LOG(("RtspControllerChild:: meta data is not available"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-  LOG(("RtspControllerChild::GetTrackMetaData() %d", index));
-  NS_IF_ADDREF(*result = mMetaArray[index]);
-  return NS_OK;
-}
-
-enum IPCEvent
-{
-  SendNoneEvent = 0,
-  SendPlayEvent,
-  SendPauseEvent,
-  SendSeekEvent,
-  SendStopEvent,
-  SendPlaybackEndedEvent
-};
-
-class SendIPCEvent : public Runnable
-{
-public:
-  SendIPCEvent(RtspControllerChild *aController, IPCEvent aEvent)
-    : mController(aController)
-    , mEvent(aEvent)
-    , mSeekTime(0)
-  {
-  }
-
-  SendIPCEvent(RtspControllerChild *aController,
-               IPCEvent aEvent,
-               uint64_t aSeekTime)
-    : mController(aController)
-    , mEvent(aEvent)
-    , mSeekTime(aSeekTime)
-  {
-  }
-
-  NS_IMETHOD Run() override
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    if (mController->OKToSendIPC() == false) {
-      // Don't send any more IPC events; no guarantee that parent objects are
-      // still alive.
-      return NS_ERROR_FAILURE;
-    }
-    bool rv = true;
-
-    if (mEvent == SendPlayEvent) {
-      rv = mController->SendPlay();
-    } else if (mEvent == SendPauseEvent) {
-      rv = mController->SendPause();
-    } else if (mEvent == SendSeekEvent) {
-      rv = mController->SendSeek(mSeekTime);
-    } else if (mEvent == SendStopEvent) {
-      rv = mController->SendStop();
-    } else if (mEvent == SendPlaybackEndedEvent) {
-      rv = mController->SendPlaybackEnded();
-    } else {
-      LOG(("RtspControllerChild::SendIPCEvent"));
-    }
-    if (!rv) {
-      return NS_ERROR_FAILURE;
-    }
-    return NS_OK;
-  }
-private:
-  RefPtr<RtspControllerChild> mController;
-  IPCEvent mEvent;
-  uint64_t mSeekTime;
-};
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::nsIStreamingProtocolController
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspControllerChild::Play(void)
-{
-  LOG(("RtspControllerChild::Play()"));
-
-  MutexAutoLock lock(mTimerLock);
-  // Cancel the pause timer if it is active because successive pause-play in a
-  // short duration is unncessary but could impair playback smoothing.
-  if (mPauseTimer) {
-    mPauseTimer->Cancel();
-    mPauseTimer = nullptr;
-  }
-
-  // Start a timer to delay the play operation for a short duration.
-  if (!mPlayTimer) {
-    mPlayTimer = do_CreateInstance("@mozilla.org/timer;1");
-    if (!mPlayTimer) {
-      return NS_ERROR_NOT_INITIALIZED;
-    }
-    // We have to dispatch the timer callback to the main thread because the
-    // decoder thread is a thread from nsIThreadPool and cannot be the timer
-    // target. Furthermore, IPC send functions should only be called from the
-    // main thread.
-    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
-    mPlayTimer->SetTarget(mainThread);
-    mPlayTimer->InitWithFuncCallback(
-                  RtspControllerChild::PlayTimerCallback,
-                  this, kRtspCommandDelayMs,
-                  nsITimer::TYPE_ONE_SHOT);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Pause(void)
-{
-  LOG(("RtspControllerChild::Pause()"));
-
-  MutexAutoLock lock(mTimerLock);
-  // Cancel the play timer if it is active because successive play-pause in a
-  // shrot duration is unnecessary but could impair playback smoothing.
-  if (mPlayTimer) {
-    mPlayTimer->Cancel();
-    mPlayTimer = nullptr;
-  }
-
-  // Start a timer to delay the pause operation for a short duration.
-  if (!mPauseTimer) {
-    mPauseTimer = do_CreateInstance("@mozilla.org/timer;1");
-    if (!mPauseTimer) {
-      return NS_ERROR_NOT_INITIALIZED;
-    }
-    // We have to dispatch the timer callback to the main thread because the
-    // decoder thread is a thread from nsIThreadPool and cannot be the timer
-    // target.
-    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
-    mPauseTimer->SetTarget(mainThread);
-    mPauseTimer->InitWithFuncCallback(
-                  RtspControllerChild::PauseTimerCallback,
-                  this, kRtspCommandDelayMs,
-                  nsITimer::TYPE_ONE_SHOT);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Resume(void)
-{
-  LOG(("RtspControllerChild::Resume()"));
-  NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED);
-
-  if (!--mSuspendCount) {
-    return Play();
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Suspend(void)
-{
-  LOG(("RtspControllerChild::Suspend()"));
-
-  if (!mSuspendCount++) {
-    return Pause();
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Seek(uint64_t seekTimeUs)
-{
-  LOG(("RtspControllerChild::Seek() %llu", seekTimeUs));
-
-  if (NS_IsMainThread()) {
-    if (!OKToSendIPC() || !SendSeek(seekTimeUs)) {
-      return NS_ERROR_FAILURE;
-    }
-  } else {
-    nsresult rv = NS_DispatchToMainThread(
-                    new SendIPCEvent(this, SendSeekEvent, seekTimeUs));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::Stop()
-{
-  LOG(("RtspControllerChild::Stop()"));
-  StopPlayAndPauseTimer();
-
-  if (NS_IsMainThread()) {
-    if (!OKToSendIPC() || !SendStop()) {
-      return NS_ERROR_FAILURE;
-    }
-    DisallowIPC();
-  } else {
-    nsresult rv = NS_DispatchToMainThread(
-                    new SendIPCEvent(this, SendStopEvent));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::GetTotalTracks(uint8_t *aTracks)
-{
-  NS_ENSURE_ARG_POINTER(aTracks);
-  *aTracks = kRtspTotalTracks;
-  if (mTotalTracks) {
-    *aTracks = mTotalTracks;
-  }
-  LOG(("RtspControllerChild::GetTracks() %d", *aTracks));
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::PlaybackEnded()
-{
-  LOG(("RtspControllerChild::PlaybackEnded"));
-
-  StopPlayAndPauseTimer();
-
-  if (NS_IsMainThread()) {
-    if (!OKToSendIPC() || !SendPlaybackEnded()) {
-      return NS_ERROR_FAILURE;
-    }
-  } else {
-    nsresult rv = NS_DispatchToMainThread(
-                    new SendIPCEvent(this, SendPlaybackEndedEvent));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::nsIStreamingProtocolListener
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspControllerChild::OnMediaDataAvailable(uint8_t index,
-                                          const nsACString & data,
-                                          uint32_t length,
-                                          uint32_t offset,
-                                          nsIStreamingProtocolMetaData *meta)
-{
-  LOG(("RtspControllerChild::OnMediaDataAvailable()"));
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::OnConnected(uint8_t index,
-                                 nsIStreamingProtocolMetaData *meta)
-
-{
-  LOG(("RtspControllerChild::OnConnected()"));
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::OnDisconnected(uint8_t index,
-                                    nsresult reason)
-{
-  LOG(("RtspControllerChild::OnDisconnected() reason = 0x%x", reason));
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild::nsIStreamingProtocoController
-//-----------------------------------------------------------------------------
-NS_IMETHODIMP
-RtspControllerChild::Init(nsIURI *aURI)
-{
-  nsresult rv;
-
-  if (!aURI) {
-    LOG(("RtspControllerChild::Init() - invalid URI"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  nsAutoCString host;
-  int32_t port = -1;
-
-  rv = aURI->GetAsciiHost(host);
-  if (NS_FAILED(rv)) return rv;
-
-  // Reject the URL if it doesn't specify a host
-  if (host.IsEmpty())
-    return NS_ERROR_MALFORMED_URI;
-
-  rv = aURI->GetPort(&port);
-  if (NS_FAILED(rv)) return rv;
-
-  rv = aURI->GetAsciiSpec(mSpec);
-  if (NS_FAILED(rv)) return rv;
-
-  if (!strncmp(mSpec.get(), "rtsp:", 5) == 0)
-    return NS_ERROR_UNEXPECTED;
-
-  mURI = aURI;
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerChild::AsyncOpen(nsIStreamingProtocolListener *aListener)
-{
-  LOG(("RtspControllerChild::AsyncOpen()"));
-  if (!aListener) {
-    LOG(("RtspControllerChild::AsyncOpen() - invalid listener"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-  mListener = aListener;
-
-  if (!mChannel) {
-    LOG(("RtspControllerChild::AsyncOpen() - invalid URI"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  nsCOMPtr<nsIURI> uri;
-  URIParams uriParams;
-  mChannel->GetURI(getter_AddRefs(uri));
-  if (!uri) {
-    LOG(("RtspControllerChild::AsyncOpen() - invalid URI"));
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-  SerializeURI(uri, uriParams);
-
-  if (!OKToSendIPC() || !SendAsyncOpen(uriParams)) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// RtspControllerChild static member methods
-//-----------------------------------------------------------------------------
-//static
-void
-RtspControllerChild::PlayTimerCallback(nsITimer *aTimer, void *aClosure)
-{
-  MOZ_ASSERT(aTimer);
-  MOZ_ASSERT(aClosure);
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RtspControllerChild *self = static_cast<RtspControllerChild*>(aClosure);
-
-  MutexAutoLock lock(self->mTimerLock);
-  if (!self->mPlayTimer || !self->OKToSendIPC()) {
-    return;
-  }
-  self->SendPlay();
-  self->mPlayTimer = nullptr;
-}
-
-//static
-void
-RtspControllerChild::PauseTimerCallback(nsITimer *aTimer, void *aClosure)
-{
-  MOZ_ASSERT(aTimer);
-  MOZ_ASSERT(aClosure);
-  MOZ_ASSERT(NS_IsMainThread());
-
-  RtspControllerChild *self = static_cast<RtspControllerChild*>(aClosure);
-
-  MutexAutoLock lock(self->mTimerLock);
-  if (!self->mPauseTimer || !self->OKToSendIPC()) {
-    return;
-  }
-  self->SendPause();
-  self->mPauseTimer = nullptr;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerChild.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspControllerChild_h
-#define RtspControllerChild_h
-
-#include "mozilla/net/PRtspControllerChild.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsIChannel.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-#include "nsTArray.h"
-#include "mozilla/net/RtspChannelChild.h"
-#include "mozilla/Mutex.h"
-#include "nsITimer.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspControllerChild : public nsIStreamingProtocolController
-                          , public nsIStreamingProtocolListener
-                          , public PRtspControllerChild
-{
- public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSISTREAMINGPROTOCOLCONTROLLER
-  NS_DECL_NSISTREAMINGPROTOCOLLISTENER
-
-  RtspControllerChild(nsIChannel *channel);
-
-  bool RecvOnConnected(const uint8_t& index,
-                       InfallibleTArray<RtspMetadataParam>&& meta);
-
-  bool RecvOnMediaDataAvailable(
-         const uint8_t& index,
-         const nsCString& data,
-         const uint32_t& length,
-         const uint32_t& offset,
-         InfallibleTArray<RtspMetadataParam>&& meta);
-
-  bool RecvOnDisconnected(const uint8_t& index,
-                          const nsresult& reason);
-
-  bool RecvAsyncOpenFailed(const nsresult& reason);
-  void AddIPDLReference();
-  void ReleaseIPDLReference();
-  void AddMetaData(already_AddRefed<nsIStreamingProtocolMetaData>&& meta);
-  int  GetMetaDataLength();
-  bool OKToSendIPC();
-  void AllowIPC();
-  void DisallowIPC();
-
-  // These callbacks will be called when mPlayTimer/mPauseTimer fires.
-  static void PlayTimerCallback(nsITimer *aTimer, void *aClosure);
-  static void PauseTimerCallback(nsITimer *aTimer, void *aClosure);
-
- protected:
-  ~RtspControllerChild();
-
- private:
-  bool mIPCOpen;
-  // The intention of this variable is just to avoid any IPC message to be sent
-  // when this flag is set as false. Nothing more.
-  bool mIPCAllowed;
-  // Dummy channel used to aid MediaResource creation in HTMLMediaElement.
-  nsCOMPtr<nsIChannel> mChannel;
-  // The nsIStreamingProtocolListener implementation.
-  nsCOMPtr<nsIStreamingProtocolListener> mListener;
-  // RTSP URL refer to a stream or an aggregate of streams.
-  nsCOMPtr<nsIURI> mURI;
-  // Array refer to metadata of the media stream.
-  nsTArray<nsCOMPtr<nsIStreamingProtocolMetaData>> mMetaArray;
-  // ASCII encoded URL spec
-  nsCString mSpec;
-  // The total tracks for the given media stream session.
-  uint32_t mTotalTracks;
-  // Current suspension depth for this channel object
-  uint32_t mSuspendCount;
-  // Detach channel-controller relationship.
-  void ReleaseChannel();
-  // This lock protects mPlayTimer and mPauseTimer.
-  Mutex mTimerLock;
-  // Timers to delay the play and pause operations.
-  // They are used for optimization and to avoid sending unnecessary requests to
-  // the server.
-  nsCOMPtr<nsITimer> mPlayTimer;
-  nsCOMPtr<nsITimer> mPauseTimer;
-  // Timers should be stopped if we are going to terminate, such as when
-  // receiving Stop command or OnDisconnected event.
-  void StopPlayAndPauseTimer();
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspControllerChild_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerParent.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "RtspControllerParent.h"
-#include "RtspController.h"
-#include "nsIAuthPromptProvider.h"
-#include "nsThreadUtils.h"
-#include "nsProxyRelease.h"
-#include "mozilla/ipc/InputStreamUtils.h"
-#include "mozilla/ipc/URIUtils.h"
-#include "mozilla/unused.h"
-#include "mozilla/Logging.h"
-
-#include <sys/types.h>
-
-#define SEND_DISCONNECT_IF_ERROR(rv)                         \
-  if (NS_FAILED(rv) && mIPCOpen && mTotalTracks > 0ul) {     \
-    for (uint32_t i = 0; i < mTotalTracks; i++) {            \
-      Unused << SendOnDisconnected(i, rv);                   \
-    }                                                        \
-  }
-
-using namespace mozilla::ipc;
-
-namespace mozilla {
-namespace net {
-
-LazyLogModule gRtspLog("nsRtsp");
-#undef LOG
-#define LOG(args) MOZ_LOG(mozilla::net::gRtspLog, mozilla::LogLevel::Debug, args)
-
-void
-RtspControllerParent::Destroy()
-{
-  // If we're being destroyed on a non-main thread, we AddRef again and use a
-  // proxy to release the RtspControllerParent on the main thread, where the
-  // RtspControllerParent is deleted. This ensures we only delete the
-  // RtspControllerParent on the main thread.
-  if (!NS_IsMainThread()) {
-    RefPtr<RtspControllerParent> doomed(this);
-    NS_ReleaseOnMainThread(doomed.forget(), true);
-  } else {
-    delete this;
-  }
-}
-
-NS_IMPL_ADDREF(RtspControllerParent)
-NS_IMPL_RELEASE_WITH_DESTROY(RtspControllerParent, Destroy())
-NS_IMPL_QUERY_INTERFACE(RtspControllerParent,
-                        nsIStreamingProtocolListener)
-
-RtspControllerParent::RtspControllerParent()
-  : mIPCOpen(true)
-  , mTotalTracks(0)
-{
-}
-
-RtspControllerParent::~RtspControllerParent()
-{
-}
-
-void
-RtspControllerParent::ActorDestroy(ActorDestroyReason why)
-{
-  LOG(("RtspControllerParent::ActorDestroy()"));
-  mIPCOpen = false;
-
-  NS_ENSURE_TRUE_VOID(mController);
-  if (mController) {
-    mController->Stop();
-    mController = nullptr;
-  }
-}
-
-bool
-RtspControllerParent::RecvAsyncOpen(const URIParams& aURI)
-{
-  LOG(("RtspControllerParent::RecvAsyncOpen()"));
-
-  mURI = DeserializeURI(aURI);
-
-  mController = new RtspController(nullptr);
-  mController->Init(mURI);
-  nsresult rv = mController->AsyncOpen(this);
-  if (NS_SUCCEEDED(rv)) return true;
-
-  mController = nullptr;
-  return SendAsyncOpenFailed(rv);
-}
-
-bool
-RtspControllerParent::RecvPlay()
-{
-  LOG(("RtspControllerParent::RecvPlay()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->Play();
-  SEND_DISCONNECT_IF_ERROR(rv)
-  return true;
-}
-
-bool
-RtspControllerParent::RecvPause()
-{
-  LOG(("RtspControllerParent::RecvPause()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->Pause();
-  SEND_DISCONNECT_IF_ERROR(rv)
-  return true;
-}
-
-bool
-RtspControllerParent::RecvResume()
-{
-  LOG(("RtspControllerParent::RecvResume()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->Resume();
-  SEND_DISCONNECT_IF_ERROR(rv)
-  return true;
-}
-
-bool
-RtspControllerParent::RecvSuspend()
-{
-  LOG(("RtspControllerParent::RecvSuspend()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->Suspend();
-  SEND_DISCONNECT_IF_ERROR(rv)
-  return true;
-}
-
-bool
-RtspControllerParent::RecvSeek(const uint64_t& offset)
-{
-  LOG(("RtspControllerParent::RecvSeek()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->Seek(offset);
-  SEND_DISCONNECT_IF_ERROR(rv)
-  return true;
-}
-
-bool
-RtspControllerParent::RecvStop()
-{
-  LOG(("RtspControllerParent::RecvStop()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->Stop();
-  NS_ENSURE_SUCCESS(rv, true);
-  return true;
-}
-
-bool
-RtspControllerParent::RecvPlaybackEnded()
-{
-  LOG(("RtspControllerParent::RecvPlaybackEnded()"));
-  NS_ENSURE_TRUE(mController, true);
-
-  nsresult rv = mController->PlaybackEnded();
-  SEND_DISCONNECT_IF_ERROR(rv)
-  return true;
-}
-
-NS_IMETHODIMP
-RtspControllerParent::OnMediaDataAvailable(uint8_t index,
-                                           const nsACString & data,
-                                           uint32_t length,
-                                           uint32_t offset,
-                                           nsIStreamingProtocolMetaData *meta)
-{
-  NS_ENSURE_ARG_POINTER(meta);
-  uint32_t int32Value;
-  uint64_t int64Value;
-
-  nsresult rv = meta->GetTimeStamp(&int64Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-
-  LOG(("RtspControllerParent:: OnMediaDataAvailable %d:%d time %lld",
-       index, length, int64Value));
-
-  // Serialize meta data.
-  nsCString name;
-  name.AssignLiteral("TIMESTAMP");
-  InfallibleTArray<RtspMetadataParam> metaData;
-  metaData.AppendElement(RtspMetadataParam(name, int64Value));
-
-  name.AssignLiteral("FRAMETYPE");
-  rv = meta->GetFrameType(&int32Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
-  nsCString stream;
-  stream.Assign(data);
-  if (!mIPCOpen ||
-      !SendOnMediaDataAvailable(index, stream, length, offset, metaData)) {
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerParent::OnConnected(uint8_t index,
-                                  nsIStreamingProtocolMetaData *meta)
-{
-  NS_ENSURE_ARG_POINTER(meta);
-  uint32_t int32Value;
-  uint64_t int64Value;
-
-  LOG(("RtspControllerParent:: OnConnected"));
-  // Serialize meta data.
-  InfallibleTArray<RtspMetadataParam> metaData;
-  nsCString name;
-  name.AssignLiteral("TRACKS");
-  nsresult rv = meta->GetTotalTracks(&mTotalTracks);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, mTotalTracks));
-
-  name.AssignLiteral("MIMETYPE");
-  nsCString mimeType;
-  rv = meta->GetMimeType(mimeType);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, mimeType));
-
-  name.AssignLiteral("WIDTH");
-  rv = meta->GetWidth(&int32Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
-  name.AssignLiteral("HEIGHT");
-  rv = meta->GetHeight(&int32Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
-  name.AssignLiteral("DURATION");
-  rv = meta->GetDuration(&int64Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int64Value));
-
-  name.AssignLiteral("SAMPLERATE");
-  rv = meta->GetSampleRate(&int32Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
-  name.AssignLiteral("TIMESTAMP");
-  rv = meta->GetTimeStamp(&int64Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int64Value));
-
-  name.AssignLiteral("CHANNELCOUNT");
-  rv = meta->GetChannelCount(&int32Value);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  metaData.AppendElement(RtspMetadataParam(name, int32Value));
-
-  nsCString esds;
-  rv = meta->GetEsdsData(esds);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  name.AssignLiteral("ESDS");
-  metaData.AppendElement(RtspMetadataParam(name, esds));
-
-  nsCString avcc;
-  rv = meta->GetAvccData(avcc);
-  NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-  name.AssignLiteral("AVCC");
-  metaData.AppendElement(RtspMetadataParam(name, avcc));
-
-  if (!mIPCOpen || !SendOnConnected(index, metaData)) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspControllerParent::OnDisconnected(uint8_t index,
-                                     nsresult reason)
-{
-  LOG(("RtspControllerParent::OnDisconnected() for track %d reason = 0x%x", index, reason));
-  if (!mIPCOpen || !SendOnDisconnected(index, reason)) {
-    return NS_ERROR_FAILURE;
-  }
-  if (mController) {
-    mController = nullptr;
-  }
-  return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspControllerParent.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspControllerParent_h
-#define RtspControllerParent_h
-
-#include "mozilla/net/PRtspControllerParent.h"
-#include "mozilla/net/NeckoParent.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsILoadContext.h"
-#include "nsIURI.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspControllerParent : public PRtspControllerParent
-                           , public nsIStreamingProtocolListener
-{
- public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSISTREAMINGPROTOCOLLISTENER
-
-  RtspControllerParent();
-
-  bool RecvAsyncOpen(const URIParams& aURI);
-  bool RecvPlay();
-  bool RecvPause();
-  bool RecvResume();
-  bool RecvSuspend();
-  bool RecvSeek(const uint64_t& offset);
-  bool RecvStop();
-  bool RecvPlaybackEnded();
-
- protected:
-  ~RtspControllerParent();
-
- private:
-  bool mIPCOpen;
-  void ActorDestroy(ActorDestroyReason why);
-  // RTSP URL refer to a stream or an aggregate of streams.
-  nsCOMPtr<nsIURI> mURI;
-  // The nsIStreamingProtocolController implementation.
-  nsCOMPtr<nsIStreamingProtocolController> mController;
-  uint32_t mTotalTracks;
-  // Ensure we are destroyed on the main thread.
-  void Destroy();
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspControllerParent_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspMetaData.cpp
+++ /dev/null
@@ -1,246 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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/. */
-
-#include "RtspMetaData.h"
-#include "mozilla/Logging.h"
-
-using namespace mozilla;
-
-namespace mozilla {
-namespace net {
-
-NS_IMPL_ISUPPORTS(RtspMetaData, nsIStreamingProtocolMetaData)
-
-RtspMetaData::RtspMetaData()
- : mIndex(0)
- , mWidth(0)
- , mHeight(0)
- , mDuration(0)
- , mSampleRate(0)
- , mCurrentTimeStamp(0)
- , mChannelCount(0)
-{
-  mMimeType.AssignLiteral("NONE");
-}
-
-RtspMetaData::~RtspMetaData()
-{
-
-}
-
-nsresult
-RtspMetaData::DeserializeRtspMetaData(const InfallibleTArray<RtspMetadataParam>& metaArray)
-{
-  nsresult rv;
-
-  // Deserialize meta data.
-  for (uint32_t i = 0; i < metaArray.Length(); i++) {
-    const RtspMetaValue& value = metaArray[i].value();
-    const nsCString& name = metaArray[i].name();
-
-    if (name.EqualsLiteral("FRAMETYPE")) {
-      rv = SetFrameType(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("TIMESTAMP")) {
-      rv = SetTimeStamp(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("TRACKS")) {
-      rv = SetTotalTracks(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if(name.EqualsLiteral("MIMETYPE")) {
-      rv = SetMimeType(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("WIDTH")) {
-      rv = SetWidth(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("HEIGHT")) {
-      rv = SetHeight(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("SAMPLERATE")) {
-      rv = SetSampleRate(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if(name.EqualsLiteral("DURATION")) {
-      rv = SetDuration(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("CHANNELCOUNT")) {
-      rv = SetChannelCount(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("ESDS")) {
-      rv = SetEsdsData(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    } else if (name.EqualsLiteral("AVCC")) {
-      rv = SetAvccData(value);
-      NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
-    }
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetFrameType(uint32_t *aFrameType)
-{
-  NS_ENSURE_ARG_POINTER(aFrameType);
-  *aFrameType = mFrameType;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetFrameType(uint32_t aFrameType)
-{
-  mFrameType = aFrameType;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetTotalTracks(uint32_t *aTracks)
-{
-  NS_ENSURE_ARG_POINTER(aTracks);
-  *aTracks = mTotalTracks;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetTotalTracks(uint32_t aTracks)
-{
-  mTotalTracks = aTracks;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetMimeType(nsACString & aMimeType)
-{
-  aMimeType.Assign(mMimeType);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetMimeType(const nsACString & aMimeType)
-{
-  mMimeType.Assign(aMimeType);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetWidth(uint32_t *aWidth)
-{
-  NS_ENSURE_ARG_POINTER(aWidth);
-  *aWidth = mWidth;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetWidth(uint32_t aWidth)
-{
-  mWidth = aWidth;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetHeight(uint32_t *aHeight)
-{
-  NS_ENSURE_ARG_POINTER(aHeight);
-  *aHeight = mHeight;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetHeight(uint32_t aHeight)
-{
-  mHeight = aHeight;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetDuration(uint64_t *aDuration)
-{
-  NS_ENSURE_ARG_POINTER(aDuration);
-  *aDuration = mDuration;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetDuration(uint64_t aDuration)
-{
-  mDuration = aDuration;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetSampleRate(uint32_t *aSampleRate)
-{
-  NS_ENSURE_ARG_POINTER(aSampleRate);
-  *aSampleRate = mSampleRate;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetSampleRate(uint32_t aSampleRate)
-{
-  mSampleRate = aSampleRate;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetTimeStamp(uint64_t *aTimeStamp)
-{
-  NS_ENSURE_ARG_POINTER(aTimeStamp);
-  *aTimeStamp = mCurrentTimeStamp;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetTimeStamp(uint64_t aTimeStamp)
-{
-  mCurrentTimeStamp = aTimeStamp;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetChannelCount(uint32_t *aChannelCount)
-{
-  NS_ENSURE_ARG_POINTER(aChannelCount);
-  *aChannelCount = mChannelCount;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetChannelCount(uint32_t aChannelCount)
-{
-  mChannelCount = aChannelCount;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetEsdsData(nsACString & aESDS)
-{
-  aESDS.Assign(mESDS);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetEsdsData(const nsACString & aESDS)
-{
-  mESDS.Assign(aESDS);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::GetAvccData(nsACString & aAVCC)
-{
-  aAVCC.Assign(mAVCC);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-RtspMetaData::SetAvccData(const nsACString & aAVCC)
-{
-  mAVCC.Assign(aAVCC);
-  return NS_OK;
-}
-
-} // namespace mozilla::net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/rtsp/controller/RtspMetaData.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set sw=2 ts=8 et tw=80 : */
-/* 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 RtspMetaData_h
-#define RtspMetaData_h
-
-#include "mozilla/net/PRtspController.h"
-#include "nsIStreamingProtocolController.h"
-#include "nsCOMPtr.h"
-#include "nsString.h"
-
-namespace mozilla {
-namespace net {
-
-class RtspMetaData final : public nsIStreamingProtocolMetaData
-{
- public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSISTREAMINGPROTOCOLMETADATA
-
-  RtspMetaData();
-
-  nsresult DeserializeRtspMetaData(const InfallibleTArray<RtspMetadataParam>& metaArray);
-
- protected:
-  ~RtspMetaData();
-
- private:
-  uint32_t  mFrameType;
-  uint32_t  mIndex;
-  uint32_t  mTotalTracks;
-  uint32_t  mWidth;
-  uint32_t  mHeight;
-  uint64_t  mDuration;
-  uint32_t  mSampleRate;
-  uint64_t  mCurrentTimeStamp;
-  uint32_t  mChannelCount;
-  nsCString mMimeType;
-  nsCString mESDS;
-  nsCString mAVCC;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // RtspMetaData_h
deleted file mode 100644
--- a/netwerk/protocol/rtsp/moz.build
+++ /dev/null
@@ -1,73 +0,0 @@
-# vim: set filetype=python:
-# 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/.
-
-EXPORTS.mozilla.net += [
-    'controller/RtspController.h',
-    'controller/RtspControllerChild.h',
-    'controller/RtspControllerParent.h',
-    'controller/RtspMetaData.h',
-    'rtsp/RTSPSource.h',
-    'RtspChannelChild.h',
-    'RtspChannelParent.h',
-    'RtspHandler.h',
-]
-
-UNIFIED_SOURCES += [
-    'controller/RtspController.cpp',
-    'controller/RtspControllerChild.cpp',
-    'controller/RtspControllerParent.cpp',
-    'controller/RtspMetaData.cpp',
-    'RtspChannelChild.cpp',
-    'RtspChannelParent.cpp',
-    'RtspHandler.cpp',
-]
-
-# Android sources
-SOURCES += [
-    'rtsp/AAMRAssembler.cpp',
-    'rtsp/AAVCAssembler.cpp',
-    'rtsp/AH263Assembler.cpp',
-    'rtsp/AMPEG4AudioAssembler.cpp',
-    'rtsp/AMPEG4ElementaryAssembler.cpp',
-    'rtsp/APacketSource.cpp',
-    'rtsp/ARawAudioAssembler.cpp',
-    'rtsp/ARTPAssembler.cpp',
-    'rtsp/ARTPConnection.cpp',
-    'rtsp/ARTPSource.cpp',
-    'rtsp/ARTPWriter.cpp',
-    'rtsp/ARTSPConnection.cpp',
-    'rtsp/ASessionDescription.cpp',
-    'rtsp/RTSPSource.cpp',
-]
-
-include('/ipc/chromium/chromium-config.mozbuild')
-
-# Suppress some GCC warnings being treated as errors:
-#  - about attributes on forward declarations for types that are already
-#    defined, which complains about an important MOZ_EXPORT for android::AString
-if CONFIG['GNU_CC']:
-  CXXFLAGS += ['-Wno-error=attributes']
-
-FINAL_LIBRARY = 'xul'
-
-DEFINES['IMPL_NS_NET'] = True
-DEFINES['FORCE_PR_LOG'] = True
-
-LOCAL_INCLUDES += [
-    '/dom/base',
-    '/netwerk/base',
-    'controller',
-    'rtsp',
-]
-
-for var in ('IMPL_NS_NET', 'FORCE_PR_LOG'):
-    DEFINES[var] = True
-
-if CONFIG['ANDROID_VERSION'] == '15':
-    LOCAL_INCLUDES += ['%' + '%s/frameworks/base/media/libstagefright/mpeg2ts' % CONFIG['ANDROID_SOURCE']]
-else:
-    LOCAL_INCLUDES += ['%' + '%s/frameworks/av/media/libstagefright/mpeg2ts' % CONFIG['ANDROID_SOURCE']]
-
-CXXFLAGS += ['-Wno-multichar']
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAMRAssembler.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AAMRAssembler"
-#include "RtspPrlog.h"
-
-#include "AAMRAssembler.h"
-
-#include "ARTPSource.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
-    value->clear();
-
-    size_t keyLen = strlen(key);
-
-    for (;;) {
-        const char *colonPos = strchr(s, ';');
-
-        size_t len =
-            (colonPos == NULL) ? strlen(s) : colonPos - s;
-
-        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
-            value->setTo(&s[keyLen + 1], len - keyLen - 1);
-            return true;
-        }
-        if (len == keyLen && !strncmp(s, key, keyLen)) {
-            value->setTo("1");
-            return true;
-        }
-
-        if (colonPos == NULL) {
-            return false;
-        }
-
-        s = colonPos + 1;
-    }
-}
-
-AAMRAssembler::AAMRAssembler(
-        const sp<AMessage> &notify, bool isWide, const AString &params)
-    : mIsWide(isWide),
-      mNotifyMsg(notify),
-      mNextExpectedSeqNoValid(false),
-      mNextExpectedSeqNo(0) {
-    AString value;
-    CHECK(GetAttribute(params.c_str(), "octet-align", &value) && value == "1");
-    CHECK(!GetAttribute(params.c_str(), "crc", &value) || value == "0");
-    CHECK(!GetAttribute(params.c_str(), "interleaving", &value));
-}
-
-AAMRAssembler::~AAMRAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus AAMRAssembler::assembleMore(
-        const sp<ARTPSource> &source) {
-    return addPacket(source);
-}
-
-static size_t getFrameSize(bool isWide, unsigned FT) {
-    static const size_t kFrameSizeNB[9] = {
-        95, 103, 118, 134, 148, 159, 204, 244, 39
-    };
-    static const size_t kFrameSizeWB[10] = {
-        132, 177, 253, 285, 317, 365, 397, 461, 477, 40
-    };
-
-    if (FT == 15) {
-        return 1;
-    }
-
-    size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];
-
-    // Round up bits to bytes and add 1 for the header byte.
-    frameSize = (frameSize + 7) / 8 + 1;
-
-    return frameSize;
-}
-
-ARTPAssembler::AssemblyStatus AAMRAssembler::addPacket(
-        const sp<ARTPSource> &source) {
-    List<sp<ABuffer> > *queue = source->queue();
-
-    if (queue->empty()) {
-        return NOT_ENOUGH_DATA;
-    }
-
-    if (mNextExpectedSeqNoValid) {
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
-                break;
-            }
-
-            it = queue->erase(it);
-        }
-
-        if (queue->empty()) {
-            return NOT_ENOUGH_DATA;
-        }
-    }
-
-    sp<ABuffer> buffer = *queue->begin();
-
-    if (!mNextExpectedSeqNoValid) {
-        mNextExpectedSeqNoValid = true;
-        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
-    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-        LOGV("Not the sequence number I expected");
-
-        return WRONG_SEQUENCE_NUMBER;
-    }
-
-    // hexdump(buffer->data(), buffer->size());
-
-    if (buffer->size() < 1) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        LOGW("AMR packet too short.");
-
-        return MALFORMED_PACKET;
-    }
-
-    unsigned payloadHeader = buffer->data()[0];
-    if ((payloadHeader & 0x0f) != 0u) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        LOGW("Wrong payload header");
-
-        return MALFORMED_PACKET;
-    }
-
-    Vector<uint8_t> tableOfContents;
-
-    size_t offset = 1;
-    size_t totalSize = 0;
-    for (;;) {
-        if (offset >= buffer->size()) {
-            queue->erase(queue->begin());
-            ++mNextExpectedSeqNo;
-
-            LOGW("Unable to parse TOC.");
-
-            return MALFORMED_PACKET;
-        }
-
-        uint8_t toc = buffer->data()[offset++];
-
-        unsigned FT = (toc >> 3) & 0x0f;
-        if ((toc & 3) != 0
-                || (mIsWide && FT > 9 && FT != 15)
-                || (!mIsWide && FT > 8 && FT != 15)) {
-            queue->erase(queue->begin());
-            ++mNextExpectedSeqNo;
-
-            LOGW("Illegal TOC entry.");
-
-            return MALFORMED_PACKET;
-        }
-
-        totalSize += getFrameSize(mIsWide, (toc >> 3) & 0x0f);
-
-        tableOfContents.push(toc);
-
-        if (0 == (toc & 0x80)) {
-            break;
-        }
-    }
-
-    sp<ABuffer> accessUnit = new ABuffer(totalSize);
-    if (!CopyTimes(accessUnit, buffer)) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        return MALFORMED_PACKET;
-    }
-
-    size_t dstOffset = 0;
-    for (size_t i = 0; i < tableOfContents.size(); ++i) {
-        uint8_t toc = tableOfContents[i];
-
-        size_t frameSize = getFrameSize(mIsWide, (toc >> 3) & 0x0f);
-
-        if (offset + frameSize - 1 > buffer->size()) {
-            queue->erase(queue->begin());
-            ++mNextExpectedSeqNo;
-
-            LOGW("AMR packet too short.");
-
-            return MALFORMED_PACKET;
-        }
-
-        accessUnit->data()[dstOffset++] = toc;
-        memcpy(accessUnit->data() + dstOffset,
-               buffer->data() + offset, frameSize - 1);
-
-        offset += frameSize - 1;
-        dstOffset += frameSize - 1;
-    }
-
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setObject("access-unit", accessUnit);
-    msg->post();
-
-    queue->erase(queue->begin());
-    ++mNextExpectedSeqNo;
-
-    return OK;
-}
-
-void AAMRAssembler::packetLost() {
-    CHECK(mNextExpectedSeqNoValid);
-    ++mNextExpectedSeqNo;
-}
-
-void AAMRAssembler::onByeReceived() {
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setInt32("eos", true);
-    msg->post();
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAMRAssembler.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_AMR_ASSEMBLER_H_
-
-#define A_AMR_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-
-#include <stdint.h>
-
-namespace android {
-
-struct MOZ_EXPORT AMessage;
-struct MOZ_EXPORT AString;
-
-struct AAMRAssembler : public ARTPAssembler {
-    AAMRAssembler(
-            const sp<AMessage> &notify, bool isWide,
-            const AString &params);
-
-protected:
-    virtual ~AAMRAssembler();
-
-    virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
-    virtual void onByeReceived();
-    virtual void packetLost();
-
-private:
-    bool mIsWide;
-
-    sp<AMessage> mNotifyMsg;
-    bool mNextExpectedSeqNoValid;
-    uint32_t mNextExpectedSeqNo;
-
-    AssemblyStatus addPacket(const sp<ARTPSource> &source);
-
-    DISALLOW_EVIL_CONSTRUCTORS(AAMRAssembler);
-};
-
-}  // namespace android
-
-#endif  // A_AMR_ASSEMBLER_H_
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAVCAssembler.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AAVCAssembler"
-#include "RtspPrlog.h"
-
-#include "AAVCAssembler.h"
-
-#include "ARTPSource.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include <stdint.h>
-
-namespace android {
-
-// static
-AAVCAssembler::AAVCAssembler(const sp<AMessage> &notify)
-    : mNotifyMsg(notify),
-      mAccessUnitRTPTime(0),
-      mNextExpectedSeqNoValid(false),
-      mNextExpectedSeqNo(0),
-      mAccessUnitDamaged(false) {
-}
-
-AAVCAssembler::~AAVCAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
-        const sp<ARTPSource> &source) {
-    List<sp<ABuffer> > *queue = source->queue();
-
-    if (queue->empty()) {
-        return NOT_ENOUGH_DATA;
-    }
-
-    if (mNextExpectedSeqNoValid) {
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
-                break;
-            }
-
-            it = queue->erase(it);
-        }
-
-        if (queue->empty()) {
-            return NOT_ENOUGH_DATA;
-        }
-    }
-
-    sp<ABuffer> buffer = *queue->begin();
-
-    if (!mNextExpectedSeqNoValid) {
-        mNextExpectedSeqNoValid = true;
-        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
-    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-        LOGV("Not the sequence number I expected");
-
-        return WRONG_SEQUENCE_NUMBER;
-    }
-
-    const uint8_t *data = buffer->data();
-    size_t size = buffer->size();
-
-    if (size < 1 || (data[0] & 0x80)) {
-        // Corrupt.
-
-        LOGW("Ignoring corrupt buffer.");
-        queue->erase(queue->begin());
-
-        ++mNextExpectedSeqNo;
-        return MALFORMED_PACKET;
-    }
-
-    unsigned nalType = data[0] & 0x1f;
-    if (nalType >= 1 && nalType <= 23) {
-        bool success = addSingleNALUnit(buffer);
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        return success ? OK : MALFORMED_PACKET;
-    } else if (nalType == 28) {
-        // FU-A
-        return addFragmentedNALUnit(queue);
-    } else if (nalType == 24) {
-        // STAP-A
-        bool success = addSingleTimeAggregationPacket(buffer);
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        return success ? OK : MALFORMED_PACKET;
-    } else {
-        LOGV("Ignoring unsupported buffer (nalType=%d)", nalType);
-
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        return MALFORMED_PACKET;
-    }
-}
-
-bool AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
-    LOGV("addSingleNALUnit of size %d", buffer->size());
-#if !LOG_NDEBUG
-    hexdump(buffer->data(), buffer->size());
-#endif
-
-    uint32_t rtpTime;
-    if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
-        LOGW("Cannot find rtp-time");
-        return false;
-    }
-
-    if (!mNALUnits.empty() && rtpTime != mAccessUnitRTPTime) {
-        if (!submitAccessUnit()) {
-            LOGW("Cannot find rtp-time. Malformed packet.");
-
-            return false;
-        }
-    }
-    mAccessUnitRTPTime = rtpTime;
-
-    mNALUnits.push_back(buffer);
-    return true;
-}
-
-bool AAVCAssembler::addSingleTimeAggregationPacket(const sp<ABuffer> &buffer) {
-    const uint8_t *data = buffer->data();
-    size_t size = buffer->size();
-
-    if (size < 3) {
-        LOGV("Discarding too small STAP-A packet.");
-        return false;
-    }
-
-    ++data;
-    --size;
-    while (size >= 2) {
-        size_t nalSize = (data[0] << 8) | data[1];
-
-        if (size < nalSize + 2) {
-            LOGV("Discarding malformed STAP-A packet.");
-            return false;
-        }
-
-        sp<ABuffer> unit = new ABuffer(nalSize);
-        memcpy(unit->data(), &data[2], nalSize);
-
-        if (!CopyTimes(unit, buffer)) {
-            return false;
-        }
-
-        if (!addSingleNALUnit(unit)) {
-            LOGW("addSingleNALUnit() failed");
-            return false;
-        }
-
-        data += 2 + nalSize;
-        size -= 2 + nalSize;
-    }
-
-    if (size != 0) {
-        LOGV("Unexpected padding at end of STAP-A packet.");
-    }
-
-    return true;
-}
-
-ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
-        List<sp<ABuffer> > *queue) {
-    MOZ_ASSERT(!queue->empty());
-
-    sp<ABuffer> buffer = *queue->begin();
-    const uint8_t *data = buffer->data();
-    size_t size = buffer->size();
-
-    if (size <= 0) {
-        LOGW("Buffer is empty");
-
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-        return MALFORMED_PACKET;
-    }
-    unsigned indicator = data[0];
-
-    if ((indicator & 0x1f) != 28) {
-        LOGW("Indicator is wrong");
-
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-        return MALFORMED_PACKET;
-    }
-
-    if (size < 2) {
-        LOGW("Ignoring malformed FU buffer (size = %d)", size);
-
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-        return MALFORMED_PACKET;
-    }
-
-    if (!(data[1] & 0x80)) {
-        // Start bit not set on the first buffer.
-
-        LOGW("Start bit not set on first buffer");
-
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-        return MALFORMED_PACKET;
-    }
-
-    uint32_t nalType = data[1] & 0x1f;
-    uint32_t nri = (data[0] >> 5) & 3;
-
-    uint32_t expectedSeqNo = (uint32_t)buffer->int32Data() + 1;
-    size_t totalSize = size - 2;
-    size_t totalCount = 1;
-    bool complete = false;
-
-    if (data[1] & 0x40) {
-        // Huh? End bit also set on the first buffer.
-
-        LOGV("Grrr. This isn't fragmented at all.");
-
-        complete = true;
-    } else {
-        List<sp<ABuffer> >::iterator it = ++queue->begin();
-        while (it != queue->end()) {
-            LOGV("sequence length %d", totalCount);
-
-            const sp<ABuffer> &buffer = *it;
-
-            const uint8_t *data = buffer->data();
-            size_t size = buffer->size();
-
-            if ((uint32_t)buffer->int32Data() != expectedSeqNo) {
-                LOGV("sequence not complete, expected seqNo %d, got %d",
-                     expectedSeqNo, (uint32_t)buffer->int32Data());
-
-                return WRONG_SEQUENCE_NUMBER;
-            }
-
-            if (size < 2
-                    || data[0] != indicator
-                    || (data[1] & 0x1f) != nalType
-                    || (data[1] & 0x80)) {
-                LOGW("Ignoring malformed FU buffer.");
-
-                // Delete the whole start of the FU.
-
-                it = queue->begin();
-                for (size_t i = 0; i <= totalCount; ++i) {
-                    it = queue->erase(it);
-                }
-
-                mNextExpectedSeqNo = expectedSeqNo + 1;
-
-                return MALFORMED_PACKET;
-            }
-
-            totalSize += size - 2;
-            ++totalCount;
-
-            expectedSeqNo = expectedSeqNo + 1;
-
-            if (data[1] & 0x40) {
-                // This is the last fragment.
-                complete = true;
-                break;
-            }
-
-            ++it;
-        }
-    }
-
-    if (!complete) {
-        return NOT_ENOUGH_DATA;
-    }
-
-    mNextExpectedSeqNo = expectedSeqNo;
-
-    // We found all the fragments that make up the complete NAL unit.
-
-    // Leave room for the header. So far totalSize did not include the
-    // header byte.
-    ++totalSize;
-
-    sp<ABuffer> unit = new ABuffer(totalSize);
-    if (!CopyTimes(unit, *queue->begin())) {
-        return MALFORMED_PACKET;
-    }
-
-    unit->data()[0] = (nri << 5) | nalType;
-
-    size_t offset = 1;
-    List<sp<ABuffer> >::iterator it = queue->begin();
-    for (size_t i = 0; i < totalCount; ++i) {
-        const sp<ABuffer> &buffer = *it;
-
-        LOGV("piece #%d/%d", i + 1, totalCount);
-#if !LOG_NDEBUG
-        hexdump(buffer->data(), buffer->size());
-#endif
-
-        memcpy(unit->data() + offset, buffer->data() + 2, buffer->size() - 2);
-        offset += buffer->size() - 2;
-
-        it = queue->erase(it);
-    }
-
-    unit->setRange(0, totalSize);
-
-    if (!addSingleNALUnit(unit)) {
-        return MALFORMED_PACKET;
-    }
-
-    LOGV("successfully assembled a NAL unit from fragments.");
-
-    return OK;
-}
-
-bool AAVCAssembler::submitAccessUnit() {
-    MOZ_ASSERT(!mNALUnits.empty());
-
-    LOGV("Access unit complete (%d nal units)", mNALUnits.size());
-
-    size_t totalSize = 0;
-    for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
-         it != mNALUnits.end(); ++it) {
-        totalSize += 4 + (*it)->size();
-    }
-
-    sp<ABuffer> accessUnit = new ABuffer(totalSize);
-    size_t offset = 0;
-    for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
-         it != mNALUnits.end(); ++it) {
-        memcpy(accessUnit->data() + offset, "\x00\x00\x00\x01", 4);
-        offset += 4;
-
-        sp<ABuffer> nal = *it;
-        memcpy(accessUnit->data() + offset, nal->data(), nal->size());
-        offset += nal->size();
-    }
-
-    if (!CopyTimes(accessUnit, *mNALUnits.begin())) {
-        return false;
-    }
-
-#if 0
-    printf(mAccessUnitDamaged ? "X" : ".");
-    fflush(stdout);
-#endif
-
-    if (mAccessUnitDamaged) {
-        accessUnit->meta()->setInt32("damaged", true);
-    }
-
-    mNALUnits.clear();
-    mAccessUnitDamaged = false;
-
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setObject("access-unit", accessUnit);
-    msg->post();
-    return true;
-}
-
-ARTPAssembler::AssemblyStatus AAVCAssembler::assembleMore(
-        const sp<ARTPSource> &source) {
-    AssemblyStatus status = addNALUnit(source);
-    if (status == MALFORMED_PACKET) {
-        mAccessUnitDamaged = true;
-    }
-    return status;
-}
-
-void AAVCAssembler::packetLost() {
-    CHECK(mNextExpectedSeqNoValid);
-    LOGV("packetLost (expected %d)", mNextExpectedSeqNo);
-
-    ++mNextExpectedSeqNo;
-
-    mAccessUnitDamaged = true;
-}
-
-void AAVCAssembler::onByeReceived() {
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setInt32("eos", true);
-    msg->post();
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AAVCAssembler.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_AVC_ASSEMBLER_H_
-
-#define A_AVC_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct MOZ_EXPORT AMessage;
-
-struct AAVCAssembler : public ARTPAssembler {
-    AAVCAssembler(const sp<AMessage> &notify);
-
-protected:
-    virtual ~AAVCAssembler();
-
-    virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
-    virtual void onByeReceived();
-    virtual void packetLost();
-
-private:
-    sp<AMessage> mNotifyMsg;
-
-    uint32_t mAccessUnitRTPTime;
-    bool mNextExpectedSeqNoValid;
-    uint32_t mNextExpectedSeqNo;
-    bool mAccessUnitDamaged;
-    List<sp<ABuffer> > mNALUnits;
-
-    AssemblyStatus addNALUnit(const sp<ARTPSource> &source);
-    bool addSingleNALUnit(const sp<ABuffer> &buffer);
-    AssemblyStatus addFragmentedNALUnit(List<sp<ABuffer> > *queue);
-    bool addSingleTimeAggregationPacket(const sp<ABuffer> &buffer);
-
-    bool submitAccessUnit();
-
-    DISALLOW_EVIL_CONSTRUCTORS(AAVCAssembler);
-};
-
-}  // namespace android
-
-#endif  // A_AVC_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AH263Assembler.cpp
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "AH263Assembler.h"
-
-#include "ARTPSource.h"
-#include "RtspPrlog.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/Utils.h>
-
-namespace android {
-
-AH263Assembler::AH263Assembler(const sp<AMessage> &notify)
-    : mNotifyMsg(notify),
-      mAccessUnitRTPTime(0),
-      mNextExpectedSeqNoValid(false),
-      mNextExpectedSeqNo(0),
-      mAccessUnitDamaged(false) {
-}
-
-AH263Assembler::~AH263Assembler() {
-}
-
-ARTPAssembler::AssemblyStatus AH263Assembler::assembleMore(
-        const sp<ARTPSource> &source) {
-    AssemblyStatus status = addPacket(source);
-    if (status == MALFORMED_PACKET) {
-        mAccessUnitDamaged = true;
-    }
-    return status;
-}
-
-ARTPAssembler::AssemblyStatus AH263Assembler::addPacket(
-        const sp<ARTPSource> &source) {
-    List<sp<ABuffer> > *queue = source->queue();
-
-    if (queue->empty()) {
-        return NOT_ENOUGH_DATA;
-    }
-
-    if (mNextExpectedSeqNoValid) {
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
-                break;
-            }
-
-            it = queue->erase(it);
-        }
-
-        if (queue->empty()) {
-            return NOT_ENOUGH_DATA;
-        }
-    }
-
-    sp<ABuffer> buffer = *queue->begin();
-
-    if (!mNextExpectedSeqNoValid) {
-        mNextExpectedSeqNoValid = true;
-        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
-    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-#if VERBOSE
-        LOG(VERBOSE) << "Not the sequence number I expected";
-#endif
-
-        return WRONG_SEQUENCE_NUMBER;
-    }
-
-    uint32_t rtpTime;
-    if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        LOGW("Cannot find rtp-time. Malformed packet.");
-
-        return MALFORMED_PACKET;
-    }
-
-    if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
-        if (!submitAccessUnit()) {
-            queue->erase(queue->begin());
-            ++mNextExpectedSeqNo;
-
-            LOGW("Cannot find rtp-time. Malformed packet.");
-
-            return MALFORMED_PACKET;
-        }
-    }
-    mAccessUnitRTPTime = rtpTime;
-
-    // hexdump(buffer->data(), buffer->size());
-
-    if (buffer->size() < 2) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-
-        return MALFORMED_PACKET;
-    }
-
-    // RFC 4629, Sec. 5.1 General H.263+ Payload Header.
-    // The H.263+ payload header is structured as follows:
-    //  0                   1
-    //  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    // |   RR    |P|V|   PLEN    |PEBIT|
-    // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    //
-    // RR: 5 bits
-    //     Reserved bits. It SHALL be zero and MUST be ignored by receivers.
-    // P: 1 bit
-    //     Indicates the picture start or a picture segment (GOB/Slice) start or
-    //     a video sequence end (EOS or EOSBS). Two bytes of zero bits then have
-    //     to be prefixed to the payload of such a packet to compose a complete
-    //     picture/GOB/slice/EOS/EOSBS start code. This bit allows the omission
-    //     of the two first bytes of the start code, thus improving the
-    //     compression ratio.
-    // V: 1 bit
-    //     Indicates the presence of an 8-bit field containing information for
-    //     Video Redundancy Coding (VRC), which follows immediately after the
-    //     initial 16 bits of the payload header.
-    // PLEN: 6 bits
-    //     Length, in bytes, of the extra picture header. If no extra picture
-    //     header is attached, PLEN is 0. If PLEN>0, the extra picture header is
-    //     attached immediately following the rest of the payload header. Note
-    //     that the length reflects the omission of the first two bytes of the
-    //     picture start code (PSC).
-    // PEBIT: 3 bits
-    //     Indicates the number of bits that shall be ignored in the last byte
-    //     of the picture header. If PLEN is not zero, the ignored bits shall be
-    //     the least significant bits of the byte. If PLEN is zero, then PEBIT
-    //     shall also be zero.
-
-    unsigned payloadHeader = U16_AT(buffer->data());
-    unsigned P = (payloadHeader >> 10) & 1;
-    unsigned V = (payloadHeader >> 9) & 1;
-    unsigned PLEN = (payloadHeader >> 3) & 0x3f;
-    unsigned PEBIT = payloadHeader & 7;
-
-    // V = 0
-    // We do not support VRC header extension for now, so just discard it if
-    // present.
-    if (V != 0u) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-        LOGW("Packet discarded due to VRC (V != 0)");
-        return MALFORMED_PACKET;
-    }
-
-    // If PLEN is zero, then PEBIT shall also be zero.
-    if (PLEN == 0u && PEBIT != 0u) {
-        queue->erase(queue->begin());
-        ++mNextExpectedSeqNo;
-        LOGW("Packet discarded (PEBIT != 0)");
-        return MALFORMED_PACKET;
-    }
-
-    size_t skip = PLEN + (P ? 0: 2);
-
-    buffer->setRange(buffer->offset() + skip, buffer->size() - skip);
-
-    if (P) {
-        buffer->data()[0] = 0x00;
-        buffer->data()[1] = 0x00;
-    }
-
-    mPackets.push_back(buffer);
-
-    queue->erase(queue->begin());
-    ++mNextExpectedSeqNo;
-
-    return OK;
-}
-
-bool AH263Assembler::submitAccessUnit() {
-    MOZ_ASSERT(!mPackets.empty());
-
-#if VERBOSE
-    LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
-#endif
-
-    size_t totalSize = 0;
-    List<sp<ABuffer> >::iterator it = mPackets.begin();
-    while (it != mPackets.end()) {
-        const sp<ABuffer> &unit = *it;
-
-        totalSize += unit->size();
-        ++it;
-    }
-
-    sp<ABuffer> accessUnit = new ABuffer(totalSize);
-    size_t offset = 0;
-    it = mPackets.begin();
-    while (it != mPackets.end()) {
-        const sp<ABuffer> &unit = *it;
-
-        memcpy((uint8_t *)accessUnit->data() + offset,
-               unit->data(), unit->size());
-
-        offset += unit->size();
-
-        ++it;
-    }
-
-    if (!CopyTimes(accessUnit, *mPackets.begin())) {
-        return false;
-    }
-
-#if 0
-    printf(mAccessUnitDamaged ? "X" : ".");
-    fflush(stdout);
-#endif
-
-    if (mAccessUnitDamaged) {
-        accessUnit->meta()->setInt32("damaged", true);
-    }
-
-    mPackets.clear();
-    mAccessUnitDamaged = false;
-
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setObject("access-unit", accessUnit);
-    msg->post();
-
-    return true;
-}
-
-void AH263Assembler::packetLost() {
-    CHECK(mNextExpectedSeqNoValid);
-    ++mNextExpectedSeqNo;
-
-    mAccessUnitDamaged = true;
-}
-
-void AH263Assembler::onByeReceived() {
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setInt32("eos", true);
-    msg->post();
-}
-
-}  // namespace android
-
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AH263Assembler.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_H263_ASSEMBLER_H_
-
-#define A_H263_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-
-#include <stdint.h>
-
-namespace android {
-
-struct MOZ_EXPORT AMessage;
-
-struct AH263Assembler : public ARTPAssembler {
-    AH263Assembler(const sp<AMessage> &notify);
-
-protected:
-    virtual ~AH263Assembler();
-
-    virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
-    virtual void onByeReceived();
-    virtual void packetLost();
-
-private:
-    sp<AMessage> mNotifyMsg;
-    uint32_t mAccessUnitRTPTime;
-    bool mNextExpectedSeqNoValid;
-    uint32_t mNextExpectedSeqNo;
-    bool mAccessUnitDamaged;
-    List<sp<ABuffer> > mPackets;
-
-    AssemblyStatus addPacket(const sp<ARTPSource> &source);
-    bool submitAccessUnit();
-
-    DISALLOW_EVIL_CONSTRUCTORS(AH263Assembler);
-};
-
-}  // namespace android
-
-#endif  // A_H263_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4AudioAssembler.cpp
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AMPEG4AudioAssembler"
-#include "RtspPrlog.h"
-
-#include "AMPEG4AudioAssembler.h"
-
-#include "ARTPSource.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/MediaErrors.h>
-
-#include <ctype.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
-    value->clear();
-
-    size_t keyLen = strlen(key);
-
-    for (;;) {
-        while (isspace(*s)) {
-            ++s;
-        }
-
-        const char *colonPos = strchr(s, ';');
-
-        size_t len =
-            (colonPos == NULL) ? strlen(s) : colonPos - s;
-
-        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
-            value->setTo(&s[keyLen + 1], len - keyLen - 1);
-            return true;
-        }
-
-        if (colonPos == NULL) {
-            return false;
-        }
-
-        s = colonPos + 1;
-    }
-}
-
-static sp<ABuffer> decodeHex(const AString &s) {
-    if ((s.size() % 2) != 0) {
-        return NULL;
-    }
-
-    size_t outLen = s.size() / 2;
-    sp<ABuffer> buffer = new ABuffer(outLen);
-    uint8_t *out = buffer->data();
-
-    uint8_t accum = 0;
-    for (size_t i = 0; i < s.size(); ++i) {
-        char c = s.c_str()[i];
-        unsigned value;
-        if (c >= '0' && c <= '9') {
-            value = c - '0';
-        } else if (c >= 'a' && c <= 'f') {
-            value = c - 'a' + 10;
-        } else if (c >= 'A' && c <= 'F') {
-            value = c - 'A' + 10;
-        } else {
-            return NULL;
-        }
-
-        accum = (accum << 4) | value;
-
-        if (i & 1) {
-            *out++ = accum;
-
-            accum = 0;
-        }
-    }
-
-    return buffer;
-}
-
-static status_t parseAudioObjectType(
-        ABitReader *bits, unsigned *audioObjectType) {
-    *audioObjectType = bits->getBits(5);
-    if ((*audioObjectType) == 31) {
-        *audioObjectType = 32 + bits->getBits(6);
-    }
-
-    return OK;
-}
-
-static status_t parseGASpecificConfig(
-        ABitReader *bits,
-        unsigned audioObjectType, unsigned channelConfiguration) {
-    /*unsigned frameLengthFlag = */bits->getBits(1);
-    unsigned dependsOnCoreCoder = bits->getBits(1);
-    if (dependsOnCoreCoder) {
-        /* unsigned coreCoderDelay = */bits->getBits(1);
-    }
-    unsigned extensionFlag = bits->getBits(1);
-
-    if (!channelConfiguration) {
-        // program_config_element
-        return ERROR_UNSUPPORTED;  // XXX to be implemented
-    }
-
-    if (audioObjectType == 6 || audioObjectType == 20) {
-        /* unsigned layerNr = */bits->getBits(3);
-    }
-
-    if (extensionFlag) {
-        if (audioObjectType == 22) {
-            /* unsigned numOfSubFrame = */bits->getBits(5);
-            /* unsigned layerLength = */bits->getBits(11);
-        } else if (audioObjectType == 17 || audioObjectType == 19
-                || audioObjectType == 20 || audioObjectType == 23) {
-            /* unsigned aacSectionDataResilienceFlag = */bits->getBits(1);
-            /* unsigned aacScalefactorDataResilienceFlag = */bits->getBits(1);
-            /* unsigned aacSpectralDataResilienceFlag = */bits->getBits(1);
-        }
-
-        unsigned extensionFlag3 = bits->getBits(1);
-        if (extensionFlag3 != 0u) {
-            return ERROR_UNSUPPORTED; // TBD in version 3
-        }
-    }
-
-    return OK;
-}
-
-static status_t parseAudioSpecificConfig(ABitReader *bits, sp<ABuffer> *asc) {
-    const uint8_t *dataStart = bits->data();
-    size_t totalNumBits = bits->numBitsLeft();
-
-    unsigned audioObjectType;
-    if (parseAudioObjectType(bits, &audioObjectType) != (status_t)OK) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    unsigned samplingFreqIndex = bits->getBits(4);
-    if (samplingFreqIndex == 0x0f) {
-        /* unsigned samplingFrequency = */bits->getBits(24);
-    }
-
-    unsigned channelConfiguration = bits->getBits(4);
-
-    unsigned extensionAudioObjectType = 0;
-    unsigned sbrPresent = 0;
-
-    if (audioObjectType == 5) {
-        extensionAudioObjectType = audioObjectType;
-        sbrPresent = 1;
-        unsigned extensionSamplingFreqIndex = bits->getBits(4);
-        if (extensionSamplingFreqIndex == 0x0f) {
-            /* unsigned extensionSamplingFrequency = */bits->getBits(24);
-        }
-        if (parseAudioObjectType(bits, &audioObjectType) != (status_t)OK) {
-            return ERROR_UNSUPPORTED;
-        }
-    }
-
-    if (!((audioObjectType >= 1 && audioObjectType <= 4) ||
-          (audioObjectType >= 6 && audioObjectType <= 7) ||
-          audioObjectType == 17 ||
-          (audioObjectType >= 19 && audioObjectType <= 23))) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    if (parseGASpecificConfig(bits, audioObjectType, channelConfiguration)
-        != (status_t)OK) {
-        return ERROR_UNSUPPORTED;
-    }
-
-    if (audioObjectType == 17
-            || (audioObjectType >= 19 && audioObjectType <= 27)) {
-        unsigned epConfig = bits->getBits(2);
-        if (epConfig == 2 || epConfig == 3) {
-            // ErrorProtectionSpecificConfig
-            return ERROR_UNSUPPORTED;  // XXX to be implemented
-
-            if (epConfig == 3) {
-                unsigned directMapping = bits->getBits(1);
-                if (directMapping != 1u) {
-                    return ERROR_UNSUPPORTED;
-                }
-            }
-        }
-    }
-
-    if (extensionAudioObjectType != 5 && bits->numBitsLeft() >= 16) {
-        size_t numBitsLeftAtStart = bits->numBitsLeft();
-
-        unsigned syncExtensionType = bits->getBits(11);
-        if (syncExtensionType == 0x2b7) {
-            LOGI("found syncExtension");
-
-            if (parseAudioObjectType(bits, &extensionAudioObjectType)
-                != (status_t)OK) {
-                return ERROR_UNSUPPORTED;
-            }
-
-            sbrPresent = bits->getBits(1);
-
-            if (sbrPresent == 1) {
-                unsigned extensionSamplingFreqIndex = bits->getBits(4);
-                if (extensionSamplingFreqIndex == 0x0f) {
-                    /* unsigned extensionSamplingFrequency = */bits->getBits(24);
-                }
-            }
-
-            size_t numBitsInExtension =
-                numBitsLeftAtStart - bits->numBitsLeft();
-
-            if (numBitsInExtension & 7) {
-                // Apparently an extension is always considered an even
-                // multiple of 8 bits long.
-
-                LOGI("Skipping %d bits after sync extension",
-                     8 - (numBitsInExtension & 7));
-
-                bits->skipBits(8 - (numBitsInExtension & 7));
-            }
-        } else {
-            bits->putBits(syncExtensionType, 11);
-        }
-    }
-
-    if (asc != NULL) {
-        size_t bitpos = totalNumBits & 7;
-
-        ABitReader bs(dataStart, (totalNumBits + 7) / 8);
-
-        totalNumBits -= bits->numBitsLeft();
-
-        size_t numBytes = (totalNumBits + 7) / 8;
-
-        *asc = new ABuffer(numBytes);
-
-        if (bitpos & 7) {
-            bs.skipBits(8 - (bitpos & 7));
-        }
-
-        uint8_t *dstPtr = (*asc)->data();
-        while (numBytes > 0) {
-            *dstPtr++ = bs.getBits(8);
-            --numBytes;
-        }
-    }
-
-    return OK;
-}
-
-static status_t parseStreamMuxConfig(
-        ABitReader *bits,
-        unsigned *numSubFrames,
-        unsigned *frameLengthType,
-        ssize_t *fixedFrameLength,
-        bool *otherDataPresent,
-        unsigned *otherDataLenBits) {
-    unsigned audioMuxVersion = bits->getBits(1);
-
-    unsigned audioMuxVersionA = 0;
-    if (audioMuxVersion == 1) {
-        audioMuxVersionA = bits->getBits(1);
-    }
-
-    if (audioMuxVersionA != 0u) {
-        return ERROR_UNSUPPORTED;  // future spec
-    }
-
-    if (audioMuxVersion != 0u) {
-        return ERROR_UNSUPPORTED;  // XXX to be implemented;
-    }
-
-    unsigned allStreamsSameTimeFraming = bits->getBits(1);
-    if (allStreamsSameTimeFraming != 1u) {
-        return ERROR_UNSUPPORTED;  // There's only one stream.
-    }
-
-    *numSubFrames = bits->getBits(6);
-    unsigned numProgram = bits->getBits(4);
-    if (numProgram != 0u) {
-        return ERROR_UNSUPPORTED;  // disabled in RTP LATM
-    }
-
-    unsigned numLayer = bits->getBits(3);
-    if (numLayer != 0u) {
-        return ERROR_UNSUPPORTED;  // disabled in RTP LATM
-    }
-
-    if (audioMuxVersion == 0) {
-        // AudioSpecificConfig
-        if (parseAudioSpecificConfig(bits, NULL /* asc */) != (status_t)OK) {
-            return ERROR_UNSUPPORTED;
-        }
-    } else {
-        return ERROR_UNSUPPORTED; // XXX to be implemented
-    }
-
-    *frameLengthType = bits->getBits(3);
-    *fixedFrameLength = -1;
-
-    switch (*frameLengthType) {
-        case 0:
-        {
-            /* unsigned bufferFullness = */bits->getBits(8);
-
-            // The "coreFrameOffset" does not apply since there's only
-            // a single layer.
-            break;
-        }
-
-        case 1:
-        {
-            *fixedFrameLength = bits->getBits(9);
-            break;
-        }
-
-        case 2:
-        {
-            // reserved
-            TRESPASS();
-            break;
-        }
-
-        case 3:
-        case 4:
-        case 5:
-        {
-            /* unsigned CELPframeLengthTableIndex = */bits->getBits(6);
-            break;
-        }
-
-        case 6:
-        case 7:
-        {
-            /* unsigned HVXCframeLengthTableIndex = */bits->getBits(1);
-            break;
-        }
-
-        default:
-            break;
-    }
-
-    *otherDataPresent = bits->getBits(1);
-    *otherDataLenBits = 0;
-    if (*otherDataPresent) {
-        if (audioMuxVersion == 1) {
-            return ERROR_UNSUPPORTED;  // XXX to be implemented
-        } else {
-            *otherDataLenBits = 0;
-
-            unsigned otherDataLenEsc;
-            do {
-                (*otherDataLenBits) <<= 8;
-                otherDataLenEsc = bits->getBits(1);
-                unsigned otherDataLenTmp = bits->getBits(8);
-                (*otherDataLenBits) += otherDataLenTmp;
-            } while (otherDataLenEsc);
-        }
-    }
-
-    unsigned crcCheckPresent = bits->getBits(1);
-    if (crcCheckPresent) {
-        /* unsigned crcCheckSum = */bits->getBits(8);
-    }
-
-    return OK;
-}
-
-sp<ABuffer> AMPEG4AudioAssembler::removeLATMFraming(const sp<ABuffer> &buffer) {
-    if (mMuxConfigPresent) {
-        return NULL;  // XXX to be implemented
-    }
-
-    sp<ABuffer> out = new ABuffer(buffer->size());
-    out->setRange(0, 0);
-
-    size_t offset = 0;
-    uint8_t *ptr = buffer->data();
-
-    for (size_t i = 0; i <= mNumSubFrames; ++i) {
-        // parse PayloadLengthInfo
-
-        unsigned payloadLength = 0;
-
-        switch (mFrameLengthType) {
-            case 0:
-            {
-                unsigned muxSlotLengthBytes = 0;
-                unsigned tmp;
-                do {
-                    if (offset >= buffer->size()) {
-                        LOGI("Malformed packet found in removeLATMFraming");
-                        mAccessUnitDamaged = true;
-                        return out;
-                    }
-                    tmp = ptr[offset++];
-                    muxSlotLengthBytes += tmp;
-                } while (tmp == 0xff);
-
-                payloadLength = muxSlotLengthBytes;
-                break;
-            }
-
-            case 2:
-            {
-                // reserved
-
-                TRESPASS();
-                break;
-            }
-
-            default:
-            {
-                if (mFixedFrameLength < 0) {
-                    return NULL;
-                }
-
-                payloadLength = mFixedFrameLength;
-                break;
-            }
-        }
-
-        if ((offset + payloadLength) > buffer->size()) {
-            LOGI("Malformed packet found in removeLATMFraming");
-            mAccessUnitDamaged = true;
-            return out;
-        }
-
-        memcpy(out->data() + out->size(), &ptr[offset], payloadLength);
-        out->setRange(0, out->size() + payloadLength);
-
-        offset += payloadLength;
-
-        if (mOtherDataPresent) {
-            // We want to stay byte-aligned.
-
-            if (mOtherDataLenBits % 8 != 0) {
-                mAccessUnitDamaged = true;
-                return out;
-            }
-            if (offset + (mOtherDataLenBits / 8) > buffer->size()) {
-                mAccessUnitDamaged = true;
-                return out;
-            }
-            offset += mOtherDataLenBits / 8;
-        }
-    }
-
-    if (offset < buffer->size()) {
-        LOGI("ignoring %d bytes of trailing data", buffer->size() - offset);
-    }
-    CHECK_LE(offset, buffer->size());
-
-    return out;
-}
-
-AMPEG4AudioAssembler::AMPEG4AudioAssembler(
-        const sp<AMessage> &notify, const AString &params)
-    : mNotifyMsg(notify),
-      mMuxConfigPresent(false),
-      mAccessUnitRTPTime(0),
-      mNextExpectedSeqNoValid(false),
-      mNextExpectedSeqNo(0),
-      mAccessUnitDamaged(false) {
-    AString val;
-    if (!GetAttribute(params.c_str(), "cpresent", &val)) {
-        mMuxConfigPresent = true;
-    } else if (val == "0") {
-        mMuxConfigPresent = false;
-    } else {
-        CHECK(val == "1");
-        mMuxConfigPresent = true;
-    }
-
-    CHECK(GetAttribute(params.c_str(), "config", &val));
-
-    sp<ABuffer> config = decodeHex(val);
-    CHECK(config != NULL);
-
-    ABitReader bits(config->data(), config->size());
-    status_t err = parseStreamMuxConfig(
-            &bits, &mNumSubFrames, &mFrameLengthType,
-            &mFixedFrameLength,
-            &mOtherDataPresent, &mOtherDataLenBits);
-
-    CHECK_EQ(err, (status_t)NO_ERROR);
-}
-
-AMPEG4AudioAssembler::~AMPEG4AudioAssembler() {
-}
-
-ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::assembleMore(
-        const sp<ARTPSource> &source) {
-    AssemblyStatus status = addPacket(source);
-    if (status == MALFORMED_PACKET) {
-        mAccessUnitDamaged = true;
-    }
-    return status;
-}
-
-ARTPAssembler::AssemblyStatus AMPEG4AudioAssembler::addPacket(
-        const sp<ARTPSource> &source) {
-    List<sp<ABuffer> > *queue = source->queue();
-
-    if (queue->empty()) {
-        return NOT_ENOUGH_DATA;
-    }
-
-    if (mNextExpectedSeqNoValid) {
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
-                break;
-            }
-
-            it = queue->erase(it);
-        }
-
-        if (queue->empty()) {
-            return NOT_ENOUGH_DATA;
-        }
-    }
-
-    sp<ABuffer> buffer = *queue->begin();
-
-    if (!mNextExpectedSeqNoValid) {
-        mNextExpectedSeqNoValid = true;
-        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
-    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-#if VERBOSE
-        LOG(VERBOSE) << "Not the sequence number I expected";
-#endif
-
-        return WRONG_SEQUENCE_NUMBER;
-    }
-
-    uint32_t rtpTime;
-    if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
-        LOGW("Cannot find rtp-time. Malformed packet.");
-
-        return MALFORMED_PACKET;
-    }
-
-    if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
-        if (!submitAccessUnit()) {
-            LOGW("Cannot find rtp-time. Malformed packet.");
-            return MALFORMED_PACKET;
-        }
-    }
-    mAccessUnitRTPTime = rtpTime;
-
-    mPackets.push_back(buffer);
-
-    queue->erase(queue->begin());
-    ++mNextExpectedSeqNo;
-
-    return OK;
-}
-
-bool AMPEG4AudioAssembler::submitAccessUnit() {
-    MOZ_ASSERT(!mPackets.empty());
-
-#if VERBOSE
-    LOG(VERBOSE) << "Access unit complete (" << mPackets.size() << " packets)";
-#endif
-
-    size_t totalSize = 0;
-    List<sp<ABuffer> >::iterator it = mPackets.begin();
-    while (it != mPackets.end()) {
-        const sp<ABuffer> &unit = *it;
-
-        totalSize += unit->size();
-        ++it;
-    }
-
-    sp<ABuffer> accessUnit = new ABuffer(totalSize);
-    size_t offset = 0;
-    it = mPackets.begin();
-    while (it != mPackets.end()) {
-        const sp<ABuffer> &unit = *it;
-
-        memcpy((uint8_t *)accessUnit->data() + offset,
-               unit->data(), unit->size());
-
-        offset += unit->size();
-        ++it;
-    }
-
-    accessUnit = removeLATMFraming(accessUnit);
-    if (!accessUnit.get() || !CopyTimes(accessUnit, *mPackets.begin())) {
-        return false;
-    }
-
-    if (mAccessUnitDamaged) {
-        accessUnit->meta()->setInt32("damaged", true);
-    }
-
-    mPackets.clear();
-    mAccessUnitDamaged = false;
-
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setObject("access-unit", accessUnit);
-    msg->post();
-    return true;
-}
-
-void AMPEG4AudioAssembler::packetLost() {
-    CHECK(mNextExpectedSeqNoValid);
-    ++mNextExpectedSeqNo;
-
-    mAccessUnitDamaged = true;
-}
-
-void AMPEG4AudioAssembler::onByeReceived() {
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setInt32("eos", true);
-    msg->post();
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4AudioAssembler.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_MPEG4_AUDIO_ASSEMBLER_H_
-
-#define A_MPEG4_AUDIO_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <utils/List.h>
-
-#include <stdint.h>
-
-namespace android {
-
-struct MOZ_EXPORT AMessage;
-struct MOZ_EXPORT AString;
-
-struct AMPEG4AudioAssembler : public ARTPAssembler {
-    AMPEG4AudioAssembler(
-            const sp<AMessage> &notify, const AString &params);
-
-protected:
-    virtual ~AMPEG4AudioAssembler();
-
-    virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
-    virtual void onByeReceived();
-    virtual void packetLost();
-
-private:
-    sp<AMessage> mNotifyMsg;
-
-    bool mMuxConfigPresent;
-    unsigned mNumSubFrames;
-    unsigned mFrameLengthType;
-    ssize_t mFixedFrameLength;
-    bool mOtherDataPresent;
-    unsigned mOtherDataLenBits;
-
-    uint32_t mAccessUnitRTPTime;
-    bool mNextExpectedSeqNoValid;
-    uint32_t mNextExpectedSeqNo;
-    bool mAccessUnitDamaged;
-    List<sp<ABuffer> > mPackets;
-
-    AssemblyStatus addPacket(const sp<ARTPSource> &source);
-    bool submitAccessUnit();
-
-    sp<ABuffer> removeLATMFraming(const sp<ABuffer> &buffer);
-
-    DISALLOW_EVIL_CONSTRUCTORS(AMPEG4AudioAssembler);
-};
-
-}  // namespace android
-
-#endif  // A_MPEG4_AUDIO_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4ElementaryAssembler.cpp
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "AMPEG4ElementaryAssembler"
-#include "RtspPrlog.h"
-
-#include "AMPEG4ElementaryAssembler.h"
-
-#include "ARTPSource.h"
-
-#include "mozilla/Assertions.h"
-
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/Utils.h>
-
-#include <ctype.h>
-#include <stdint.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
-    value->clear();
-
-    size_t keyLen = strlen(key);
-
-    for (;;) {
-        while (isspace(*s)) {
-            ++s;
-        }
-
-        const char *colonPos = strchr(s, ';');
-
-        size_t len =
-            (colonPos == NULL) ? strlen(s) : colonPos - s;
-
-        if (len >= keyLen + 1 && s[keyLen] == '='
-                && !strncasecmp(s, key, keyLen)) {
-            value->setTo(&s[keyLen + 1], len - keyLen - 1);
-            return true;
-        }
-
-        if (colonPos == NULL) {
-            return false;
-        }
-
-        s = colonPos + 1;
-    }
-}
-
-static bool GetIntegerAttribute(
-        const char *s, const char *key, unsigned *x) {
-    *x = 0;
-
-    AString val;
-    if (!GetAttribute(s, key, &val)) {
-        return false;
-    }
-
-    s = val.c_str();
-    char *end;
-    unsigned y = strtoul(s, &end, 10);
-
-    if (end == s || *end != '\0') {
-        return false;
-    }
-
-    *x = y;
-
-    return true;
-}
-
-// static
-AMPEG4ElementaryAssembler::AMPEG4ElementaryAssembler(
-        const sp<AMessage> &notify, const AString &desc, const AString &params)
-    : mNotifyMsg(notify),
-      mIsGeneric(false),
-      mParams(params),
-      mSizeLength(0),
-      mIndexLength(0),
-      mIndexDeltaLength(0),
-      mCTSDeltaLength(0),
-      mDTSDeltaLength(0),
-      mRandomAccessIndication(false),
-      mStreamStateIndication(0),
-      mAuxiliaryDataSizeLength(0),
-      mConstantDuration(0),
-      mPreviousAUCount(0),
-      mHasAUHeader(false),
-      mAccessUnitRTPTime(0),
-      mNextExpectedSeqNoValid(false),
-      mNextExpectedSeqNo(0),
-      mAccessUnitDamaged(false) {
-    mIsGeneric = !strncasecmp(desc.c_str(),"mpeg4-generic/", 14);
-
-    if (mIsGeneric) {
-        AString value;
-        CHECK(GetAttribute(params.c_str(), "mode", &value));
-
-        if (!GetIntegerAttribute(params.c_str(), "sizeLength", &mSizeLength)) {
-            mSizeLength = 0;
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "indexLength", &mIndexLength)) {
-            mIndexLength = 0;
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "indexDeltaLength", &mIndexDeltaLength)) {
-            mIndexDeltaLength = 0;
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "CTSDeltaLength", &mCTSDeltaLength)) {
-            mCTSDeltaLength = 0;
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "DTSDeltaLength", &mDTSDeltaLength)) {
-            mDTSDeltaLength = 0;
-        }
-
-        unsigned x;
-        if (!GetIntegerAttribute(
-                    params.c_str(), "randomAccessIndication", &x)) {
-            mRandomAccessIndication = false;
-        } else {
-            CHECK(x == 0 || x == 1);
-            mRandomAccessIndication = (x != 0);
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "streamStateIndication",
-                    &mStreamStateIndication)) {
-            mStreamStateIndication = 0;
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "auxiliaryDataSizeLength",
-                    &mAuxiliaryDataSizeLength)) {
-            mAuxiliaryDataSizeLength = 0;
-        }
-
-        if (!GetIntegerAttribute(
-                    params.c_str(), "constantDuration",
-                    &mConstantDuration)) {
-            mConstantDuration = 0;
-        }
-
-        mHasAUHeader =
-            mSizeLength > 0
-            || mIndexLength > 0
-            || mIndexDeltaLength > 0
-            || mCTSDeltaLength > 0
-            || mDTSDeltaLength > 0
-            || mRandomAccessIndication
-            || mStreamStateIndication > 0;
-    }
-}
-
-AMPEG4ElementaryAssembler::~AMPEG4ElementaryAssembler() {
-}
-
-struct AUHeader {
-    unsigned mSize;
-    unsigned mSerial;
-};
-
-ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
-        const sp<ARTPSource> &source) {
-    List<sp<ABuffer> > *queue = source->queue();
-
-    if (queue->empty()) {
-        return NOT_ENOUGH_DATA;
-    }
-
-    if (mNextExpectedSeqNoValid) {
-        List<sp<ABuffer> >::iterator it = queue->begin();
-        while (it != queue->end()) {
-            if ((uint32_t)(*it)->int32Data() >= mNextExpectedSeqNo) {
-                break;
-            }
-
-            it = queue->erase(it);
-        }
-
-        if (queue->empty()) {
-            return NOT_ENOUGH_DATA;
-        }
-    }
-
-    sp<ABuffer> buffer = *queue->begin();
-
-    if (!mNextExpectedSeqNoValid) {
-        mNextExpectedSeqNoValid = true;
-        mNextExpectedSeqNo = (uint32_t)buffer->int32Data();
-    } else if ((uint32_t)buffer->int32Data() != mNextExpectedSeqNo) {
-        LOGV("Not the sequence number I expected");
-
-        return WRONG_SEQUENCE_NUMBER;
-    }
-
-    uint32_t rtpTime;
-    if (!buffer->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
-        LOGW("Cannot find rtp-time. Malformed packet.");
-
-        return MALFORMED_PACKET;
-    }
-
-    if (mPackets.size() > 0 && rtpTime != mAccessUnitRTPTime) {
-        if (!submitAccessUnit()) {
-            LOGW("Cannot find rtp-time. Malformed packet.");
-
-            return MALFORMED_PACKET;
-        }
-    }
-
-    // If constantDuration and CTSDelta are not present. We should assume the
-    // stream has fixed duration and calculate the mConstantDuration.
-    if (!mConstantDuration && !mCTSDeltaLength && mPreviousAUCount
-        && rtpTime > mAccessUnitRTPTime) {
-        mConstantDuration = (rtpTime - mAccessUnitRTPTime) / mPreviousAUCount;
-    }
-
-    mAccessUnitRTPTime = rtpTime;
-
-    if (!mIsGeneric) {
-        mPackets.push_back(buffer);
-    } else {
-        // hexdump(buffer->data(), buffer->size());
-
-        if (buffer->size() < 2u) {
-            LOGW("Payload format error. Malformed packet.");
-
-            return MALFORMED_PACKET;
-        }
-        unsigned AU_headers_length = U16_AT(buffer->data());  // in bits
-
-        if (buffer->size() < 2 + (AU_headers_length + 7) / 8) {
-            LOGW("Payload format error. Malformed packet.");
-
-            return MALFORMED_PACKET;
-        }
-
-        List<AUHeader> headers;
-
-        ABitReader bits(buffer->data() + 2, buffer->size() - 2);
-        unsigned numBitsLeft = AU_headers_length;
-
-        unsigned AU_serial = 0;
-        for (;;) {
-            if (numBitsLeft < mSizeLength) { break; }
-
-            unsigned AU_size = bits.getBits(mSizeLength);
-            numBitsLeft -= mSizeLength;
-
-            size_t n = headers.empty() ? mIndexLength : mIndexDeltaLength;
-            if (numBitsLeft < n) { break; }
-
-            unsigned AU_index = bits.getBits(n);
-            numBitsLeft -= n;
-
-            if (headers.empty()) {
-                AU_serial = AU_index;
-            } else {
-                AU_serial += 1 + AU_index;
-            }
-
-            if (mCTSDeltaLength > 0) {
-                if (numBitsLeft < 1) {
-                    break;
-                }
-                --numBitsLeft;
-                if (bits.getBits(1)) {
-                    if (numBitsLeft < mCTSDeltaLength) {
-                        break;
-                    }
-                    bits.skipBits(mCTSDeltaLength);
-                    numBitsLeft -= mCTSDeltaLength;
-                }
-            }
-
-            if (mDTSDeltaLength > 0) {
-                if (numBitsLeft < 1) {
-                    break;
-                }
-                --numBitsLeft;
-                if (bits.getBits(1)) {
-                    if (numBitsLeft < mDTSDeltaLength) {
-                        break;
-                    }
-                    bits.skipBits(mDTSDeltaLength);
-                    numBitsLeft -= mDTSDeltaLength;
-                }
-            }
-
-            if (mRandomAccessIndication) {
-                if (numBitsLeft < 1) {
-                    break;
-                }
-                bits.skipBits(1);
-                --numBitsLeft;
-            }
-
-            if (mStreamStateIndication > 0) {
-                if (numBitsLeft < mStreamStateIndication) {
-                    break;
-                }
-                bits.skipBits(mStreamStateIndication);
-            }
-
-            AUHeader header;
-            header.mSize = AU_size;
-            header.mSerial = AU_serial;
-            headers.push_back(header);
-        }
-
-        size_t offset = 2 + (AU_headers_length + 7) / 8;
-
-        if (mAuxiliaryDataSizeLength > 0) {
-            ABitReader bits(buffer->data() + offset, buffer->size() - offset);
-
-            unsigned auxSize = bits.getBits(mAuxiliaryDataSizeLength);
-
-            offset += (mAuxiliaryDataSizeLength + auxSize + 7) / 8;
-        }
-
-        mPreviousAUCount = 0;
-        for (List<AUHeader>::iterator it = headers.begin();
-             it != headers.end(); ++it) {
-            mPreviousAUCount++;
-            const AUHeader &header = *it;
-            const AUHeader &first = *headers.begin();
-            if (offset + header.mSize > buffer->size()) {
-                LOGW("Payload format error. Malformed packet.");
-
-                return MALFORMED_PACKET;
-            }
-
-            sp<ABuffer> accessUnit = new ABuffer(header.mSize);
-            memcpy(accessUnit->data(), buffer->data() + offset, header.mSize);
-
-            offset += header.mSize;
-
-            int rtpTime = mAccessUnitRTPTime +
-                          mConstantDuration * (header.mSerial - first.mSerial);
-            accessUnit->meta()->setInt32("rtp-time", rtpTime);
-            accessUnit->setInt32Data(buffer->int32Data());
-
-            mPackets.push_back(accessUnit);
-        }
-
-        if (offset != buffer->size()) {
-            LOGW("Payload format error. Malformed packet.");
-
-            return MALFORMED_PACKET;
-        }
-    }
-
-    queue->erase(queue->begin());
-    ++mNextExpectedSeqNo;
-
-    return OK;
-}
-
-bool AMPEG4ElementaryAssembler::submitAccessUnit() {
-    MOZ_ASSERT(mPackets.empty());
-
-    LOGV("Access unit complete (%d nal units)", mPackets.size());
-
-    if (mIsGeneric) {
-        /*
-         * Bug 877116.
-         * In order to remedy a latency problem caused by hardware decoder for
-         * mpeg4-generic audios, we artificially divide AUs into more smaller
-         * AUs before feeding them to decoder.
-         *
-         * TODO: However, we are not sure this solution is appropriate to video
-         * or not. Need more investigation on this. Refer to RFC 3640.
-         */
-        for (List<sp<ABuffer> >::iterator it = mPackets.begin();
-             it != mPackets.end(); ++it) {
-            sp<ABuffer> accessUnit = new ABuffer((*it)->size());
-            sp<ABuffer> nal = *it;
-            memcpy(accessUnit->data(), nal->data(), nal->size());
-            if (!CopyTimes(accessUnit, nal)) {
-                return false;
-            }
-
-            if (mAccessUnitDamaged) {
-                accessUnit->meta()->setInt32("damaged", true);
-            }
-
-            sp<AMessage> msg = mNotifyMsg->dup();
-            msg->setObject("access-unit", accessUnit);
-            msg->post();
-        }
-    } else {
-        /*
-         * For MP4V-ES (MPEG-4 Visual Elementary Streams), NAL units with the
-         * same RTP timestamp are assembled into an AU, which results in one
-         * decoded picture (RFC 6416).
-         */
-        size_t totalSize = 0;
-
-        for (List<sp<ABuffer> >::iterator it = mPackets.begin();
-             it != mPackets.end(); ++it) {
-            totalSize += (*it)->size();
-        }
-        sp<ABuffer> accessUnit = new ABuffer(totalSize);
-        size_t offset = 0;
-        for (List<sp<ABuffer> >::iterator it = mPackets.begin();
-             it != mPackets.end(); ++it) {
-            sp<ABuffer> nal = *it;
-            memcpy(accessUnit->data() + offset, nal->data(), nal->size());
-            offset += nal->size();
-        }
-        if (!CopyTimes(accessUnit, *mPackets.begin())) {
-            return false;
-        }
-
-        if (mAccessUnitDamaged) {
-            accessUnit->meta()->setInt32("damaged", true);
-        }
-
-        sp<AMessage> msg = mNotifyMsg->dup();
-        msg->setObject("access-unit", accessUnit);
-        msg->post();
-    }
-
-    mPackets.clear();
-    mAccessUnitDamaged = false;
-    return true;
-}
-
-ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::assembleMore(
-        const sp<ARTPSource> &source) {
-    AssemblyStatus status = addPacket(source);
-    if (status == MALFORMED_PACKET) {
-        mAccessUnitDamaged = true;
-    }
-    return status;
-}
-
-void AMPEG4ElementaryAssembler::packetLost() {
-    CHECK(mNextExpectedSeqNoValid);
-    LOGV("packetLost (expected %d)", mNextExpectedSeqNo);
-
-    ++mNextExpectedSeqNo;
-
-    mAccessUnitDamaged = true;
-
-    mPreviousAUCount = 0;
-}
-
-void AMPEG4ElementaryAssembler::onByeReceived() {
-    sp<AMessage> msg = mNotifyMsg->dup();
-    msg->setInt32("eos", true);
-    msg->post();
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/AMPEG4ElementaryAssembler.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_MPEG4_ELEM_ASSEMBLER_H_
-
-#define A_MPEG4_ELEM_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include "ARTPAssembler.h"
-
-#include <media/stagefright/foundation/AString.h>
-
-#include <utils/List.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct MOZ_EXPORT AMessage;
-
-struct AMPEG4ElementaryAssembler : public ARTPAssembler {
-    AMPEG4ElementaryAssembler(
-            const sp<AMessage> &notify, const AString &desc,
-            const AString &params);
-
-protected:
-    virtual ~AMPEG4ElementaryAssembler();
-
-    virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source);
-    virtual void onByeReceived();
-    virtual void packetLost();
-
-private:
-    sp<AMessage> mNotifyMsg;
-    bool mIsGeneric;
-    AString mParams;
-
-    unsigned mSizeLength;
-    unsigned mIndexLength;
-    unsigned mIndexDeltaLength;
-    unsigned mCTSDeltaLength;
-    unsigned mDTSDeltaLength;
-    bool mRandomAccessIndication;
-    unsigned mStreamStateIndication;
-    unsigned mAuxiliaryDataSizeLength;
-    unsigned mConstantDuration;
-    unsigned mPreviousAUCount;
-    bool mHasAUHeader;
-
-    uint32_t mAccessUnitRTPTime;
-    bool mNextExpectedSeqNoValid;
-    uint32_t mNextExpectedSeqNo;
-    bool mAccessUnitDamaged;
-    List<sp<ABuffer> > mPackets;
-
-    AssemblyStatus addPacket(const sp<ARTPSource> &source);
-    bool submitAccessUnit();
-
-    DISALLOW_EVIL_CONSTRUCTORS(AMPEG4ElementaryAssembler);
-};
-
-}  // namespace android
-
-#endif  // A_MPEG4_ELEM_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/APacketSource.cpp
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "APacketSource"
-#include "RtspPrlog.h"
-
-#include "APacketSource.h"
-
-#include "ARawAudioAssembler.h"
-#include "ASessionDescription.h"
-
-#include "avc_utils.h"
-
-#include <ctype.h>
-
-#include <media/stagefright/foundation/ABitReader.h>
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/base64.h>
-#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-static bool GetAttribute(const char *s, const char *key, AString *value) {
-    value->clear();
-
-    size_t keyLen = strlen(key);
-
-    for (;;) {
-        while (isspace(*s)) {
-            ++s;
-        }
-
-        const char *colonPos = strchr(s, ';');
-
-        size_t len =
-            (colonPos == NULL) ? strlen(s) : colonPos - s;
-
-        if (len >= keyLen + 1 && s[keyLen] == '=' && !strncmp(s, key, keyLen)) {
-            value->setTo(&s[keyLen + 1], len - keyLen - 1);
-            return true;
-        }
-
-        if (colonPos == NULL) {
-            return false;
-        }
-
-        s = colonPos + 1;
-    }
-}
-
-static sp<ABuffer> decodeHex(const AString &s) {
-    if ((s.size() % 2) != 0) {
-        return NULL;
-    }
-
-    size_t outLen = s.size() / 2;
-    sp<ABuffer> buffer = new ABuffer(outLen);
-    uint8_t *out = buffer->data();
-
-    uint8_t accum = 0;
-    for (size_t i = 0; i < s.size(); ++i) {
-        char c = s.c_str()[i];
-        unsigned value;
-        if (c >= '0' && c <= '9') {
-            value = c - '0';
-        } else if (c >= 'a' && c <= 'f') {
-            value = c - 'a' + 10;
-        } else if (c >= 'A' && c <= 'F') {
-            value = c - 'A' + 10;
-        } else {
-            return NULL;
-        }
-
-        accum = (accum << 4) | value;
-
-        if (i & 1) {
-            *out++ = accum;
-
-            accum = 0;
-        }
-    }
-
-    return buffer;
-}
-
-static sp<ABuffer> MakeAVCCodecSpecificData(
-        const char *params, int32_t *width, int32_t *height) {
-    *width = 0;
-    *height = 0;
-
-    AString val;
-    if (!GetAttribute(params, "profile-level-id", &val)) {
-        return NULL;
-    }
-
-    sp<ABuffer> profileLevelID = decodeHex(val);
-    if (!profileLevelID.get() || profileLevelID->size() != 3u) {
-        LOGW("Format error in profile-level-id");
-
-        return NULL;
-    }
-
-    Vector<sp<ABuffer> > paramSets;
-
-    size_t numSeqParameterSets = 0;
-    size_t totalSeqParameterSetSize = 0;
-    size_t numPicParameterSets = 0;
-    size_t totalPicParameterSetSize = 0;
-
-    if (!GetAttribute(params, "sprop-parameter-sets", &val)) {
-        return NULL;
-    }
-
-    size_t start = 0;
-    for (;;) {
-        ssize_t commaPos = val.find(",", start);
-        size_t end = (commaPos < 0) ? val.size() : commaPos;
-
-        AString nalString(val, start, end - start);
-        sp<ABuffer> nal = decodeBase64(nalString);
-        if (!nal.get() || nal->size() <= 0u || nal->size() > 65535u) {
-            return NULL;
-        }
-
-        uint8_t nalType = nal->data()[0] & 0x1f;
-        if (numSeqParameterSets == 0) {
-            if ((unsigned)nalType !=  7u) {
-                return NULL;
-            }
-        } else if (numPicParameterSets > 0) {
-            if ((unsigned)nalType != 8u) {
-                return NULL;
-            }
-        }
-        if (nalType == 7) {
-            ++numSeqParameterSets;
-            totalSeqParameterSetSize += nal->size();
-        } else  {
-            if ((unsigned)nalType != 8u) {
-                return NULL;
-            }
-            ++numPicParameterSets;
-            totalPicParameterSetSize += nal->size();
-        }
-
-        paramSets.push(nal);
-
-        if (commaPos < 0) {
-            break;
-        }
-
-        start = commaPos + 1;
-    }
-
-    if (numSeqParameterSets >= 32u) {
-        return NULL;
-    }
-    if (numPicParameterSets > 255u) {
-        return NULL;
-    }
-
-    size_t csdSize =
-        1 + 3 + 1 + 1
-        + 2 * numSeqParameterSets + totalSeqParameterSetSize
-        + 1 + 2 * numPicParameterSets + totalPicParameterSetSize;
-
-    sp<ABuffer> csd = new ABuffer(csdSize);
-    uint8_t *out = csd->data();
-
-    *out++ = 0x01;  // configurationVersion
-    memcpy(out, profileLevelID->data(), 3);
-    out += 3;
-    *out++ = (0x3f << 2) | 1;  // lengthSize == 2 bytes
-    *out++ = 0xe0 | numSeqParameterSets;
-
-    for (size_t i = 0; i < numSeqParameterSets; ++i) {
-        sp<ABuffer> nal = paramSets.editItemAt(i);
-
-        *out++ = nal->size() >> 8;
-        *out++ = nal->size() & 0xff;
-
-        memcpy(out, nal->data(), nal->size());
-
-        out += nal->size();
-
-        if (i == 0) {
-            FindAVCDimensions(nal, width, height);
-            LOGI("dimensions %dx%d", *width, *height);
-        }
-    }
-
-    *out++ = numPicParameterSets;
-
-    for (size_t i = 0; i < numPicParameterSets; ++i) {
-        sp<ABuffer> nal = paramSets.editItemAt(i + numSeqParameterSets);
-
-        *out++ = nal->size() >> 8;
-        *out++ = nal->size() & 0xff;
-
-        memcpy(out, nal->data(), nal->size());
-
-        out += nal->size();
-    }
-
-    // hexdump(csd->data(), csd->size());
-
-    return csd;
-}
-
-sp<ABuffer> MakeAACCodecSpecificData(const char *params) {
-    if (!params || !strlen(params)) {
-      return NULL;
-    }
-    AString val;
-    if (!GetAttribute(params, "config", &val)) {
-        return NULL;
-    }
-
-    sp<ABuffer> config = decodeHex(val);
-    if (!config.get()) {
-      return NULL;
-    }
-    if (config->size() < 4u) {
-      return NULL;
-    }
-
-    const uint8_t *data = config->data();
-    uint32_t x = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
-    x = (x >> 1) & 0xffff;
-
-    static const uint8_t kStaticESDS[] = {
-        0x03, 22,
-        0x00, 0x00,     // ES_ID
-        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
-        0x04, 17,
-        0x40,                       // Audio ISO/IEC 14496-3
-        0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00,
-
-        0x05, 2,
-        // AudioSpecificInfo follows
-    };
-
-    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + 2);
-    memcpy(csd->data(), kStaticESDS, sizeof(kStaticESDS));
-    csd->data()[sizeof(kStaticESDS)] = (x >> 8) & 0xff;
-    csd->data()[sizeof(kStaticESDS) + 1] = x & 0xff;
-
-    // hexdump(csd->data(), csd->size());
-
-    return csd;
-}
-
-// From mpeg4-generic configuration data.
-sp<ABuffer> MakeAACCodecSpecificData2(const char *params) {
-    AString val;
-    unsigned long objectType;
-    if (GetAttribute(params, "objectType", &val)) {
-        const char *s = val.c_str();
-        char *end;
-        objectType = strtoul(s, &end, 10);
-        if (end <= s || *end != '\0') {
-            return NULL;
-        }
-    } else {
-        objectType = 0x40;  // Audio ISO/IEC 14496-3
-    }
-
-    if (!GetAttribute(params, "config", &val)) {
-        LOGW("Cannot find attribute config");
-
-        return NULL;
-    }
-
-    sp<ABuffer> config = decodeHex(val);
-    if (!config.get()) {
-        return NULL;
-    }
-
-    // Make sure size fits into a single byte and doesn't have to
-    // be encoded.
-    if (20 + config->size() >= 128u) {
-        return NULL;
-    }
-
-    static const uint8_t kStaticESDS[] = {
-        0x03, 22,
-        0x00, 0x00,     // ES_ID
-        0x00,           // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
-        0x04, 17,
-        0x40,                       // Audio ISO/IEC 14496-3
-        0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00,
-        0x00, 0x00, 0x00, 0x00,
-
-        0x05, 2,
-        // AudioSpecificInfo follows
-    };
-
-    sp<ABuffer> csd = new ABuffer(sizeof(kStaticESDS) + config->size());
-    uint8_t *dst = csd->data();
-    *dst++ = 0x03;
-    *dst++ = 20 + config->size();
-    *dst++ = 0x00;  // ES_ID
-    *dst++ = 0x00;
-    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
-    *dst++ = 0x04;
-    *dst++ = 15 + config->size();
-    *dst++ = objectType;
-    for (int i = 0; i < 12; ++i) { *dst++ = 0x00; }
-    *dst++ = 0x05;
-    *dst++ = config->size();
-    memcpy(dst, config->data(), config->size());
-
-    // hexdump(csd->data(), csd->size());
-
-    return csd;
-}
-
-static size_t GetSizeWidth(size_t x) {
-    size_t n = 1;
-    while (x > 127) {
-        ++n;
-        x >>= 7;
-    }
-    return n;
-}
-
-static uint8_t *EncodeSize(uint8_t *dst, size_t x) {
-    while (x > 127) {
-        *dst++ = (x & 0x7f) | 0x80;
-        x >>= 7;
-    }
-    *dst++ = x;
-    return dst;
-}
-
-static bool ExtractDimensionsMPEG4Config(
-        const sp<ABuffer> &config, int32_t *width, int32_t *height) {
-    *width = 0;
-    *height = 0;
-
-    const uint8_t *ptr = config->data();
-    size_t offset = 0;
-    bool foundVOL = false;
-    while (offset + 3 < config->size()) {
-        if (memcmp("\x00\x00\x01", &ptr[offset], 3)
-                || (ptr[offset + 3] & 0xf0) != 0x20) {
-            ++offset;
-            continue;
-        }
-
-        foundVOL = true;
-        break;
-    }
-
-    if (!foundVOL) {
-        return false;
-    }
-
-    return ExtractDimensionsFromVOLHeader(
-            &ptr[offset], config->size() - offset, width, height);
-}
-
-static sp<ABuffer> MakeMPEG4VideoCodecSpecificData(
-        const char *params, int32_t *width, int32_t *height) {
-    *width = 0;
-    *height = 0;
-
-    AString val;
-    if (!GetAttribute(params, "config", &val)) {
-        LOGW("Cannot find attribute config");
-
-        return NULL;
-    }
-
-    sp<ABuffer> config = decodeHex(val);
-    if (!config.get()) {
-        return NULL;
-    }
-
-    if (!ExtractDimensionsMPEG4Config(config, width, height)) {
-        return NULL;
-    }
-
-    LOGI("VOL dimensions = %dx%d", *width, *height);
-
-    size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
-    size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
-    size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
-
-    sp<ABuffer> csd = new ABuffer(len3);
-    uint8_t *dst = csd->data();
-    *dst++ = 0x03;
-    dst = EncodeSize(dst, len2 + 3);
-    *dst++ = 0x00;  // ES_ID
-    *dst++ = 0x00;
-    *dst++ = 0x00;  // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
-    *dst++ = 0x04;
-    dst = EncodeSize(dst, len1 + 13);
-    *dst++ = 0x01;  // Video ISO/IEC 14496-2 Simple Profile
-    for (size_t i = 0; i < 12; ++i) {
-        *dst++ = 0x00;
-    }
-
-    *dst++ = 0x05;
-    dst = EncodeSize(dst, config->size());
-    memcpy(dst, config->data(), config->size());
-    dst += config->size();
-
-    // hexdump(csd->data(), csd->size());
-
-    return csd;
-}
-
-APacketSource::APacketSource(
-        const sp<ASessionDescription> &sessionDesc, size_t index)
-    : mInitCheck(NO_INIT),
-      mFormat(new MetaData) {
-    unsigned long PT;
-    AString desc;
-    AString params;
-
-    if (!sessionDesc->getFormatType(index, &PT, &desc, &params)) {
-      mInitCheck = ERROR_UNSUPPORTED;
-      return;
-    }
-
-    int64_t durationUs;
-    if (sessionDesc->getDurationUs(&durationUs)) {
-        mFormat->setInt64(kKeyDuration, durationUs);
-    } else {
-        // Set its value to zero(long long) to indicate that this is a live stream.
-        mFormat->setInt64(kKeyDuration, 0ll);
-    }
-
-    mInitCheck = OK;
-    if (!strncmp(desc.c_str(), "H264/", 5)) {
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
-
-        int32_t width, height;
-        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
-            width = -1;
-            height = -1;
-        }
-
-        int32_t encWidth, encHeight;
-        sp<ABuffer> codecSpecificData =
-            MakeAVCCodecSpecificData(params.c_str(), &encWidth, &encHeight);
-
-        if (codecSpecificData != NULL) {
-            if (width < 0) {
-                // If no explicit width/height given in the sdp, use the dimensions
-                // extracted from the first sequence parameter set.
-                width = encWidth;
-                height = encHeight;
-            }
-
-            mFormat->setData(
-                    kKeyAVCC, 0,
-                    codecSpecificData->data(), codecSpecificData->size());
-        } else if (width < 0) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeyWidth, width);
-        mFormat->setInt32(kKeyHeight, height);
-    } else if (!strncmp(desc.c_str(), "H263-2000/", 10)
-            || !strncmp(desc.c_str(), "H263-1998/", 10)) {
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
-
-        int32_t width, height;
-        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeyWidth, width);
-        mFormat->setInt32(kKeyHeight, height);
-    } else if (!strncmp(desc.c_str(), "MP4A-LATM/", 10)) {
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-
-        int32_t sampleRate, numChannels;
-        if (!ASessionDescription::ParseFormatDesc(
-                desc.c_str(), &sampleRate, &numChannels)) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeySampleRate, sampleRate);
-        mFormat->setInt32(kKeyChannelCount, numChannels);
-
-        sp<ABuffer> codecSpecificData =
-            MakeAACCodecSpecificData(params.c_str());
-        if (!codecSpecificData.get()) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setData(
-                kKeyESDS, 0,
-                codecSpecificData->data(), codecSpecificData->size());
-    } else if (!strncmp(desc.c_str(), "AMR/", 4)) {
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_NB);
-
-        int32_t sampleRate, numChannels;
-        if (!ASessionDescription::ParseFormatDesc(
-                desc.c_str(), &sampleRate, &numChannels)) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeySampleRate, sampleRate);
-        mFormat->setInt32(kKeyChannelCount, numChannels);
-
-        if (sampleRate != 8000 || numChannels != 1) {
-            mInitCheck = ERROR_UNSUPPORTED;
-        }
-    } else if (!strncmp(desc.c_str(), "AMR-WB/", 7)) {
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AMR_WB);
-
-        int32_t sampleRate, numChannels;
-        if (!ASessionDescription::ParseFormatDesc(
-                desc.c_str(), &sampleRate, &numChannels)) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeySampleRate, sampleRate);
-        mFormat->setInt32(kKeyChannelCount, numChannels);
-
-        if (sampleRate != 16000 || numChannels != 1) {
-            mInitCheck = ERROR_UNSUPPORTED;
-        }
-    } else if (!strncmp(desc.c_str(), "MP4V-ES/", 8)) {
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
-
-        int32_t width, height;
-        if (!sessionDesc->getDimensions(index, PT, &width, &height)) {
-            width = -1;
-            height = -1;
-        }
-
-        int32_t encWidth, encHeight;
-        sp<ABuffer> codecSpecificData =
-            MakeMPEG4VideoCodecSpecificData(
-                    params.c_str(), &encWidth, &encHeight);
-
-        if (codecSpecificData != NULL) {
-            mFormat->setData(
-                    kKeyESDS, 0,
-                    codecSpecificData->data(), codecSpecificData->size());
-
-            if (width < 0) {
-                width = encWidth;
-                height = encHeight;
-            }
-        } else if (width < 0) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeyWidth, width);
-        mFormat->setInt32(kKeyHeight, height);
-    } else if (!strncasecmp(desc.c_str(), "mpeg4-generic/", 14)) {
-        AString val;
-        if (!GetAttribute(params.c_str(), "mode", &val)
-                || (strcasecmp(val.c_str(), "AAC-lbr")
-                    && strcasecmp(val.c_str(), "AAC-hbr"))) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_AAC);
-
-        int32_t sampleRate, numChannels;
-        if (!ASessionDescription::ParseFormatDesc(
-                desc.c_str(), &sampleRate, &numChannels)) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-
-        mFormat->setInt32(kKeySampleRate, sampleRate);
-        mFormat->setInt32(kKeyChannelCount, numChannels);
-
-        sp<ABuffer> codecSpecificData =
-            MakeAACCodecSpecificData2(params.c_str());
-        if (!codecSpecificData.get()) {
-            mInitCheck = ERROR_UNSUPPORTED;
-            return;
-        }
-        mFormat->setData(
-                kKeyESDS, 0,
-                codecSpecificData->data(), codecSpecificData->size());
-    } else if (ARawAudioAssembler::Supports(desc.c_str())) {
-        if (!ARawAudioAssembler::MakeFormat(desc.c_str(), mFormat)) {
-            mInitCheck = ERROR_UNSUPPORTED;
-        }
-    } else {
-        mInitCheck = ERROR_UNSUPPORTED;
-    }
-}
-
-APacketSource::~APacketSource() {
-}
-
-status_t APacketSource::initCheck() const {
-    return mInitCheck;
-}
-
-sp<MetaData> APacketSource::getFormat() {
-    return mFormat;
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/APacketSource.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_PACKET_SOURCE_H_
-
-#define A_PACKET_SOURCE_H_
-
-#include <media/stagefright/foundation/ABase.h>
-#include <media/stagefright/MetaData.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct ASessionDescription;
-
-struct APacketSource : public RefBase {
-    APacketSource(const sp<ASessionDescription> &sessionDesc, size_t index);
-
-    status_t initCheck() const;
-
-    virtual sp<MetaData> getFormat();
-
-protected:
-    virtual ~APacketSource();
-
-private:
-    status_t mInitCheck;
-
-    sp<MetaData> mFormat;
-
-    DISALLOW_EVIL_CONSTRUCTORS(APacketSource);
-};
-
-
-}  // namespace android
-
-#endif  // A_PACKET_SOURCE_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPAssembler.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ARTPAssembler.h"
-
-#include "RtspPrlog.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
-#include <stdint.h>
-
-namespace android {
-
-static int64_t getNowUs() {
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-
-    return (int64_t)tv.tv_usec + tv.tv_sec * 1000000ll;
-}
-
-ARTPAssembler::ARTPAssembler()
-    : mFirstFailureTimeUs(-1) {
-}
-
-void ARTPAssembler::onPacketReceived(const sp<ARTPSource> &source) {
-    AssemblyStatus status;
-    for (;;) {
-        status = assembleMore(source);
-
-        if (status == WRONG_SEQUENCE_NUMBER) {
-            if (mFirstFailureTimeUs >= 0) {
-                if (getNowUs() - mFirstFailureTimeUs > 10000ll) {
-                    mFirstFailureTimeUs = -1;
-
-                    // LOG(VERBOSE) << "waited too long for packet.";
-                    packetLost();
-                    continue;
-                }
-            } else {
-                mFirstFailureTimeUs = getNowUs();
-            }
-            break;
-        } else {
-            mFirstFailureTimeUs = -1;
-
-            if (status == NOT_ENOUGH_DATA) {
-                break;
-            }
-        }
-    }
-}
-
-// static
-bool ARTPAssembler::CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from) {
-    uint32_t rtpTime;
-    if (!from->meta()->findInt32("rtp-time", (int32_t *)&rtpTime)) {
-        LOGW("CopyTimes: Cannot find rtp-time");
-
-        return false;
-    }
-
-    to->meta()->setInt32("rtp-time", rtpTime);
-
-    // Copy the seq number.
-    to->setInt32Data(from->int32Data());
-    return true;
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPAssembler.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_ASSEMBLER_H_
-
-#define A_RTP_ASSEMBLER_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/ABase.h>
-#include <utils/RefBase.h>
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct ARTPSource;
-
-struct ARTPAssembler : public RefBase {
-    enum AssemblyStatus {
-        MALFORMED_PACKET,
-        WRONG_SEQUENCE_NUMBER,
-        NOT_ENOUGH_DATA,
-        OK
-    };
-
-    ARTPAssembler();
-
-    void onPacketReceived(const sp<ARTPSource> &source);
-    virtual void onByeReceived() = 0;
-
-protected:
-    virtual AssemblyStatus assembleMore(const sp<ARTPSource> &source) = 0;
-    virtual void packetLost() = 0;
-
-    static bool CopyTimes(const sp<ABuffer> &to, const sp<ABuffer> &from);
-
-private:
-    int64_t mFirstFailureTimeUs;
-
-    DISALLOW_EVIL_CONSTRUCTORS(ARTPAssembler);
-};
-
-}  // namespace android
-
-#endif  // A_RTP_ASSEMBLER_H_
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPConnection.cpp
+++ /dev/null
@@ -1,727 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "ARTPConnection"
-#include "RtspPrlog.h"
-
-#include "ARTPConnection.h"
-
-#include "ARTPSource.h"
-#include "ASessionDescription.h"
-
-#include <media/stagefright/foundation/ABuffer.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-#include <media/stagefright/foundation/AString.h>
-#include <media/stagefright/foundation/hexdump.h>
-
-#include <arpa/inet.h>
-
-#include "mozilla/mozalloc.h"
-#include "nsTArray.h"
-#include "prnetdb.h"
-#include "prerr.h"
-#include "prerror.h"
-#include "NetworkActivityMonitor.h"
-
-using namespace mozilla::net;
-
-namespace android {
-
-static const size_t kMaxUDPSize = 1500;
-
-static uint16_t u16at(const uint8_t *data) {
-    return data[0] << 8 | data[1];
-}
-
-static uint32_t u32at(const uint8_t *data) {
-    return u16at(data) << 16 | u16at(&data[2]);
-}
-
-static uint64_t u64at(const uint8_t *data) {
-    return (uint64_t)(u32at(data)) << 32 | u32at(&data[4]);
-}
-
-// static
-const uint32_t ARTPConnection::kSocketPollTimeoutUs = 1000ll;
-
-struct ARTPConnection::StreamInfo {
-    PRFileDesc *mRTPSocket;
-    PRFileDesc *mRTCPSocket;
-    int mInterleavedRTPIdx;
-    int mInterleavedRTCPIdx;
-    sp<ASessionDescription> mSessionDesc;
-    size_t mIndex;
-    sp<AMessage> mNotifyMsg;
-    KeyedVector<uint32_t, sp<ARTPSource> > mSources;
-
-    int64_t mNumRTCPPacketsReceived;
-    int64_t mNumRTPPacketsReceived;
-    PRNetAddr mRemoteRTCPAddr;
-
-    bool mIsInjected;
-};
-
-ARTPConnection::ARTPConnection(uint32_t flags)
-    : mFlags(flags),
-      mPollEventPending(false),
-      mLastReceiverReportTimeUs(-1) {
-}
-
-ARTPConnection::~ARTPConnection() {
-}
-
-void ARTPConnection::addStream(
-        PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket,
-        int interleavedRTPIdx, int interleavedRTCPIdx,
-        const sp<ASessionDescription> &sessionDesc,
-        size_t index,
-        const sp<AMessage> &notify,
-        bool injected) {
-    sp<AMessage> msg = new AMessage(kWhatAddStream, id());
-    msg->setPointer("rtp-socket", rtpSocket);
-    msg->setPointer("rtcp-socket", rtcpSocket);
-    msg->setInt32("interleaved-rtp", interleavedRTPIdx);
-    msg->setInt32("interleaved-rtcp", interleavedRTCPIdx);
-    msg->setObject("session-desc", sessionDesc);
-    msg->setSize("index", index);
-    msg->setMessage("notify", notify);
-    msg->setInt32("injected", injected);
-    msg->post();
-}
-
-void ARTPConnection::removeStream(PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket) {
-    sp<AMessage> msg = new AMessage(kWhatRemoveStream, id());
-    msg->setPointer("rtp-socket", rtpSocket);
-    msg->setPointer("rtcp-socket", rtcpSocket);
-
-    // Since the caller will close the sockets after this function
-    // returns, we need to use a blocking post to prevent from polling
-    // closed sockets.
-    sp<AMessage> response;
-    msg->postAndAwaitResponse(&response);
-}
-
-static void bumpSocketBufferSize(PRFileDesc *s) {
-    uint32_t size = 256 * 1024;
-    PRSocketOptionData opt;
-
-    opt.option = PR_SockOpt_RecvBufferSize;
-    opt.value.recv_buffer_size = size;
-    CHECK_EQ(PR_SetSocketOption(s, &opt), PR_SUCCESS);
-}
-
-// static
-void ARTPConnection::MakePortPair(
-        PRFileDesc **rtpSocket, PRFileDesc **rtcpSocket, uint16_t *rtpPort) {
-    *rtpSocket = PR_OpenUDPSocket(PR_AF_INET);
-    if (!*rtpSocket) {
-        TRESPASS();
-    }
-
-    bumpSocketBufferSize(*rtpSocket);
-
-    *rtcpSocket = PR_OpenUDPSocket(PR_AF_INET);
-    if (!*rtcpSocket) {
-        TRESPASS();
-    }
-
-    bumpSocketBufferSize(*rtcpSocket);
-
-    NetworkActivityMonitor::AttachIOLayer(*rtpSocket);
-    NetworkActivityMonitor::AttachIOLayer(*rtcpSocket);
-
-    // Reduce the chance of using duplicate port numbers.
-    srand(time(NULL));
-    // rand() * 1000 may overflow int type, use long long.
-    unsigned start = (unsigned)((rand() * 1000ll) / RAND_MAX) + 15550;
-    start &= ~1;
-
-    for (uint32_t port = start; port < 65536; port += 2) {
-        PRNetAddr addr;
-        addr.inet.family = PR_AF_INET;
-        addr.inet.ip = PR_htonl(PR_INADDR_ANY);
-        addr.inet.port = PR_htons(port);
-
-        if (PR_Bind(*rtpSocket, &addr) == PR_FAILURE) {
-            continue;
-        }
-
-        addr.inet.port = PR_htons(port + 1);
-
-        if (PR_Bind(*rtcpSocket, &addr) == PR_SUCCESS) {
-            *rtpPort = port;
-            return;
-        }
-    }
-
-    TRESPASS();
-}
-
-void ARTPConnection::onMessageReceived(const sp<AMessage> &msg) {
-    switch (msg->what()) {
-        case kWhatAddStream:
-        {
-            onAddStream(msg);
-            break;
-        }
-
-        case kWhatRemoveStream:
-        {
-            onRemoveStream(msg);
-            sp<AMessage> ack = new AMessage;
-            uint32_t replyID;
-            CHECK(msg->senderAwaitsResponse(&replyID));
-            ack->postReply(replyID);
-            break;
-        }
-
-        case kWhatPollStreams:
-        {
-            onPollStreams();
-            break;
-        }
-
-        case kWhatInjectPacket:
-        {
-            onInjectPacket(msg);
-            break;
-        }
-
-        default:
-        {
-            TRESPASS();
-            break;
-        }
-    }
-}
-
-void ARTPConnection::onAddStream(const sp<AMessage> &msg) {
-    mStreams.push_back(StreamInfo());
-    StreamInfo *info = &*--mStreams.end();
-
-    void *s;
-    CHECK(msg->findPointer("rtp-socket", &s));
-    info->mRTPSocket = (PRFileDesc*)s;
-    CHECK(msg->findPointer("rtcp-socket", &s));
-    info->mRTCPSocket = (PRFileDesc*)s;
-
-    CHECK(msg->findInt32("interleaved-rtp", &info->mInterleavedRTPIdx));
-    CHECK(msg->findInt32("interleaved-rtcp", &info->mInterleavedRTCPIdx));
-
-    int32_t injected;
-    CHECK(msg->findInt32("injected", &injected));
-
-    info->mIsInjected = injected;
-
-    sp<RefBase> obj;
-    CHECK(msg->findObject("session-desc", &obj));
-    info->mSessionDesc = static_cast<ASessionDescription *>(obj.get());
-
-    CHECK(msg->findSize("index", &info->mIndex));
-    CHECK(msg->findMessage("notify", &info->mNotifyMsg));
-
-    info->mNumRTCPPacketsReceived = 0;
-    info->mNumRTPPacketsReceived = 0;
-    PR_InitializeNetAddr(PR_IpAddrNull, 0, &info->mRemoteRTCPAddr);
-
-    if (!injected) {
-        postPollEvent();
-    }
-}
-
-void ARTPConnection::onRemoveStream(const sp<AMessage> &msg) {
-    PRFileDesc *rtpSocket = nullptr, *rtcpSocket = nullptr;
-    void *s;
-    CHECK(msg->findPointer("rtp-socket", &s));
-    rtpSocket = (PRFileDesc*)s;
-    CHECK(msg->findPointer("rtcp-socket", &s));
-    rtcpSocket = (PRFileDesc*)s;
-
-    List<StreamInfo>::iterator it = mStreams.begin();
-    while (it != mStreams.end()
-           && (it->mRTPSocket != rtpSocket || it->mRTCPSocket != rtcpSocket)) {
-        ++it;
-    }
-
-    if (it == mStreams.end()) {
-        return;
-    }
-
-    mStreams.erase(it);
-}
-
-void ARTPConnection::postPollEvent() {
-    if (mPollEventPending) {
-        return;
-    }
-
-    sp<AMessage> msg = new AMessage(kWhatPollStreams, id());
-    msg->post();
-
-    mPollEventPending = true;
-}
-
-void ARTPConnection::onPollStreams() {
-    mPollEventPending = false;
-
-    if (mStreams.empty()) {
-        return;
-    }
-
-    uint32_t pollCount = mStreams.size() * 2;
-    nsTArray<PRPollDesc> pollList;
-    pollList.AppendElements(pollCount);
-    memset(pollList.Elements(), 0, sizeof(PRPollDesc) * pollCount);
-
-    // |pollIndex| is used to map different RTP & RTCP socket pairs.
-    uint32_t numSocketsToPoll = 0, pollIndex = 0;
-    for (List<StreamInfo>::iterator it = mStreams.begin();
-         it != mStreams.end(); ++it, pollIndex += 2) {
-        if (pollIndex >= pollCount) {
-            // |pollIndex| should never equal or exceed |pollCount|.
-            TRESPASS();
-        }
-
-        if ((*it).mIsInjected) {
-            continue;
-        }
-
-        if (it->mRTPSocket) {
-            pollList[pollIndex].fd = it->mRTPSocket;
-            pollList[pollIndex].in_flags = PR_POLL_READ;
-            pollList[pollIndex].out_flags = 0;
-            numSocketsToPoll++;
-        }
-        if (it->mRTCPSocket) {
-            pollList[pollIndex + 1].fd = it->mRTCPSocket;
-            pollList[pollIndex + 1].in_flags = PR_POLL_READ;
-            pollList[pollIndex + 1].out_flags = 0;
-            numSocketsToPoll++;
-        }
-    }
-
-    if (numSocketsToPoll == 0) {
-        // No sockets need to poll. return.
-        return;
-    }
-
-    const int32_t numSocketsReadyToRead =
-        PR_Poll(pollList.Elements(), pollList.Length(),
-                PR_MicrosecondsToInterval(kSocketPollTimeoutUs));
-
-    if (numSocketsReadyToRead > 0) {
-        pollIndex = 0;
-        List<StreamInfo>::iterator it = mStreams.begin();
-        while (it != mStreams.end()) {
-            if ((*it).mIsInjected) {
-                ++it;
-                pollIndex += 2;
-                continue;
-            }
-
-            status_t err = OK;
-            if (pollList[pollIndex].out_flags != 0) {
-                err = receive(&*it, true);
-            }
-            if (err == OK && pollList[pollIndex + 1].out_flags != 0) {
-                err = receive(&*it, false);
-            }
-
-            if (err == -ECONNRESET) {
-                // socket failure, this stream is dead, Jim.
-
-                LOGW("failed to receive RTP/RTCP datagram.");
-                it = mStreams.erase(it);
-                pollIndex += 2;
-                continue;
-            }
-
-            ++it;
-            pollIndex += 2;
-        }
-    }
-
-    int64_t nowUs = ALooper::GetNowUs();
-    if (mLastReceiverReportTimeUs <= 0
-            || mLastReceiverReportTimeUs + 5000000ll <= nowUs) {
-        sp<ABuffer> buffer = new ABuffer(kMaxUDPSize);
-        List<StreamInfo>::iterator it = mStreams.begin();
-        while (it != mStreams.end()) {
-            StreamInfo *s = &*it;
-
-            if (s->mIsInjected) {
-                ++it;
-                continue;
-            }
-
-            if (s->mNumRTCPPacketsReceived == 0) {
-                // We have never received any RTCP packets on this stream,
-                // we don't even know where to send a report.
-                ++it;
-                continue;
-            }
-
-            buffer->setRange(0, 0);
-
-            for (size_t i = 0; i < s->mSources.size(); ++i) {
-                sp<ARTPSource> source = s->mSources.valueAt(i);
-
-                source->addReceiverReport(buffer);
-
-                if (mFlags & kRegularlyRequestFIR) {
-                    source->addFIR(buffer);
-                }
-            }
-
-            if (buffer->size() > 0) {
-                LOGV("Sending RR...");
-
-                ssize_t n;
-                PRErrorCode errorCode;
-                do {
-                    n = PR_SendTo(s->mRTCPSocket, buffer->data(), buffer->size(),
-                                  0, &s->mRemoteRTCPAddr, PR_INTERVAL_NO_WAIT);
-                    errorCode = PR_GetError();
-                } while (n < 0 && errorCode == PR_PENDING_INTERRUPT_ERROR);
-
-                if (n <= 0) {
-                    LOGW("failed to send RTCP receiver report (%s).",
-                         n == 0 ? "connection gone" : "interrupt error");
-
-                    it = mStreams.erase(it);
-                    continue;
-                }
-
-                CHECK_EQ(n, (ssize_t)buffer->size());
-
-                mLastReceiverReportTimeUs = nowUs;
-            }
-
-            ++it;
-        }
-    }
-
-    if (!mStreams.empty()) {
-        postPollEvent();
-    }
-}
-
-status_t ARTPConnection::receive(StreamInfo *s, bool receiveRTP) {
-    LOGV("receiving %s", receiveRTP ? "RTP" : "RTCP");
-
-    CHECK(!s->mIsInjected);
-
-    sp<ABuffer> buffer = new ABuffer(65536);
-
-    int32_t remoteAddrLen =
-        (!receiveRTP && s->mNumRTCPPacketsReceived == 0)
-            ? sizeof(s->mRemoteRTCPAddr) : 0;
-
-    ssize_t nbytes;
-    PRErrorCode errorCode;
-    do {
-        nbytes = PR_RecvFrom(receiveRTP ? s->mRTPSocket : s->mRTCPSocket,
-                             buffer->data(),
-                             buffer->size(),
-                             0,
-                             remoteAddrLen > 0 ? &s->mRemoteRTCPAddr : NULL,
-                             PR_INTERVAL_NO_WAIT);
-        errorCode = PR_GetError();
-    } while (nbytes < 0 && errorCode == PR_PENDING_INTERRUPT_ERROR);
-
-    if (nbytes <= 0) {
-        return -PR_CONNECT_RESET_ERROR;
-    }
-
-    buffer->setRange(0, nbytes);
-
-    // LOGI("received %d bytes.", buffer->size());
-
-    status_t err;
-    if (receiveRTP) {
-        err = parseRTP(s, buffer);
-    } else {
-        err = parseRTCP(s, buffer);
-    }
-
-    return err;
-}
-
-status_t ARTPConnection::parseRTP(StreamInfo *s, const sp<ABuffer> &buffer) {
-    if (s->mNumRTPPacketsReceived++ == 0) {
-        sp<AMessage> notify = s->mNotifyMsg->dup();
-        notify->setInt32("first-rtp", true);
-        notify->post();
-    }
-
-    size_t size = buffer->size();
-
-    if (size < 12) {
-        // Too short to be a valid RTP header.
-        return -1;
-    }
-
-    const uint8_t *data = buffer->data();
-
-    if ((data[0] >> 6) != 2) {
-        // Unsupported version.
-        return -1;
-    }
-
-    if (data[0] & 0x20) {
-        // Padding present.
-
-        size_t paddingLength = data[size - 1];
-
-        if (paddingLength + 12 > size) {
-            // If we removed this much padding we'd end up with something
-            // that's too short to be a valid RTP header.
-            return -1;
-        }
-
-        size -= paddingLength;
-    }
-
-    int numCSRCs = data[0] & 0x0f;
-
-    size_t payloadOffset = 12 + 4 * numCSRCs;
-
-    if (size < payloadOffset) {
-        // Not enough data to fit the basic header and all the CSRC entries.
-        return -1;
-    }
-
-    if (data[0] & 0x10) {
-        // Header eXtension present.
-
-        if (size < payloadOffset + 4) {
-            // Not enough data to fit the basic header, all CSRC entries
-            // and the first 4 bytes of the extension header.
-
-            return -1;
-        }
-
-        const uint8_t *extensionData = &data[payloadOffset];
-
-        size_t extensionLength =
-            4 * (extensionData[2] << 8 | extensionData[3]);
-
-        if (size < payloadOffset + 4 + extensionLength) {
-            return -1;
-        }
-
-        payloadOffset += 4 + extensionLength;
-    }
-
-    uint32_t srcId = u32at(&data[8]);
-
-    sp<ARTPSource> source = findSource(s, srcId);
-
-    uint32_t rtpTime = u32at(&data[4]);
-
-    sp<AMessage> meta = buffer->meta();
-    meta->setInt32("ssrc", srcId);
-    meta->setInt32("rtp-time", rtpTime);
-    meta->setInt32("PT", data[1] & 0x7f);
-    meta->setInt32("M", data[1] >> 7);
-
-    buffer->setInt32Data(u16at(&data[2]));
-    buffer->setRange(payloadOffset, size - payloadOffset);
-
-    source->processRTPPacket(buffer);
-
-    return OK;
-}
-
-status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
-    if (s->mNumRTCPPacketsReceived++ == 0) {
-        sp<AMessage> notify = s->mNotifyMsg->dup();
-        notify->setInt32("first-rtcp", true);
-        notify->post();
-    }
-
-    const uint8_t *data = buffer->data();
-    size_t size = buffer->size();
-
-    while (size > 0) {
-        if (size < 8) {
-            // Too short to be a valid RTCP header
-            return -1;
-        }
-
-        if ((data[0] >> 6) != 2) {
-            // Unsupported version.
-            return -1;
-        }
-
-        if (data[0] & 0x20) {
-            // Padding present.
-
-            size_t paddingLength = data[size - 1];
-
-            if (paddingLength + 12 > size) {
-                // If we removed this much padding we'd end up with something
-                // that's too short to be a valid RTP header.
-                return -1;
-            }
-
-            size -= paddingLength;
-        }
-
-        size_t headerLength = 4 * (data[2] << 8 | data[3]) + 4;
-
-        if (size < headerLength) {
-            // Only received a partial packet?
-            return -1;
-        }
-
-        switch (data[1]) {
-            case 200:
-            {
-                parseSR(s, data, headerLength);
-                break;
-            }
-
-            case 201:  // RR
-            case 202:  // SDES
-            case 204:  // APP
-                break;
-
-            case 205:  // TSFB (transport layer specific feedback)
-            case 206:  // PSFB (payload specific feedback)
-                // hexdump(data, headerLength);
-                break;
-
-            case 203:
-            {
-                parseBYE(s, data, headerLength);
-                break;
-            }
-
-            default:
-            {
-                LOGW("Unknown RTCP packet type %u of size %d",
-                     (unsigned)data[1], headerLength);
-                break;
-            }
-        }
-
-        data += headerLength;
-        size -= headerLength;
-    }
-
-    return OK;
-}
-
-status_t ARTPConnection::parseBYE(
-        StreamInfo *s, const uint8_t *data, size_t size) {
-    size_t SC = data[0] & 0x3f;
-
-    if (SC == 0 || size < (4 + SC * 4)) {
-        // Packet too short for the minimal BYE header.
-        return -1;
-    }
-
-    uint32_t id = u32at(&data[4]);
-
-    sp<ARTPSource> source = findSource(s, id);
-
-    source->byeReceived();
-
-    return OK;
-}
-
-status_t ARTPConnection::parseSR(
-        StreamInfo *s, const uint8_t *data, size_t size) {
-    size_t RC = data[0] & 0x1f;
-
-    if (size < (7 + RC * 6) * 4) {
-        // Packet too short for the minimal SR header.
-        return -1;
-    }
-
-    uint32_t id = u32at(&data[4]);
-    uint64_t ntpTime = u64at(&data[8]);
-    uint32_t rtpTime = u32at(&data[16]);
-
-#if 0
-    LOGI("XXX timeUpdate: ssrc=0x%08x, rtpTime %u == ntpTime %.3f",
-         id,
-         rtpTime,
-         (ntpTime >> 32) + (double)(ntpTime & 0xffffffff) / (1ll << 32));
-#endif
-
-    sp<ARTPSource> source = findSource(s, id);
-
-    source->timeUpdate(rtpTime, ntpTime);
-
-    return 0;
-}
-
-sp<ARTPSource> ARTPConnection::findSource(StreamInfo *info, uint32_t srcId) {
-    sp<ARTPSource> source;
-    ssize_t index = info->mSources.indexOfKey(srcId);
-    if (index < 0) {
-        index = info->mSources.size();
-
-        source = new ARTPSource(
-                srcId, info->mSessionDesc, info->mIndex, info->mNotifyMsg);
-
-        info->mSources.add(srcId, source);
-    } else {
-        source = info->mSources.valueAt(index);
-    }
-
-    return source;
-}
-
-void ARTPConnection::injectPacket(int index, const sp<ABuffer> &buffer) {
-    sp<AMessage> msg = new AMessage(kWhatInjectPacket, id());
-    msg->setInt32("index", index);
-    msg->setObject("buffer", buffer);
-    msg->post();
-}
-
-void ARTPConnection::onInjectPacket(const sp<AMessage> &msg) {
-    int32_t index;
-    CHECK(msg->findInt32("index", &index));
-
-    sp<RefBase> obj;
-    CHECK(msg->findObject("buffer", &obj));
-
-    sp<ABuffer> buffer = static_cast<ABuffer *>(obj.get());
-
-    List<StreamInfo>::iterator it = mStreams.begin();
-    while (it != mStreams.end()
-           && it->mInterleavedRTPIdx != index && it->mInterleavedRTCPIdx != index) {
-        ++it;
-    }
-
-    if (it == mStreams.end()) {
-        TRESPASS();
-    }
-
-    StreamInfo *s = &*it;
-
-    if (it->mInterleavedRTPIdx == index) {
-        parseRTP(s, buffer);
-    } else {
-        parseRTCP(s, buffer);
-    }
-}
-
-}  // namespace android
deleted file mode 100644
--- a/netwerk/protocol/rtsp/rtsp/ARTPConnection.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef A_RTP_CONNECTION_H_
-
-#define A_RTP_CONNECTION_H_
-
-#include "mozilla/Types.h"
-#include <media/stagefright/foundation/AHandler.h>
-#include <utils/List.h>
-
-#include "prio.h"
-
-namespace android {
-
-struct MOZ_EXPORT ABuffer;
-struct ARTPSource;
-struct ASessionDescription;
-
-struct ARTPConnection : public AHandler {
-    enum Flags {
-        kRegularlyRequestFIR = 2,
-    };
-
-    ARTPConnection(uint32_t flags = 0);
-
-    void addStream(
-            PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket,
-            int interleavedRTPIdx, int interleavedRTCPIdx,
-            const sp<ASessionDescription> &sessionDesc, size_t index,
-            const sp<AMessage> &notify,
-            bool injected);
-
-    void removeStream(PRFileDesc *rtpSocket, PRFileDesc *rtcpSocket);
-
-    void injectPacket(int index, const sp<ABuffer> &buffer);
-
-    // Creates a pair of UDP datagram sockets bound to adjacent ports
-    // (the rtpSocket is bound to an even port, the rtcpSocket to the
-    // next higher port).
-    static void MakePortPair(
-            PRFileDesc **rtpSocket, PRFileDesc **rtcpSocket, uint16_t *rtpPort);
-
-protected:
-    virtual ~ARTPConnection();
-    virtual void onMessageReceived(const sp<AMessage> &msg);
-
-private:
-    enum {
-        kWhatAddStream,
-        kWhatRemoveStream,
-        kWhatPollStreams,
-        kWhatInjectPacket,
-    };
-
-    static const uint32_t kSocketPollTimeoutUs;
-
-    uint32_t mFlags;
-
-    struct StreamInfo;
-    List<StreamInfo> mStreams;
-
-    bool mPollEventPending;
-    int64_t mLastReceiverReportTimeUs;
-
-    void onAddStream(const sp<AMessage> &msg);
-    void onRemoveStream(const sp<AMessage> &msg);
-    void onPollStreams();
-    void onInjectPacket(const sp<AMessage> &msg);
-    void onSendReceiverReports();
-
-    status_t receive(StreamInfo *info, bool receiveRTP);
-
-    status_t parseRTP(StreamInfo *info, const sp<ABuffer> &buffer);
-    status_t parseRTCP(StreamInfo *info, const sp<ABuffer> &buffer);
-    status_t parseSR(StreamInfo *info, const uint8_t *data, size_t size);
-    status_t parseBYE(StreamInfo *info, const uint8_t *data, size_t size);
-
-    sp<ARTPSource> findSource(StreamInfo *info, uint32_t id);
-
-    void postPollEvent();
-
-    DISALLOW_EVIL_CONSTRUCTORS(ARTPConnection);
-};