merge mozilla-central to b2g-inbound
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Thu, 07 Nov 2013 16:01:27 +0100
changeset 153973 393da598b0a98e0e4b220ad57d536c4f8429cc58
parent 153972 17d3151c1b7022ccaeb3377c5198ffbea6519600 (current diff)
parent 153961 7433abfef863802979912bb538fa2b579dfaf422 (diff)
child 153974 9dadec8d0d94b9fddeb6ccd1ce0bd06c58b44a7f
push id25616
push userryanvm@gmail.com
push dateThu, 07 Nov 2013 19:36:12 +0000
treeherdermozilla-central@530f65e0bec5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone28.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 mozilla-central to b2g-inbound
config/makefiles/target_libs.mk
configure.in
content/media/dash/DASHDecoder.cpp
content/media/dash/DASHDecoder.h
content/media/dash/DASHReader.cpp
content/media/dash/DASHReader.h
content/media/dash/DASHRepDecoder.cpp
content/media/dash/DASHRepDecoder.h
content/media/dash/DASHRepReader.h
content/media/dash/Makefile.in
content/media/dash/moz.build
content/media/test/test_can_play_type_dash.html
content/media/test/test_can_play_type_no_dash.html
content/media/test/test_dash_detect_stream_switch.html
js/src/config/makefiles/target_libs.mk
netwerk/dash/moz.build
netwerk/dash/mpd/AdaptationSet.cpp
netwerk/dash/mpd/AdaptationSet.h
netwerk/dash/mpd/IMPDManager.cpp
netwerk/dash/mpd/IMPDManager.h
netwerk/dash/mpd/IMPDParser.h
netwerk/dash/mpd/MPD.cpp
netwerk/dash/mpd/MPD.h
netwerk/dash/mpd/Makefile.in
netwerk/dash/mpd/Period.cpp
netwerk/dash/mpd/Period.h
netwerk/dash/mpd/Representation.cpp
netwerk/dash/mpd/Representation.h
netwerk/dash/mpd/SegmentBase.cpp
netwerk/dash/mpd/SegmentBase.h
netwerk/dash/mpd/moz.build
netwerk/dash/mpd/nsDASHMPDParser.cpp
netwerk/dash/mpd/nsDASHMPDParser.h
netwerk/dash/mpd/nsDASHWebMODManager.cpp
netwerk/dash/mpd/nsDASHWebMODManager.h
netwerk/dash/mpd/nsDASHWebMODParser.cpp
netwerk/dash/mpd/nsDASHWebMODParser.h
--- a/Makefile.in
+++ b/Makefile.in
@@ -12,35 +12,38 @@ ifneq ($(make_min_ver),$(firstword $(sor
 $(error GNU Make $(make_min_ver) or higher is required)
 endif
 endif
 
 export TOPLEVEL_BUILD := 1
 
 default::
 
-ifdef COMPILE_ENVIRONMENT
 include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
-endif
-
 
 include $(topsrcdir)/config/config.mk
 
+ifndef LIBXUL_SDK
+ifdef COMPILE_ENVIRONMENT
+BUILD_JS = 1
+endif
+endif
+
 GARBAGE_DIRS += dist _javagen _profile staticlib
 DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
    config/autoconf.mk \
    mozilla-config.h \
    netwerk/necko-config.h xpcom/xpcom-config.h xpcom/xpcom-private.h \
    .mozconfig.mk
 
 ifndef MOZ_PROFILE_USE
 # We need to explicitly put backend.RecursiveMakeBackend here
 # otherwise the rule in rules.mk doesn't run early enough.
 libs binaries export tools:: CLOBBER $(topsrcdir)/configure config.status backend.RecursiveMakeBackend
-ifndef LIBXUL_SDK
+ifdef BUILD_JS
 libs binaries export tools:: js-config-status
 endif
 endif
 
 CLOBBER: $(topsrcdir)/CLOBBER
 	@echo "STOP!  The CLOBBER file has changed."
 	@echo "Please run the build through a sanctioned build wrapper, such as"
 	@echo "'mach build' or client.mk."
@@ -64,54 +67,54 @@ config.status: $(topsrcdir)/configure
 # this main make file because having it in rules.mk and applied to partial tree
 # builds resulted in a world of hurt. Gory details are in bug 877308.
 #
 # The mach build driver will ensure the backend is up to date for partial tree
 # builds. This cleanly avoids most of the pain.
 
 backend.RecursiveMakeBackend:
 	@echo "Build configuration changed. Regenerating backend."
-	./config.status
+	$(PYTHON) config.status
 
 Makefile: backend.RecursiveMakeBackend
 	@$(TOUCH) $@
 
 include backend.RecursiveMakeBackend.pp
 
 default:: backend.RecursiveMakeBackend
 
-ifndef LIBXUL_SDK
+ifdef BUILD_JS
 .PHONY: js-config-status
 js-config-status:
 	$(call SUBMAKE,backend.RecursiveMakeBackend,js/src,1)
 endif
 
 install_manifests := bin idl include public private sdk
 install_manifest_depends = \
   CLOBBER \
   $(topsrcdir)/configure \
   config.status \
   backend.RecursiveMakeBackend \
   $(NULL)
 
-ifndef LIBXUL_SDK
+ifdef BUILD_JS
 install_manifest_depends += js-config-status
 endif
 
 .PHONY: install-manifests
 install-manifests: $(addprefix install-dist-,$(install_manifests))
 
 .PHONY: $(addprefix install-dist-,$(install_manifests))
 $(addprefix install-dist-,$(install_manifests)): install-dist-%: $(install_manifest_depends)
-	$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$(DIST)/$* _build_manifests/install/dist_$* $(if $(LIBXUL_SDK),,js/src/_build_manifests/install/dist_$*))
+	$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )$(DIST)/$* _build_manifests/install/dist_$* $(if $(BUILD_JS),js/src/_build_manifests/install/dist_$*))
 
 .PHONY: install-tests
 install-manifests: install-tests
 install-tests: $(install_manifest_depends)
-	$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )_tests _build_manifests/install/tests js/src/_build_manifests/install/tests)
+	$(call py_action,process_install_manifest,$(if $(NO_REMOVE),--no-remove )_tests _build_manifests/install/tests $(if $(BUILD_JS),js/src/_build_manifests/install/tests))
 
 
 # _tests should be purged during cleaning. However, we don't want it purged
 # during PGO builds because it contains some auto-generated files.
 ifneq ($(filter-out maybe_clobber_profiledbuild,$(MAKECMDGOALS)),)
 GARBAGE_DIRS += _tests
 endif
 
@@ -137,17 +140,17 @@ endif
 export:: install-dist-sdk
 
 ifdef ENABLE_TESTS
 # Additional makefile targets to call automated test suites
 include $(topsrcdir)/testing/testsuite-targets.mk
 endif
 
 default all::
-	$(call BUILDSTATUS,TIERS export $(if $(MOZ_PSEUDO_DERECURSE),compile )libs tools)
+	$(call BUILDSTATUS,TIERS export $(if $(COMPILE_ENVIRONMENT),$(if $(MOZ_PSEUDO_DERECURSE),compile ))libs tools)
 
 include $(topsrcdir)/config/rules.mk
 
 distclean::
 	$(RM) $(DIST_GARBAGE)
 
 ifeq ($(OS_ARCH),WINNT)
 # we want to copy PDB files on Windows
@@ -242,17 +245,17 @@ endif
 
 # Look for R_386_PC32 relocations in shared libs, these
 # break x86_64 builds and SELinux users.
 ifeq ($(OS_TARGET)_$(TARGET_XPCOM_ABI),Linux_x86-gcc3)
 scheck::
 	@relcount=`find $(DIST)/bin -name "*.so" | xargs objdump -R | grep R_386_PC32 | wc -l` && if test $$relcount -gt 0; then echo "FAILED: R_386_PC32 relocations detected in a shared library.  Did you use a system header without adding it to config/system-headers?"; exit 1; else echo "PASSED"; fi
 endif
 
-ifndef LIBXUL_SDK
+ifdef BUILD_JS
 js/src/Makefile: subsrcdir := js/src
 
 ifdef ENABLE_TESTS
 # Incorporate static tier directories into tests. This should be incorporated
 # into moz.build files someday.
 check::
 	$(call SUBMAKE,$@,js/src)
 endif
--- a/accessible/public/nsIAccessibleHyperLink.idl
+++ b/accessible/public/nsIAccessibleHyperLink.idl
@@ -8,17 +8,17 @@
 
 interface nsIURI;
 interface nsIAccessible;
 
 /**
  * A cross-platform interface that supports hyperlink-specific properties and
  * methods.  Anchors, image maps, xul:labels with class="text-link" implement this interface.
  */
-[scriptable, uuid(38c60bfa-6040-4bfe-93f2-acd6a909bb60)]
+[scriptable, uuid(883643d4-93a5-4f32-922c-6f06e01363c1)]
 interface nsIAccessibleHyperLink : nsISupports
 {
   /**
    * Returns the offset of the link within the parent accessible.
    */
   readonly attribute long startIndex;
 
   /**
@@ -34,26 +34,16 @@ interface nsIAccessibleHyperLink : nsISu
    *
    * @note  XXX Currently only used with ARIA links, and the author has to
    * specify that the link is invalid via the aria-invalid="true" attribute.
    * In all other cases, TRUE is returned.
    */
   readonly attribute boolean valid;
 
   /**
-   * Determines whether the element currently has the focus, e. g. after
-   * returning from the destination page.
-   *
-   * @note  ARIA links can only be focused if they have the tabindex
-   * attribute set.  Also, state_focused should then be set on the accessible
-   * for this link.
-   */
-  readonly attribute boolean selected;
-
-  /**
    * The numbber of anchors within this Hyperlink. Is normally 1 for anchors.
    * This anchor is, for example, the visible output of the html:a tag.
    * With an Image Map, reflects the actual areas within the map.
    */
   readonly attribute long anchorCount;
 
   /**
    * Returns the URI at the given index.
--- a/accessible/src/generic/Accessible.cpp
+++ b/accessible/src/generic/Accessible.cpp
@@ -2420,31 +2420,16 @@ Accessible::GetValid(bool *aValid)
 
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   *aValid = IsLinkValid();
   return NS_OK;
 }
 
-// readonly attribute boolean nsIAccessibleHyperLink::selected
-NS_IMETHODIMP
-Accessible::GetSelected(bool *aSelected)
-{
-  NS_ENSURE_ARG_POINTER(aSelected);
-  *aSelected = false;
-
-  if (IsDefunct())
-    return NS_ERROR_FAILURE;
-
-  *aSelected = IsLinkSelected();
-  return NS_OK;
-
-}
-
 void
 Accessible::AppendTextTo(nsAString& aText, uint32_t aStartOffset,
                          uint32_t aLength)
 {
   // Return text representation of non-text accessible within hypertext
   // accessible. Text accessible overrides this method to return enclosed text.
   if (aStartOffset != 0 || aLength == 0)
     return;
@@ -2774,24 +2759,16 @@ uint32_t
 Accessible::EndOffset()
 {
   NS_PRECONDITION(IsLink(), "EndOffset is called on not hyper link!");
 
   HyperTextAccessible* hyperText = mParent ? mParent->AsHyperText() : nullptr;
   return hyperText ? (hyperText->GetChildOffset(this) + 1) : 0;
 }
 
-bool
-Accessible::IsLinkSelected()
-{
-  NS_PRECONDITION(IsLink(),
-                  "IsLinkSelected() called on something that is not a hyper link!");
-  return FocusMgr()->IsFocused(this);
-}
-
 uint32_t
 Accessible::AnchorCount()
 {
   NS_PRECONDITION(IsLink(), "AnchorCount is called on not hyper link!");
   return 1;
 }
 
 Accessible*
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -625,21 +625,16 @@ public:
     // XXX In order to implement this we would need to follow every link
     // Perhaps we can get information about invalid links from the cache
     // In the mean time authors can use role="link" aria-invalid="true"
     // to force it for links they internally know to be invalid
     return (0 == (State() & mozilla::a11y::states::INVALID));
   }
 
   /**
-   * Return true if the link currently has the focus.
-   */
-  bool IsLinkSelected();
-
-  /**
    * Return the number of anchors within the link.
    */
   virtual uint32_t AnchorCount();
 
   /**
    * Returns an anchor accessible at the given index.
    */
   virtual Accessible* AnchorAt(uint32_t aAnchorIndex);
--- a/accessible/src/jsat/AccessFu.jsm
+++ b/accessible/src/jsat/AccessFu.jsm
@@ -730,16 +730,22 @@ var Input = {
         this.sendContextMenuMessage();
         break;
       case 'swiperight1':
         this.moveCursor('moveNext', 'Simple', 'gestures');
         break;
       case 'swipeleft1':
         this.moveCursor('movePrevious', 'Simple', 'gesture');
         break;
+      case 'swipeup1':
+        this.contextAction('backward');
+        break;
+      case 'swipedown1':
+        this.contextAction('forward');
+        break;
       case 'exploreend1':
         this.activateCurrent(null, true);
         break;
       case 'swiperight2':
         this.sendScrollMessage(-1, true);
         break;
       case 'swipedown2':
         this.sendScrollMessage(-1);
@@ -854,16 +860,22 @@ var Input = {
 
   moveCursor: function moveCursor(aAction, aRule, aInputType) {
     let mm = Utils.getMessageManager(Utils.CurrentBrowser);
     mm.sendAsyncMessage('AccessFu:MoveCursor',
                         {action: aAction, rule: aRule,
                          origin: 'top', inputType: aInputType});
   },
 
+  contextAction: function contextAction(aDirection) {
+    // XXX: For now, the only supported context action is adjusting a range.
+    let mm = Utils.getMessageManager(Utils.CurrentBrowser);
+    mm.sendAsyncMessage('AccessFu:AdjustRange', {direction: aDirection});
+  },
+
   moveByGranularity: function moveByGranularity(aDetails) {
     const MOVEMENT_GRANULARITY_PARAGRAPH = 8;
 
     if (!this.editState.editing) {
       if (aDetails.granularity === MOVEMENT_GRANULARITY_PARAGRAPH) {
         this.moveCursor('move' + aDetails.direction, 'Paragraph', 'gesture');
         return;
       }
--- a/accessible/src/jsat/content-script.js
+++ b/accessible/src/jsat/content-script.js
@@ -326,29 +326,47 @@ function scroll(aMessage) {
   }
 
   let position = Utils.getVirtualCursor(content.document).position;
   if (!forwardToChild(aMessage, scroll, position)) {
     sendScrollCoordinates(position);
   }
 }
 
+function adjustRange(aMessage) {
+  function sendUpDownKey(aAccessible) {
+    let evt = content.document.createEvent('KeyboardEvent');
+    let keycode = aMessage.json.direction == 'forward' ?
+      content.KeyEvent.DOM_VK_DOWN : content.KeyEvent.DOM_VK_UP;
+    evt.initKeyEvent(
+      "keypress", false, true, null, false, false, false, false, keycode, 0);
+    if (aAccessible.DOMNode) {
+      aAccessible.DOMNode.dispatchEvent(evt);
+    }
+  }
+
+  let position = Utils.getVirtualCursor(content.document).position;
+  if (!forwardToChild(aMessage, adjustRange, position)) {
+    sendUpDownKey(position);
+  }
+}
 addMessageListener(
   'AccessFu:Start',
   function(m) {
     Logger.debug('AccessFu:Start');
     if (m.json.buildApp)
       Utils.MozBuildApp = m.json.buildApp;
 
     addMessageListener('AccessFu:MoveToPoint', moveToPoint);
     addMessageListener('AccessFu:MoveCursor', moveCursor);
     addMessageListener('AccessFu:ShowCurrent', showCurrent);
     addMessageListener('AccessFu:Activate', activateCurrent);
     addMessageListener('AccessFu:ContextMenu', activateContextMenu);
     addMessageListener('AccessFu:Scroll', scroll);
+    addMessageListener('AccessFu:AdjustRange', adjustRange);
     addMessageListener('AccessFu:MoveCaret', moveCaret);
     addMessageListener('AccessFu:MoveByGranularity', moveByGranularity);
 
     if (!eventManager) {
       eventManager = new EventManager(this);
     }
     eventManager.start();
   });
--- a/accessible/tests/mochitest/hyperlink/hyperlink.js
+++ b/accessible/tests/mochitest/hyperlink/hyperlink.js
@@ -16,31 +16,25 @@ function focusLink(aID, aSelectedAfter)
   var checker = new invokerChecker(EVENT_FOCUS, this.accessible);
   if (aSelectedAfter)
     this.eventSeq.push(checker);
   else
     this.unexpectedEventSeq.push(checker);
 
   this.invoke = function focusLink_invoke()
   {
-    is(this.accessible.selected, false,
-       "Wrong selected state before focus for ID " + prettyName(aID) + "!");
-
     var expectedStates = (aSelectedAfter ? STATE_FOCUSABLE : 0);
     var unexpectedStates = (!aSelectedAfter ? STATE_FOCUSABLE : 0) | STATE_FOCUSED;
     testStates(aID, expectedStates, 0, unexpectedStates, 0);
 
     this.node.focus();
   }
 
   this.finalCheck = function focusLink_finalCheck()
   {
-    is(this.accessible.selected, aSelectedAfter,
-       "Wrong seleccted state after focus for ID " + prettyName(aID) + "!");
-
     var expectedStates = (aSelectedAfter ? STATE_FOCUSABLE | STATE_FOCUSED : 0);
     var unexpectedStates = (!aSelectedAfter ? STATE_FOCUSABLE | STATE_FOCUSED : 0);
     testStates(aID, expectedStates, 0, unexpectedStates, 0);
   }
 
   this.getID = function focusLink_getID()
   {
     return "focus hyperlink " + prettyName(aID);
--- a/b2g/app/Makefile.in
+++ b/b2g/app/Makefile.in
@@ -108,44 +108,41 @@ APP_VERSION = $(MOZ_APP_VERSION)
 ifdef MOZ_DEBUG
 APP_NAME := $(APP_NAME)Debug
 endif
 
 AB_CD = $(MOZ_UI_LOCALE)
 
 AB := $(firstword $(subst -, ,$(AB_CD)))
 
-clean clobber repackage::
+clean clobber::
 	rm -rf $(DIST)/$(APP_NAME).app
 
 ifdef LIBXUL_SDK
 APPFILES = Resources
 else
 APPFILES = MacOS
 endif
 
 libs-preqs = \
   $(call mkdir_deps,$(DIST)/$(APP_NAME).app/Contents/MacOS) \
   $(call mkdir_deps,$(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj) \
   $(NULL)
 
 .PHONY: repackage
-tools repackage:: $(libs-preqs)
+libs:: $(libs-preqs)
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(DIST)/$(APP_NAME).app --exclude English.lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj
 	sed -e "s/%MOZ_APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MOZ_APP_NAME%/$(MOZ_APP_NAME)/" -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" -e "s/%APP_BINARY%/$(APP_BINARY)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(DIST)/$(APP_NAME).app/Contents/Info.plist
 	sed -e "s/%APP_VERSION%/$(APP_VERSION)/" -e "s/%APP_NAME%/$(APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(DIST)/$(APP_NAME).app/Contents/Resources/$(AB).lproj/InfoPlist.strings
-	rsync -a $(DIST)/bin/ $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
-	$(RM) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/mangle $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)/shlibsign
+	rm -rf $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
+	ln -s $(abspath $(DIST)/bin) $(DIST)/$(APP_NAME).app/Contents/$(APPFILES)
 ifdef LIBXUL_SDK
 	cp $(LIBXUL_DIST)/bin/xulrunner$(BIN_SUFFIX) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(APP_BINARY)
 	rsync -a --exclude nsinstall --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(DIST)/$(APP_NAME).app/Contents/Frameworks
-else
-	$(RM) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
-	rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
 endif
 	cp -RL $(srcdir)/b2g.icns $(DIST)/$(APP_NAME).app/Contents/Resources/$(MOZ_APP_NAME).icns
 	printf "APPLMOZB" > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
 
 else # MOZ_WIDGET_TOOLKIT != cocoa
 
 libs::
 ifdef LIBXUL_SDK
--- a/b2g/locales/Makefile.in
+++ b/b2g/locales/Makefile.in
@@ -52,21 +52,16 @@ include $(topsrcdir)/toolkit/locales/l10
 $(DIST)/branding:
 	$(NSINSTALL) -D $@
 
 libs::
 	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
 	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
 	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(FINAL_TARGET)/defaults/existing-profile-defaults.js; \
 	fi
-install::
-	@if test -f "$(LOCALE_SRCDIR)/existing-profile-defaults.js"; then \
-	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(PREF_PPFLAGS) $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) \
-	    $(LOCALE_SRCDIR)/existing-profile-defaults.js > $(DESTDIR)$(mozappdir)/defaults/existing-profile-defaults.js; \
-	fi
 
 NO_JA_JP_MAC_AB_CD := $(if $(filter ja-JP-mac, $(AB_CD)),ja,$(AB_CD))
 
 libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$*
 	@$(MAKE) -C ../../intl/locales AB_CD=$* XPI_NAME=locale-$*
 	@$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
--- a/browser/app/Makefile.in
+++ b/browser/app/Makefile.in
@@ -115,18 +115,20 @@ ifeq ($(OS_ARCH),WINNT) #{
 #
 ifndef GNU_CC #{
 LDFLAGS += /HEAP:0x40000
 endif #}
 endif #}
 
 ifneq (,$(filter-out OS2 WINNT,$(OS_ARCH)))
 
+ifdef COMPILE_ENVIRONMENT
 libs:: 
 	cp -p $(MOZ_APP_NAME)$(BIN_SUFFIX) $(DIST)/bin/$(MOZ_APP_NAME)-bin$(BIN_SUFFIX)
+endif
 
 GARBAGE += $(addprefix $(FINAL_TARGET)/defaults/pref/, firefox.js)
 
 endif
 
 ifdef MOZ_WIDGET_GTK
 libs::
 	$(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(FINAL_TARGET)/icons
@@ -155,38 +157,40 @@ MAC_APP_NAME = $(MOZ_APP_DISPLAYNAME)
 ifdef MOZ_DEBUG
 MAC_APP_NAME := $(MAC_APP_NAME)Debug
 endif
 
 AB_CD = $(MOZ_UI_LOCALE)
 
 AB := $(firstword $(subst -, ,$(AB_CD)))
 
-clean clobber repackage::
+clean clobber::
 	$(RM) -r $(dist_dest)
 
 ifdef LIBXUL_SDK
 APPFILES = Resources
 else
 APPFILES = MacOS
 endif
 
 MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid)
 
-.PHONY: repackage
-tools repackage:: $(PROGRAM)
+libs:: $(PROGRAM)
 	$(MKDIR) -p $(dist_dest)/Contents/MacOS
 	$(MKDIR) -p $(dist_dest)/Contents/Resources/$(AB).lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents $(dist_dest) --exclude English.lproj
 	rsync -a --exclude "*.in" $(srcdir)/macbuild/Contents/Resources/English.lproj/ $(dist_dest)/Contents/Resources/$(AB).lproj
 	sed -e "s/%APP_VERSION%/$(MOZ_APP_VERSION)/" -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" -e "s/%MOZ_MACBUNDLE_ID%/$(MOZ_MACBUNDLE_ID)/" -e "s/%MAC_BUNDLE_VERSION%/$(MAC_BUNDLE_VERSION)/" $(srcdir)/macbuild/Contents/Info.plist.in > $(dist_dest)/Contents/Info.plist
 	sed -e "s/%MAC_APP_NAME%/$(MAC_APP_NAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | iconv -f UTF-8 -t UTF-16 > $(dist_dest)/Contents/Resources/$(AB).lproj/InfoPlist.strings
-	rsync -a $(DIST)/bin/ $(dist_dest)/Contents/$(APPFILES)
+	rm -rf $(dist_dest)/Contents/$(APPFILES)
+	ln -s $(abspath $(DIST)/bin) $(dist_dest)/Contents/$(APPFILES)
+ifdef LIBXUL_SDK
 	$(RM) $(dist_dest)/Contents/MacOS/$(PROGRAM)
 	rsync -aL $(PROGRAM) $(dist_dest)/Contents/MacOS
+endif
 	cp -RL $(DIST)/branding/firefox.icns $(dist_dest)/Contents/Resources/firefox.icns
 	cp -RL $(DIST)/branding/document.icns $(dist_dest)/Contents/Resources/document.icns
 	printf APPLMOZB > $(dist_dest)/Contents/PkgInfo
 endif
 
 ifdef LIBXUL_SDK #{
 ifndef SKIP_COPY_XULRUNNER #{
 libs::
--- a/browser/locales/Makefile.in
+++ b/browser/locales/Makefile.in
@@ -115,24 +115,16 @@ NO_JA_JP_MAC_AB_CD := $(if $(filter ja-J
 libs:: $(FINAL_TARGET)/defaults/profile/bookmarks.html ;
 
 libs:: $(addprefix generic/profile/,$(PROFILE_FILES))
 	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile
 
 libs:: $(call MERGE_FILES,$(addprefix profile/chrome/,$(PROFILE_CHROME)))
 	$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/defaults/profile/chrome
 
-install:: $(DESTDIR)$(mozappdir)/defaults/profile/bookmarks.html ;
-
-install:: $(addprefix generic/profile/,$(PROFILE_FILES))
-	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/defaults/profile
-
-install:: $(call MERGE_FILES,$(addprefix profile/chrome/,$(PROFILE_CHROME)))
-	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/defaults/profile/chrome
-
 # metro build calls back here for search engine plugins
 searchplugins: $(addprefix $(FINAL_TARGET)/searchplugins/,$(SEARCHPLUGINS))
 .PHONY: searchplugins
 
 libs-%:
 	$(NSINSTALL) -D $(DIST)/install
 	@$(MAKE) -C ../../toolkit/locales libs-$*
 	@$(MAKE) -C ../../services/sync/locales AB_CD=$* XPI_NAME=locale-$*
--- a/browser/metro/base/content/ContextUI.js
+++ b/browser/metro/base/content/ContextUI.js
@@ -287,17 +287,19 @@ var ContextUI = {
     // dismiss tabs and context app bar if visible
     this.dismissTabs();
     this.dismissContextAppbar();
   },
 
   handleEvent: function handleEvent(aEvent) {
     switch (aEvent.type) {
       case "URLChanged":
-        this.displayNavbar();
+        if (aEvent.target == Browser.selectedBrowser) {
+          this.displayNavbar();
+        }
         break;
       case "MozEdgeUIStarted":
         this._onEdgeUIStarted(aEvent);
         break;
       case "MozEdgeUICanceled":
         this._onEdgeUICanceled(aEvent);
         break;
       case "MozEdgeUICompleted":
--- a/browser/metro/shell/Makefile.in
+++ b/browser/metro/shell/Makefile.in
@@ -1,9 +1,6 @@
 # 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/.
 
 export::
 	$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
-
-install::
-	$(NSINSTALL) $(srcdir)/resources.pri $(DIST)/bin
--- a/build/unix/elfhack/Makefile.in
+++ b/build/unix/elfhack/Makefile.in
@@ -35,23 +35,25 @@ test-array$(DLL_SUFFIX) test-ctors$(DLL_
 
 test-array$(DLL_SUFFIX): DT_TYPE=INIT_ARRAY
 test-ctors$(DLL_SUFFIX): DT_TYPE=INIT
 
 .PRECIOUS: test-array$(DLL_SUFFIX) test-ctors$(DLL_SUFFIX)
 
 GARBAGE += test-array$(DLL_SUFFIX) test-ctors$(DLL_SUFFIX) test-array$(DLL_SUFFIX).bak test-ctors$(DLL_SUFFIX).bak
 
+ifndef CROSS_COMPILE
+ifdef COMPILE_ENVIRONMENT
 libs:: test-array$(DLL_SUFFIX) test-ctors$(DLL_SUFFIX)
 
-ifndef CROSS_COMPILE
 dummy: dummy.$(OBJ_SUFFIX)
 	$(CC) -o $@ $^ $(LDFLAGS)
 
 libs:: dummy
 	# Will either crash or return exit code 1 if elfhack is broken
 	LD_PRELOAD=$(CURDIR)/test-array$(DLL_SUFFIX) $(CURDIR)/dummy
 	LD_PRELOAD=$(CURDIR)/test-ctors$(DLL_SUFFIX) $(CURDIR)/dummy
 
 GARBAGE += dummy
 endif
+endif
 
 test.$(OBJ_SUFFIX): CFLAGS := -O0
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -4,44 +4,48 @@
 # 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/.
 
 # STDCXX_COMPAT is not needed here, and will actually fail because
 # libstdc++-compat is not built yet.
 MOZ_LIBSTDCXX_HOST_VERSION =
 
 ifndef CROSS_COMPILE
+ifdef COMPILE_ENVIRONMENT
 ifdef USE_ELF_DYNSTR_GC
 export:: elf-dynstr-gc
 endif
 endif
+endif
 
 # IMPORTANT: Disable NSBUILDROOT for this directory only, otherwise we have
 # a recursive rule for finding nsinstall and the Perl scripts.
 ifdef NSBUILDROOT
 override NSBUILDROOT :=
 endif
 
 ifdef GNU_CC
 MODULE_OPTIMIZE_FLAGS = -O3
 endif
 
 include $(topsrcdir)/config/config.mk
 
 ifneq (WINNT,$(HOST_OS_ARCH))
+ifdef COMPILE_ENVIRONMENT
 # Ensure nsinstall is atomically created
 nsinstall$(HOST_BIN_SUFFIX): $(HOST_PROGRAM)
 	cp $^ $@.tmp
 	mv $@.tmp $@
 
 NSINSTALL_FILES := nsinstall$(HOST_BIN_SUFFIX)
 NSINSTALL_DEST := $(DIST)/bin
 NSINSTALL_TARGET := export
 INSTALL_TARGETS += NSINSTALL
 endif
+endif
 
 HEADERS_FILES = \
 	$(DEPTH)/mozilla-config.h \
 	$(NULL)
 HEADERS_DEST := $(DIST)/include
 HEADERS_TARGET := export
 INSTALL_TARGETS += HEADERS
 
@@ -106,19 +110,16 @@ STL_WRAPPERS_SENTINEL = $(DIST)/stl_wrap
 	touch $(STL_WRAPPERS_SENTINEL)
 
 export:: $(STL_WRAPPERS_SENTINEL)
 
 GARBAGE += $(STL_WRAPPERS_SENTINEL)
 GARBAGE_DIRS += stl_wrappers
 endif
 
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(DEPTH)/mozilla-config.h $(DESTDIR)$(includedir)
-
 GARBAGE += \
   $(FINAL_LINK_COMPS) $(FINAL_LINK_LIBS) $(FINAL_LINK_COMP_NAMES) buildid $(srcdir)/*.pyc *.pyc
 
 ifndef CROSS_COMPILE
 ifdef USE_ELF_DYNSTR_GC
 elf-dynstr-gc: elf-dynstr-gc.c $(GLOBAL_DEPS) $(call mkdir_deps,$(MDDEPDIR))
 	$(CC) $(COMPILE_CFLAGS) $(GLIB_CFLAGS) -DELFDYNSTRGC_BUILD -o $@ $< $(LDFLAGS) $(GLIB_LIBS)
 endif
--- a/config/config.mk
+++ b/config/config.mk
@@ -617,18 +617,23 @@ endif
 ifneq (WINNT_,$(OS_ARCH)_$(GNU_CC))
 LIBS_DIR	= -L$(DIST)/bin -L$(DIST)/lib
 ifdef LIBXUL_SDK
 LIBS_DIR	+= -L$(LIBXUL_SDK)/bin -L$(LIBXUL_SDK)/lib
 endif
 endif
 
 # Default location of include files
+ifndef LIBXUL_SDK
 IDL_PARSER_DIR = $(topsrcdir)/xpcom/idl-parser
 IDL_PARSER_CACHE_DIR = $(DEPTH)/xpcom/idl-parser
+else
+IDL_PARSER_DIR = $(LIBXUL_SDK)/sdk/bin
+IDL_PARSER_CACHE_DIR = $(LIBXUL_SDK)/sdk/bin
+endif
 
 SDK_LIB_DIR = $(DIST)/sdk/lib
 SDK_BIN_DIR = $(DIST)/sdk/bin
 
 DEPENDENCIES	= .md
 
 MOZ_COMPONENT_LIBS=$(XPCOM_LIBS) $(MOZ_COMPONENT_NSPR_LIBS)
 
rename from config/makefiles/target_libs.mk
rename to config/makefiles/target_binaries.mk
--- a/config/makefiles/xpidl/Makefile.in
+++ b/config/makefiles/xpidl/Makefile.in
@@ -44,16 +44,20 @@ dist_include_dir := $(DIST)/include
 process_py := $(topsrcdir)/python/mozbuild/mozbuild/action/xpidl-process.py
 
 # TODO we should use py_action, but that would require extra directories to be
 # in the virtualenv.
 idlprocess := $(PYTHON_PATH) $(PLY_INCLUDE) -I$(IDL_PARSER_DIR) -I$(IDL_PARSER_CACHE_DIR) \
     $(process_py) --cache-dir $(IDL_PARSER_CACHE_DIR) $(dist_idl_dir) \
         $(dist_include_dir) $(idl_xpt_dir) $(idl_deps_dir)
 
+ifdef LIBXUL_SDK
+idlprocess += -I$(LIBXUL_SDK)/idl
+endif
+
 xpidl_modules := @xpidl_modules@
 
 @xpidl_rules@
 
 linked_xpt_files := $(addprefix $(idl_xpt_dir)/,$(addsuffix .xpt,$(xpidl_modules)))
 depends_files := $(foreach root,$(xpidl_modules),$(idl_deps_dir)/$(root).pp)
 
 GARBAGE += $(linked_xpt_files) $(depends_files)
--- a/config/recurse.mk
+++ b/config/recurse.mk
@@ -107,16 +107,17 @@ endif
 $(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
 
 # The export tier requires nsinstall, which is built from config. So every
 # subdirectory traversal needs to happen after traversing config.
 ifeq ($(CURRENT_TIER),export)
 $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER)
 endif
 
+ifdef COMPILE_ENVIRONMENT
 ifneq (,$(filter libs binaries,$(CURRENT_TIER)))
 # When doing a "libs" build, target_libs.mk ensures the interesting dependency data
 # is available in the "binaries" stamp. Once recursion is done, aggregate all that
 # dependency info so that stamps depend on relevant files and relevant other stamps.
 # When doing a "binaries" build, the aggregate dependency file and those stamps are
 # used and allow to skip recursing directories where changes are not going to require
 # rebuild. A few directories, however, are still traversed all the time, mostly, the
 # gyp managed ones and js/src.
@@ -134,16 +135,18 @@ binaries-deps: $(addsuffix /binaries,$(C
 ifeq (recurse_binaries,$(MAKECMDGOALS))
 $(call include_deps,binaries-deps.mk)
 endif
 
 endif
 
 DIST_GARBAGE += binaries-deps.mk binaries-deps
 
+endif
+
 else
 
 # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above, but
 # still recurse for externally managed make files (gyp-generated ones).
 ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL))
 
 compile binaries libs export tools::
 
@@ -204,16 +207,18 @@ ifeq (.,$(DEPTH))
 recurse_targets := $(addsuffix /binaries,$(binaries_dirs))
 ifdef recurse_targets
 # only js/src has binaries_dirs, and we want to adjust paths for it.
 want_abspaths = 1
 endif
 endif
 endif
 
+ifdef COMPILE_ENVIRONMENT
+
 # Aggregate all dependency files relevant to a binaries build except in
 # the mozilla top-level directory.
 ifneq (_.,$(recurse_targets)_$(DEPTH))
 ALL_DEP_FILES := \
   $(BINARIES_PP) \
   $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
     $(TARGETS) \
     $(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
@@ -222,9 +227,11 @@ ALL_DEP_FILES := \
   $(NULL)
 endif
 
 binaries libs:: $(TARGETS) $(BINARIES_PP)
 ifneq (_.,$(recurse_targets)_$(DEPTH))
 	@$(if $(or $(recurse_targets),$^),$(call py_action,link_deps,-o binaries --group-all $(if $(want_abspaths),--abspaths )--topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
 endif
 
+endif
+
 endif # ifdef MOZ_PSEUDO_DERECURSE
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -117,16 +117,17 @@ CSRCS += $(GTEST_CSRCS)
 endif
 
 ifdef GTEST_CMMSRCS
 CMMSRCS += $(GTEST_CMMSRCS)
 endif
 endif
 
 ifdef CPP_UNIT_TESTS
+ifdef COMPILE_ENVIRONMENT
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
 CPPSRCS += $(CPP_UNIT_TESTS)
 CPP_UNIT_TEST_BINS := $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
 SIMPLE_PROGRAMS += $(CPP_UNIT_TEST_BINS)
 INCLUDES += -I$(DIST)/include/testing
@@ -148,16 +149,17 @@ cppunittests-remote:
 			--localLib=$(DEPTH)/dist/$(MOZ_APP_NAME) \
 			--dm_trans=$(DM_TRANS) \
 			--deviceIP=${TEST_DEVICE} \
 			$(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)) $(EXTRA_TEST_ARGS); \
 	else \
 		echo "please prepare your host with environment variables for TEST_DEVICE"; \
 	fi
 
+endif # COMPILE_ENVIRONMENT
 endif # CPP_UNIT_TESTS
 
 .PHONY: check
 
 ifdef PYTHON_UNIT_TESTS
 
 RUN_PYTHON_UNIT_TESTS := $(addsuffix -run,$(PYTHON_UNIT_TESTS))
 
@@ -298,16 +300,17 @@ HOST_PDBFILE=$(basename $(@F)).pdb
 endif
 
 # Don't build SIMPLE_PROGRAMS during the MOZ_PROFILE_GENERATE pass
 ifdef MOZ_PROFILE_GENERATE
 EXCLUDED_OBJS := $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.$(OBJ_SUFFIX))
 SIMPLE_PROGRAMS :=
 endif
 
+ifdef COMPILE_ENVIRONMENT
 ifndef TARGETS
 TARGETS			= $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS)
 endif
 
 COBJS = $(notdir $(CSRCS:.c=.$(OBJ_SUFFIX)))
 SOBJS = $(notdir $(SSRCS:.S=.$(OBJ_SUFFIX)))
 # CPPSRCS can have different extensions (eg: .cpp, .cc)
 CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS))))
@@ -323,16 +326,29 @@ HOST_COBJS = $(addprefix host_,$(notdir 
 # HOST_CPPOBJS can have different extensions (eg: .cpp, .cc)
 HOST_CPPOBJS = $(addprefix host_,$(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(HOST_CPPSRCS)))))
 HOST_CMOBJS = $(addprefix host_,$(notdir $(HOST_CMSRCS:.m=.$(OBJ_SUFFIX))))
 HOST_CMMOBJS = $(addprefix host_,$(notdir $(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX))))
 ifndef HOST_OBJS
 _HOST_OBJS = $(HOST_COBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
 HOST_OBJS = $(strip $(_HOST_OBJS))
 endif
+else
+LIBRARY :=
+SHARED_LIBRARY :=
+IMPORT_LIBRARY :=
+REAL_LIBRARY :=
+PROGRAM :=
+SIMPLE_PROGRAMS :=
+HOST_LIBRARY :=
+HOST_PROGRAM :=
+HOST_SIMPLE_PROGRAMS :=
+SDK_BINARY := $(filter %.py,$(SDK_BINARY))
+SDK_LIBRARY :=
+endif
 
 ALL_TRASH = \
 	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
 	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
 	$(OBJS:.$(OBJ_SUFFIX)=.i) $(OBJS:.$(OBJ_SUFFIX)=.i_o) \
 	$(HOST_PROGOBJS) $(HOST_OBJS) $(IMPORT_LIBRARY) $(DEF_FILE)\
 	$(EXE_DEF_FILE) so_locations _gen _stubs $(wildcard *.res) $(wildcard *.RES) \
 	$(wildcard *.pdb) $(CODFILE) $(IMPORT_LIBRARY) \
@@ -608,18 +624,20 @@ endif
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
 default all::
 	$(MAKE) export
 ifdef MOZ_PSEUDO_DERECURSE
+ifdef COMPILE_ENVIRONMENT
 	$(MAKE) compile
 endif
+endif
 	$(MAKE) libs
 	$(MAKE) tools
 endif # SUPPRESS_DEFAULT_RULES
 
 ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),)
 ECHO := echo
 QUIET :=
 else
@@ -637,21 +655,23 @@ ifneq (,$(filter-out %.$(LIB_SUFFIX),$(S
 endif
 
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
+ifdef COMPILE_ENVIRONMENT
 OBJ_TARGETS = $(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS)
 
 compile:: $(OBJ_TARGETS)
 
-include $(topsrcdir)/config/makefiles/target_libs.mk
+include $(topsrcdir)/config/makefiles/target_binaries.mk
+endif
 
 ifdef IS_TOOL_DIR
 # One would think "tools:: libs" would work, but it turns out that combined with
 # bug 907365, this makes make forget to run some rules sometimes.
 tools::
 	@$(MAKE) libs
 endif
 
@@ -1348,17 +1368,17 @@ endif
 
 ifneq ($(DIST_CHROME_FILES),)
 DIST_CHROME_FILES_PATH := $(FINAL_TARGET)/chrome
 DIST_CHROME_FILES_FLAGS := $(XULAPP_DEFINES)
 PP_TARGETS += DIST_CHROME_FILES
 endif
 
 ifneq ($(XPI_PKGNAME),)
-tools realchrome::
+libs realchrome::
 ifdef STRIP_XPI
 ifndef MOZ_DEBUG
 	@echo "Stripping $(XPI_PKGNAME) package directory..."
 	@echo $(FINAL_TARGET)
 	@cd $(FINAL_TARGET) && find . ! -type d \
 			! -name "*.js" \
 			! -name "*.xpt" \
 			! -name "*.gif" \
@@ -1387,17 +1407,17 @@ endif
 	cd $(FINAL_TARGET) && $(ZIP) -qr ../$(XPI_PKGNAME).xpi *
 endif
 
 ifdef INSTALL_EXTENSION_ID
 ifndef XPI_NAME
 $(error XPI_NAME must be set for INSTALL_EXTENSION_ID)
 endif
 
-tools::
+libs::
 	$(RM) -r "$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)"
 	$(NSINSTALL) -D "$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)"
 	$(call copy_dir,$(FINAL_TARGET),$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID))
 
 endif
 
 #############################################################################
 # MDDEPDIR is the subdirectory where all the dependency files are placed.
--- a/configure.in
+++ b/configure.in
@@ -2493,19 +2493,20 @@ case "$target" in
            MOZ_COMPONENTS_VERSION_SCRIPT_LDFLAGS='-Wl,--version-script,$(BUILD_TOOLS)/gnu-ld-scripts/components-version-script'
         fi
         ;;
 esac
 
 if test -z "$COMPILE_ENVIRONMENT"; then
     SKIP_COMPILER_CHECKS=1
     SKIP_LIBRARY_CHECKS=1
-fi
-
-MOZ_COMPILER_OPTS
+else
+    MOZ_COMPILER_OPTS
+fi
+
 if test -z "$SKIP_COMPILER_CHECKS"; then
 dnl Checks for typedefs, structures, and compiler characteristics.
 dnl ========================================================
 AC_HEADER_STDC
 AC_C_CONST
 AC_TYPE_MODE_T
 AC_TYPE_OFF_T
 AC_TYPE_PID_T
@@ -3923,17 +3924,16 @@ MOZ_SOUNDTOUCH=1
 MOZ_CUBEB=
 MOZ_VORBIS=
 MOZ_TREMOR=
 MOZ_WAVE=1
 MOZ_SAMPLE_TYPE_FLOAT32=
 MOZ_SAMPLE_TYPE_S16=
 MOZ_OPUS=1
 MOZ_WEBM=1
-MOZ_DASH=
 MOZ_DIRECTSHOW=
 MOZ_WMF=
 MOZ_WEBRTC=1
 MOZ_PEERCONNECTION=
 MOZ_SRTP=
 MOZ_WEBRTC_SIGNALING=
 MOZ_WEBRTC_ASSERT_ALWAYS=1
 MOZ_SCTP=
@@ -7174,17 +7174,17 @@ if test "$USE_ELF_HACK" = 1; then
         esac
         ;;
     *)
         USE_ELF_HACK=
         ;;
     esac
 fi
 
-if test -n "$USE_ELF_HACK"; then
+if test -n "$COMPILE_ENVIRONMENT" -a -n "$USE_ELF_HACK"; then
     dnl PT_GNU_RELRO segment makes the dynamic linker set a read-only flag on
     dnl memory addresses it maps to. The result is that by the time elfhack
     dnl kicks in, it is not possible to apply relocations because of that,
     dnl thus elfhack effectively skips relocations inside the PT_GNU_RELRO
     dnl segment. It makes elfhack mostly useless, so considering the problems
     dnl we have we PT_GNU_RELRO (e.g. bug 664366), and until elfhack can deal
     dnl with PT_GNU_RELRO segments, it's just simpler to disable elfhack when
     dnl the linker creates PT_GNU_RELRO segments. However, when we do want
@@ -7877,17 +7877,19 @@ else
     PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.19.2)
     MOZ_PIXMAN_CFLAGS="$PIXMAN_CFLAGS"
     MOZ_PIXMAN_LIBS="$PIXMAN_LIBS"
 fi
 AC_SUBST(MOZ_PIXMAN_CFLAGS)
 AC_SUBST(MOZ_PIXMAN_LIBS)
 
 # Check for headers defining standard int types.
-MOZ_CHECK_HEADERS(stdint.h inttypes.h sys/int_types.h)
+if test -n "$COMPILE_ENVIRONMENT"; then
+    MOZ_CHECK_HEADERS(stdint.h inttypes.h sys/int_types.h)
+fi
 
 if test "$MOZ_TREE_CAIRO"; then
     MOZ_CAIRO_CFLAGS='-I$(LIBXUL_DIST)/include/cairo'
     AC_DEFINE(MOZ_TREE_CAIRO)
 
     # For now we assume that we will have a uint64_t available through
     # one of the above headers or mozstdint.h.
     AC_DEFINE(HAVE_UINT64_T)
@@ -8633,17 +8635,16 @@ AC_SUBST(MOZ_APP_EXTRA_LIBS)
 AC_SUBST(MOZ_SPEEX_RESAMPLER)
 AC_SUBST(MOZ_SOUNDTOUCH)
 AC_SUBST(MOZ_CUBEB)
 AC_SUBST(MOZ_WAVE)
 AC_SUBST(MOZ_VORBIS)
 AC_SUBST(MOZ_TREMOR)
 AC_SUBST(MOZ_OPUS)
 AC_SUBST(MOZ_WEBM)
-AC_SUBST(MOZ_DASH)
 AC_SUBST(MOZ_WMF)
 AC_SUBST(MOZ_DIRECTSHOW)
 AC_SUBST(MOZ_MEDIA_PLUGINS)
 AC_SUBST(MOZ_APPLEMEDIA)
 AC_SUBST(MOZ_OMX_PLUGIN)
 AC_SUBST(MOZ_VP8_ERROR_CONCEALMENT)
 AC_SUBST(MOZ_VP8_ENCODER)
 AC_SUBST(MOZ_VP8)
@@ -8664,32 +8665,32 @@ AC_SUBST(LIBJPEG_TURBO_X64_ASM)
 AC_SUBST(LIBJPEG_TURBO_ARM_ASM)
 
 AC_SUBST(MOZ_PACKAGE_JSSHELL)
 AC_SUBST(MOZ_FOLD_LIBS)
 
 AC_SUBST(MOZ_ENABLE_SZIP)
 AC_SUBST(MOZ_SZIP_FLAGS)
 
+if test -n "$COMPILE_ENVIRONMENT"; then
 AC_MSG_CHECKING([for posix_fallocate])
 AC_TRY_LINK([#define _XOPEN_SOURCE 600
   #include <fcntl.h>],
                  [posix_fallocate(0, 0, 0);],
                  [ac_cv___posix_fallocate=true],
                  [ac_cv___posix_fallocate=false])
 
 if test "$ac_cv___posix_fallocate" = true ; then
   AC_DEFINE(HAVE_POSIX_FALLOCATE)
   AC_MSG_RESULT(yes)
 else
   AC_MSG_RESULT(no)
 fi
 
 dnl Check for missing components
-if test "$COMPILE_ENVIRONMENT"; then
 if test "$MOZ_X11"; then
     if test "$WITHOUT_X11"; then
         AC_MSG_ERROR([--without-x specified and MOZ_X11 still defined])
     fi
     dnl ====================================================
     dnl = Check if X headers exist
     dnl ====================================================
     _SAVE_CFLAGS=$CFLAGS
--- a/content/base/public/nsIMessageManager.idl
+++ b/content/base/public/nsIMessageManager.idl
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 
 interface nsIDOMDOMStringList;
 interface nsIDOMWindow;
 interface nsIDocShell;
 interface nsIContent;
+interface nsIPrincipal;
 
 /**
  * Message managers provide a way for chrome-privileged JS code to
  * communicate with each other, even across process boundaries.
  *
  * Message managers are separated into "parent side" and "child side".
  * These don't always correspond to process boundaries, but can.  For
  * each child-side message manager, there is always exactly one
@@ -151,24 +152,25 @@ interface nsIContent;
 [scriptable, function, uuid(2b44eb57-a9c6-4773-9a1e-fe0818739a4c)]
 interface nsIMessageListener : nsISupports
 {
   /**
    * This is for JS only.
    * receiveMessage is called with one parameter, which has the following
    * properties:
    *   {
-   *     target:  %the target of the message. Either an element owning
-   *               the message manager, or message manager itself if no
-   *               element owns it%
-   *     name:    %message name%,
-   *     sync:    %true or false%.
-   *     data:    %structured clone of the sent message data%,
-   *     json:    %same as .data, deprecated%,
-   *     objects: %named table of jsvals/objects, or null%
+   *     target:    %the target of the message. Either an element owning
+   *                 the message manager, or message manager itself if no
+   *                 element owns it%
+   *     name:      %message name%,
+   *     sync:      %true or false%.
+   *     data:      %structured clone of the sent message data%,
+   *     json:      %same as .data, deprecated%,
+   *     objects:   %named table of jsvals/objects, or null%
+   *     principal: %principal for the window app
    *   }
    *
    * Each listener is invoked with its own copy of the message
    * parameter.
    *
    * When the listener is called, 'this' value is the target of the message.
    *
    * If the message is synchronous, the possible return value is
@@ -226,17 +228,17 @@ interface nsIMessageListenerManager : ns
 };
 
 /**
  * Message "senders" have a single "other side" to which messages are
  * sent.  For example, a child-process message manager will send
  * messages that are only delivered to its one parent-process message
  * manager.
  */
-[scriptable, builtinclass, uuid(7f23767d-0f39-40c1-a22d-d3ab8a481f9d)]
+[scriptable, builtinclass, uuid(d6b0d851-43e6-426d-9f13-054bc0198175)]
 interface nsIMessageSender : nsIMessageListenerManager
 {
   /**
    * Send |messageName| and |obj| to the "other side" of this message
    * manager.  This invokes listeners who registered for
    * |messageName|.
    *
    * See nsIMessageListener::receiveMessage() for the format of the
@@ -247,17 +249,18 @@ interface nsIMessageSender : nsIMessageL
    *         yet been set up.
    * @throws NS_ERROR_FAILURE when the message receiver cannot be found.  For
    *         example, we will throw NS_ERROR_FAILURE if we try to send a message
    *         to a cross-process frame whose process has crashed.
    */
   [implicit_jscontext, optional_argc]
   void sendAsyncMessage([optional] in AString messageName,
                         [optional] in jsval obj,
-                        [optional] in jsval objects);
+                        [optional] in jsval objects,
+                        [optional] in nsIPrincipal principal);
 };
 
 /**
  * Message "broadcasters" don't have a single "other side" that they
  * send messages to, but rather a set of subordinate message managers.
  * For example, broadcasting a message through a window message
  * manager will broadcast the message to all frame message managers
  * within its window.
@@ -284,42 +287,44 @@ interface nsIMessageBroadcaster : nsIMes
   readonly attribute unsigned long childCount;
 
   /**
    * Return a single subordinate message manager.
    */
   nsIMessageListenerManager getChildAt(in unsigned long aIndex);
 };
 
-[scriptable, builtinclass, uuid(79eeb70f-58e3-4d32-b46f-106f42ada12b)]
+[scriptable, builtinclass, uuid(7fda0941-9dcc-448b-bd39-16373c5b4003)]
 interface nsISyncMessageSender : nsIMessageSender
 {
   /**
    * Like |sendAsyncMessage()|, except blocks the sender until all
    * listeners of the message have been invoked.  Returns an array
    * containing return values from each listener invoked.
    */
   [implicit_jscontext, optional_argc]
   jsval sendSyncMessage([optional] in AString messageName,
                         [optional] in jsval obj,
-                        [optional] in jsval objects);
+                        [optional] in jsval objects,
+                        [optional] in nsIPrincipal principal);
 
   /**
    * Like |sendSyncMessage()|, except re-entrant. New RPC messages may be
    * issued even if, earlier on the call stack, we are waiting for a reply
    * to an earlier sendRpcMessage() call.
    *
    * Both sendSyncMessage and sendRpcMessage will block until a reply is
    * received, but they may be temporarily interrupted to process an urgent
    * incoming message (such as a CPOW request).
    */
   [implicit_jscontext, optional_argc]
   jsval sendRpcMessage([optional] in AString messageName,
                        [optional] in jsval obj,
-                       [optional] in jsval objects);
+                       [optional] in jsval objects,
+                       [optional] in nsIPrincipal principal);
 };
 
 [scriptable, builtinclass, uuid(894ff2d4-39a3-4df8-9d76-8ee329975488)]
 interface nsIContentFrameMessageManager : nsISyncMessageSender
 {
   /**
    * The current top level window in the frame or null.
    */
--- a/content/base/src/nsFrameLoader.cpp
+++ b/content/base/src/nsFrameLoader.cpp
@@ -2210,18 +2210,20 @@ nsFrameLoader::DoLoadFrameScript(const n
 
 class nsAsyncMessageToChild : public nsRunnable
 {
 public:
   nsAsyncMessageToChild(JSContext* aCx,
                         nsFrameLoader* aFrameLoader,
                         const nsAString& aMessage,
                         const StructuredCloneData& aData,
-                        JS::Handle<JSObject *> aCpows)
-    : mRuntime(js::GetRuntime(aCx)), mFrameLoader(aFrameLoader), mMessage(aMessage), mCpows(aCpows)
+                        JS::Handle<JSObject *> aCpows,
+                        nsIPrincipal* aPrincipal)
+    : mRuntime(js::GetRuntime(aCx)), mFrameLoader(aFrameLoader)
+    , mMessage(aMessage), mCpows(aCpows), mPrincipal(aPrincipal)
   {
     if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
       NS_RUNTIMEABORT("OOM");
     }
     if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
       NS_RUNTIMEABORT("OOM");
     }
     mClosure = aData.mClosure;
@@ -2244,50 +2246,55 @@ public:
       data.mData = mData.data();
       data.mDataLength = mData.nbytes();
       data.mClosure = mClosure;
 
       SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
 
       nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
       mm->ReceiveMessage(static_cast<EventTarget*>(tabChild), mMessage,
-                         false, &data, &cpows, nullptr);
+                         false, &data, &cpows, mPrincipal, nullptr);
     }
     return NS_OK;
   }
   JSRuntime* mRuntime;
   nsRefPtr<nsFrameLoader> mFrameLoader;
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
   JSObject* mCpows;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 bool
 nsFrameLoader::DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows)
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal)
 {
   TabParent* tabParent = mRemoteBrowser;
   if (tabParent) {
     ClonedMessageData data;
     ContentParent* cp = tabParent->Manager();
     if (!BuildClonedMessageDataForParent(cp, aData, data)) {
       return false;
     }
     InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
     if (aCpows && !cp->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
-    return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows);
+    return tabParent->SendAsyncMessage(nsString(aMessage), data, cpows,
+                                       aPrincipal);
   }
 
   if (mChildMessageManager) {
-    nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage, aData, aCpows);
+    nsRefPtr<nsIRunnable> ev = new nsAsyncMessageToChild(aCx, this, aMessage,
+                                                         aData, aCpows,
+                                                         aPrincipal);
     NS_DispatchToCurrentThread(ev);
     return true;
   }
 
   // We don't have any targets to send our asynchronous message to.
   return false;
 }
 
--- a/content/base/src/nsFrameLoader.h
+++ b/content/base/src/nsFrameLoader.h
@@ -179,17 +179,18 @@ public:
 
   /**
    * MessageManagerCallback methods that we override.
    */
   virtual bool DoLoadFrameScript(const nsAString& aURL) MOZ_OVERRIDE;
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows);
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
   virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
   virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
   virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
 
   /**
    * Called from the layout frame associated with this frame loader;
    * this notifies us to hook up with the widget and view.
    */
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -495,38 +495,43 @@ GetParamsForMessage(JSContext* aCx,
 // nsISyncMessageSender
 
 static bool sSendingSyncMessage = false;
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendSyncMessage(const nsAString& aMessageName,
                                        const JS::Value& aJSON,
                                        const JS::Value& aObjects,
+                                       nsIPrincipal* aPrincipal,
                                        JSContext* aCx,
                                        uint8_t aArgc,
                                        JS::Value* aRetval)
 {
-  return SendMessage(aMessageName, aJSON, aObjects, aCx, aArgc, aRetval, true);
+  return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
+                     aRetval, true);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendRpcMessage(const nsAString& aMessageName,
                                       const JS::Value& aJSON,
                                       const JS::Value& aObjects,
+                                      nsIPrincipal* aPrincipal,
                                       JSContext* aCx,
                                       uint8_t aArgc,
                                       JS::Value* aRetval)
 {
-  return SendMessage(aMessageName, aJSON, aObjects, aCx, aArgc, aRetval, false);
+  return SendMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx, aArgc,
+                     aRetval, false);
 }
 
 nsresult
 nsFrameMessageManager::SendMessage(const nsAString& aMessageName,
                                    const JS::Value& aJSON,
                                    const JS::Value& aObjects,
+                                   nsIPrincipal* aPrincipal,
                                    JSContext* aCx,
                                    uint8_t aArgc,
                                    JS::Value* aRetval,
                                    bool aIsSync)
 {
   NS_ASSERTION(!IsGlobal(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!IsWindowLevel(), "Should not call SendSyncMessage in chrome");
   NS_ASSERTION(!mParentManager, "Should not have parent manager in content!");
@@ -551,17 +556,18 @@ nsFrameMessageManager::SendMessage(const
   JS::RootedObject objects(aCx);
   if (aArgc >= 3 && aObjects.isObject()) {
     objects = &aObjects.toObject();
   }
 
   InfallibleTArray<nsString> retval;
 
   sSendingSyncMessage |= aIsSync;
-  bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects, &retval, aIsSync);
+  bool rv = mCallback->DoSendBlockingMessage(aCx, aMessageName, data, objects,
+                                             aPrincipal, &retval, aIsSync);
   if (aIsSync) {
     sSendingSyncMessage = false;
   }
 
   if (!rv) {
     return NS_OK;
   }
 
@@ -586,38 +592,40 @@ nsFrameMessageManager::SendMessage(const
   *aRetval = OBJECT_TO_JSVAL(dataArray);
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
                                                     const nsAString& aMessage,
                                                     const StructuredCloneData& aData,
-                                                    JS::Handle<JSObject *> aCpows)
+                                                    JS::Handle<JSObject *> aCpows,
+                                                    nsIPrincipal* aPrincipal)
 {
   if (mIsBroadcaster) {
     int32_t len = mChildManagers.Count();
     for (int32_t i = 0; i < len; ++i) {
       static_cast<nsFrameMessageManager*>(mChildManagers[i])->
-         DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows);
+         DispatchAsyncMessageInternal(aCx, aMessage, aData, aCpows, aPrincipal);
     }
     return NS_OK;
   }
 
   NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
-  if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows)) {
+  if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal)) {
     return NS_ERROR_FAILURE;
   }
   return NS_OK;
 }
 
 nsresult
 nsFrameMessageManager::DispatchAsyncMessage(const nsAString& aMessageName,
                                             const JS::Value& aJSON,
                                             const JS::Value& aObjects,
+                                            nsIPrincipal* aPrincipal,
                                             JSContext* aCx,
                                             uint8_t aArgc)
 {
   StructuredCloneData data;
   JSAutoStructuredCloneBuffer buffer;
 
   if (aArgc >= 2 &&
       !GetParamsForMessage(aCx, aJSON, buffer, data.mClosure)) {
@@ -627,43 +635,47 @@ nsFrameMessageManager::DispatchAsyncMess
   JS::RootedObject objects(aCx);
   if (aArgc >= 3 && aObjects.isObject()) {
     objects = &aObjects.toObject();
   }
 
   data.mData = buffer.data();
   data.mDataLength = buffer.nbytes();
 
-  return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects);
+  return DispatchAsyncMessageInternal(aCx, aMessageName, data, objects,
+                                      aPrincipal);
 }
 
 
 // nsIMessageSender
 
 NS_IMETHODIMP
 nsFrameMessageManager::SendAsyncMessage(const nsAString& aMessageName,
                                         const JS::Value& aJSON,
                                         const JS::Value& aObjects,
+                                        nsIPrincipal* aPrincipal,
                                         JSContext* aCx,
                                         uint8_t aArgc)
 {
-  return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
+  return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aPrincipal, aCx,
+                              aArgc);
 }
 
 
 // nsIMessageBroadcaster
 
 NS_IMETHODIMP
 nsFrameMessageManager::BroadcastAsyncMessage(const nsAString& aMessageName,
                                              const JS::Value& aJSON,
                                              const JS::Value& aObjects,
                                              JSContext* aCx,
                                              uint8_t aArgc)
 {
-  return DispatchAsyncMessage(aMessageName, aJSON, aObjects, aCx, aArgc);
+  return DispatchAsyncMessage(aMessageName, aJSON, aObjects, nullptr, aCx,
+                              aArgc);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::GetChildCount(uint32_t* aChildCount)
 {
   *aChildCount = static_cast<uint32_t>(mChildManagers.Count()); 
   return NS_OK;
 }
@@ -836,16 +848,17 @@ public:
 // nsIMessageListener
 
 nsresult
 nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
                                       const nsAString& aMessage,
                                       bool aIsSync,
                                       const StructuredCloneData* aCloneData,
                                       CpowHolder* aCpows,
+                                      nsIPrincipal* aPrincipal,
                                       InfallibleTArray<nsString>* aJSONRetVal)
 {
   AutoSafeJSContext ctx;
   nsAutoTObserverArray<nsMessageListenerInfo, 1>* listeners =
     mListeners.Get(aMessage);
   if (listeners) {
 
     MMListenerRemover lr(this);
@@ -921,16 +934,52 @@ nsFrameMessageManager::ReceiveMessage(ns
       JS_DefineProperty(ctx, param, "name",
                         STRING_TO_JSVAL(jsMessage), nullptr, nullptr, JSPROP_ENUMERATE);
       JS_DefineProperty(ctx, param, "sync",
                         BOOLEAN_TO_JSVAL(aIsSync), nullptr, nullptr, JSPROP_ENUMERATE);
       JS_DefineProperty(ctx, param, "json", json, nullptr, nullptr, JSPROP_ENUMERATE); // deprecated
       JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
       JS_DefineProperty(ctx, param, "objects", cpowsv, nullptr, nullptr, JSPROP_ENUMERATE);
 
+      // message.principal == null
+      if (!aPrincipal) {
+        JS::Rooted<JS::Value> nullValue(ctx);
+        JS_DefineProperty(ctx, param, "principal", nullValue, nullptr, nullptr, JSPROP_ENUMERATE);
+      }
+
+      // message.principal = { appId: <id>, origin: <origin>, isInBrowserElement: <something> }
+      else {
+        JS::Rooted<JSObject*> principalObj(ctx,
+          JS_NewObject(ctx, nullptr, nullptr, nullptr));
+
+        uint32_t appId;
+        nsresult rv = aPrincipal->GetAppId(&appId);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        JS::Rooted<JS::Value> appIdValue(ctx, INT_TO_JSVAL(appId));
+        JS_DefineProperty(ctx, principalObj, "appId", appIdValue, nullptr, nullptr, JSPROP_ENUMERATE);
+
+        nsCString origin;
+        rv = aPrincipal->GetOrigin(getter_Copies(origin));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        JS::Rooted<JSString*> originValue(ctx, JS_InternString(ctx, origin.get()));
+        JS_DefineProperty(ctx, principalObj, "origin", STRING_TO_JSVAL(originValue), nullptr, nullptr, JSPROP_ENUMERATE);
+
+        bool browser;
+        rv = aPrincipal->GetIsInBrowserElement(&browser);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        JS::Rooted<JS::Value> browserValue(ctx, BOOLEAN_TO_JSVAL(browser));
+        JS_DefineProperty(ctx, principalObj, "isInBrowserElement", browserValue, nullptr, nullptr, JSPROP_ENUMERATE);
+
+        JS::RootedValue principalValue(ctx, JS::ObjectValue(*principalObj));
+        JS_DefineProperty(ctx, param, "principal", principalValue, nullptr, nullptr, JSPROP_ENUMERATE);
+      }
+
       JS::Rooted<JS::Value> thisValue(ctx, JS::UndefinedValue());
 
       JS::Rooted<JS::Value> funval(ctx);
       if (JS_ObjectIsCallable(ctx, object)) {
         // If the listener is a JS function:
         funval.setObject(*object);
 
         // A small hack to get 'this' value right on content side where
@@ -976,17 +1025,17 @@ nsFrameMessageManager::ReceiveMessage(ns
           }
         }
       }
     }
   }
   nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
   return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
                                                          aIsSync, aCloneData,
-                                                         aCpows,
+                                                         aCpows, aPrincipal,
                                                          aJSONRetVal) : NS_OK;
 }
 
 void
 nsFrameMessageManager::AddChildManager(nsFrameMessageManager* aManager,
                                        bool aLoadScripts)
 {
   mChildManagers.AppendObject(aManager);
@@ -1447,20 +1496,22 @@ nsFrameMessageManager* nsFrameMessageMan
 nsTArray<nsCOMPtr<nsIRunnable> >* nsFrameMessageManager::sPendingSameProcessAsyncMessages = nullptr;
 
 class nsAsyncMessageToSameProcessChild : public nsRunnable
 {
 public:
   nsAsyncMessageToSameProcessChild(JSContext* aCx,
                                    const nsAString& aMessage,
                                    const StructuredCloneData& aData,
-                                   JS::Handle<JSObject *> aCpows)
+                                   JS::Handle<JSObject *> aCpows,
+                                   nsIPrincipal* aPrincipal)
     : mRuntime(js::GetRuntime(aCx)),
       mMessage(aMessage),
-      mCpows(aCpows)
+      mCpows(aCpows),
+      mPrincipal(aPrincipal)
   {
     if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
       NS_RUNTIMEABORT("OOM");
     }
     if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
       NS_RUNTIMEABORT("OOM");
     }
     mClosure = aData.mClosure;
@@ -1480,25 +1531,26 @@ public:
       data.mData = mData.data();
       data.mDataLength = mData.nbytes();
       data.mClosure = mClosure;
 
       SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
 
       nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sChildProcessManager;
       ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), mMessage,
-                          false, &data, &cpows, nullptr);
+                          false, &data, &cpows, mPrincipal, nullptr);
     }
     return NS_OK;
   }
   JSRuntime* mRuntime;
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
   JSObject* mCpows;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 
 /**
  * Send messages to an imaginary child process in a single-process scenario.
  */
 class SameParentProcessMessageManagerCallback : public MessageManagerCallback
 {
@@ -1510,20 +1562,22 @@ public:
   virtual ~SameParentProcessMessageManagerCallback()
   {
     MOZ_COUNT_DTOR(SameParentProcessMessageManagerCallback);
   }
 
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows)
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal)
   {
     nsRefPtr<nsIRunnable> ev =
-      new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows);
+      new nsAsyncMessageToSameProcessChild(aCx, aMessage, aData, aCpows,
+                                           aPrincipal);
     NS_DispatchToCurrentThread(ev);
     return true;
   }
 
   bool CheckPermission(const nsAString& aPermission)
   {
     // In a single-process scenario, the child always has all capabilities.
     return true;
@@ -1557,16 +1611,17 @@ public:
   {
     MOZ_COUNT_DTOR(ChildProcessMessageManagerCallback);
   }
 
   virtual bool DoSendBlockingMessage(JSContext* aCx,
                                      const nsAString& aMessage,
                                      const mozilla::dom::StructuredCloneData& aData,
                                      JS::Handle<JSObject *> aCpows,
+                                     nsIPrincipal* aPrincipal,
                                      InfallibleTArray<nsString>* aJSONRetVal,
                                      bool aIsSync) MOZ_OVERRIDE
   {
     mozilla::dom::ContentChild* cc =
       mozilla::dom::ContentChild::GetSingleton();
     if (!cc) {
       return true;
     }
@@ -1574,55 +1629,60 @@ public:
     if (!BuildClonedMessageDataForChild(cc, aData, data)) {
       return false;
     }
     InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
     if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
     if (aIsSync) {
-      return cc->SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
+      return cc->SendSyncMessage(nsString(aMessage), data, cpows, aPrincipal,
+                                 aJSONRetVal);
     }
-    return cc->CallRpcMessage(nsString(aMessage), data, cpows, aJSONRetVal);
+    return cc->CallRpcMessage(nsString(aMessage), data, cpows, aPrincipal,
+                              aJSONRetVal);
   }
 
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal) MOZ_OVERRIDE
   {
     mozilla::dom::ContentChild* cc =
       mozilla::dom::ContentChild::GetSingleton();
     if (!cc) {
       return true;
     }
     ClonedMessageData data;
     if (!BuildClonedMessageDataForChild(cc, aData, data)) {
       return false;
     }
     InfallibleTArray<mozilla::jsipc::CpowEntry> cpows;
     if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
-    return cc->SendAsyncMessage(nsString(aMessage), data, cpows);
+    return cc->SendAsyncMessage(nsString(aMessage), data, cpows, aPrincipal);
   }
 
 };
 
 
 class nsAsyncMessageToSameProcessParent : public nsRunnable
 {
 public:
   nsAsyncMessageToSameProcessParent(JSContext* aCx,
                                     const nsAString& aMessage,
                                     const StructuredCloneData& aData,
-                                    JS::Handle<JSObject *> aCpows)
+                                    JS::Handle<JSObject *> aCpows,
+                                    nsIPrincipal* aPrincipal)
     : mRuntime(js::GetRuntime(aCx)),
       mMessage(aMessage),
-      mCpows(aCpows)
+      mCpows(aCpows),
+      mPrincipal(aPrincipal)
   {
     if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
       NS_RUNTIMEABORT("OOM");
     }
     if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
       NS_RUNTIMEABORT("OOM");
     }
     mClosure = aData.mClosure;
@@ -1646,25 +1706,26 @@ public:
       data.mDataLength = mData.nbytes();
       data.mClosure = mClosure;
 
       SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
 
       nsRefPtr<nsFrameMessageManager> ppm =
         nsFrameMessageManager::sSameProcessParentManager;
       ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
-                          mMessage, false, &data, &cpows, nullptr);
+                          mMessage, false, &data, &cpows, mPrincipal, nullptr);
      }
      return NS_OK;
   }
   JSRuntime* mRuntime;
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
   JSObject* mCpows;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
 };
 
 /**
  * Send messages to the imaginary parent process in a single-process scenario.
  */
 class SameChildProcessMessageManagerCallback : public MessageManagerCallback
 {
 public:
@@ -1676,47 +1737,49 @@ public:
   {
     MOZ_COUNT_DTOR(SameChildProcessMessageManagerCallback);
   }
 
   virtual bool DoSendBlockingMessage(JSContext* aCx,
                                      const nsAString& aMessage,
                                      const mozilla::dom::StructuredCloneData& aData,
                                      JS::Handle<JSObject *> aCpows,
+                                     nsIPrincipal* aPrincipal,
                                      InfallibleTArray<nsString>* aJSONRetVal,
                                      bool aIsSync) MOZ_OVERRIDE
   {
     nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
     if (nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
       asyncMessages.SwapElements(*nsFrameMessageManager::sPendingSameProcessAsyncMessages);
       uint32_t len = asyncMessages.Length();
       for (uint32_t i = 0; i < len; ++i) {
         nsCOMPtr<nsIRunnable> async = asyncMessages[i];
         async->Run();
       }
     }
     if (nsFrameMessageManager::sSameProcessParentManager) {
       SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
       nsRefPtr<nsFrameMessageManager> ppm = nsFrameMessageManager::sSameProcessParentManager;
       ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), aMessage,
-                          true, &aData, &cpows, aJSONRetVal);
+                          true, &aData, &cpows, aPrincipal, aJSONRetVal);
     }
     return true;
   }
 
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows)
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal)
   {
     if (!nsFrameMessageManager::sPendingSameProcessAsyncMessages) {
       nsFrameMessageManager::sPendingSameProcessAsyncMessages = new nsTArray<nsCOMPtr<nsIRunnable> >;
     }
     nsCOMPtr<nsIRunnable> ev =
-      new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows);
+      new nsAsyncMessageToSameProcessParent(aCx, aMessage, aData, aCpows, aPrincipal);
     nsFrameMessageManager::sPendingSameProcessAsyncMessages->AppendElement(ev);
     NS_DispatchToCurrentThread(ev);
     return true;
   }
 
 };
 
 
--- a/content/base/src/nsFrameMessageManager.h
+++ b/content/base/src/nsFrameMessageManager.h
@@ -56,26 +56,28 @@ public:
   {
     return true;
   }
 
   virtual bool DoSendBlockingMessage(JSContext* aCx,
                                      const nsAString& aMessage,
                                      const mozilla::dom::StructuredCloneData& aData,
                                      JS::Handle<JSObject *> aCpows,
+                                     nsIPrincipal* aPrincipal,
                                      InfallibleTArray<nsString>* aJSONRetVal,
                                      bool aIsSync)
   {
     return true;
   }
 
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows)
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal)
   {
     return true;
   }
 
   virtual bool CheckPermission(const nsAString& aPermission)
   {
     return false;
   }
@@ -213,17 +215,17 @@ public:
   NS_DECL_NSIFRAMESCRIPTLOADER
   NS_DECL_NSIPROCESSCHECKER
 
   static nsFrameMessageManager*
   NewProcessMessageManager(mozilla::dom::ContentParent* aProcess);
 
   nsresult ReceiveMessage(nsISupports* aTarget, const nsAString& aMessage,
                           bool aIsSync, const StructuredCloneData* aCloneData,
-                          CpowHolder* aCpows,
+                          CpowHolder* aCpows, nsIPrincipal* aPrincipal,
                           InfallibleTArray<nsString>* aJSONRetVal);
 
   void AddChildManager(nsFrameMessageManager* aManager,
                        bool aLoadScripts = true);
   void RemoveChildManager(nsFrameMessageManager* aManager)
   {
     mChildManagers.RemoveObject(aManager);
   }
@@ -234,22 +236,24 @@ public:
   mozilla::dom::ipc::MessageManagerCallback* GetCallback()
   {
     return mCallback;
   }
 
   nsresult DispatchAsyncMessage(const nsAString& aMessageName,
                                 const JS::Value& aJSON,
                                 const JS::Value& aObjects,
+                                nsIPrincipal* aPrincipal,
                                 JSContext* aCx,
                                 uint8_t aArgc);
   nsresult DispatchAsyncMessageInternal(JSContext* aCx,
                                         const nsAString& aMessage,
                                         const StructuredCloneData& aData,
-                                        JS::Handle<JSObject *> aCpows);
+                                        JS::Handle<JSObject *> aCpows,
+                                        nsIPrincipal* aPrincipal);
   void RemoveFromParent();
   nsFrameMessageManager* GetParentManager() { return mParentManager; }
   void SetParentManager(nsFrameMessageManager* aParent)
   {
     NS_ASSERTION(!mParentManager, "We have parent manager already!");
     NS_ASSERTION(mChrome, "Should not set parent manager!");
     mParentManager = aParent;
   }
@@ -263,16 +267,17 @@ public:
   static nsFrameMessageManager* GetChildProcessManager()
   {
     return sChildProcessManager;
   }
 private:
   nsresult SendMessage(const nsAString& aMessageName,
                        const JS::Value& aJSON,
                        const JS::Value& aObjects,
+                       nsIPrincipal* aPrincipal,
                        JSContext* aCx,
                        uint8_t aArgc,
                        JS::Value* aRetval,
                        bool aIsSync);
 protected:
   friend class MMListenerRemover;
   // We keep the message listeners as arrays in a hastable indexed by the
   // message name. That gives us fast lookups in ReceiveMessage().
--- a/content/base/src/nsInProcessTabChildGlobal.cpp
+++ b/content/base/src/nsInProcessTabChildGlobal.cpp
@@ -25,46 +25,50 @@
 using mozilla::dom::StructuredCloneData;
 using mozilla::dom::StructuredCloneClosure;
 
 bool
 nsInProcessTabChildGlobal::DoSendBlockingMessage(JSContext* aCx,
                                                  const nsAString& aMessage,
                                                  const mozilla::dom::StructuredCloneData& aData,
                                                  JS::Handle<JSObject *> aCpows,
+                                                 nsIPrincipal* aPrincipal,
                                                  InfallibleTArray<nsString>* aJSONRetVal,
                                                  bool aIsSync)
 {
   nsTArray<nsCOMPtr<nsIRunnable> > asyncMessages;
   asyncMessages.SwapElements(mASyncMessages);
   uint32_t len = asyncMessages.Length();
   for (uint32_t i = 0; i < len; ++i) {
     nsCOMPtr<nsIRunnable> async = asyncMessages[i];
     async->Run();
   }
   if (mChromeMessageManager) {
     SameProcessCpowHolder cpows(js::GetRuntime(aCx), aCpows);
     nsRefPtr<nsFrameMessageManager> mm = mChromeMessageManager;
-    mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aJSONRetVal);
+    mm->ReceiveMessage(mOwner, aMessage, true, &aData, &cpows, aPrincipal,
+                       aJSONRetVal);
   }
   return true;
 }
 
 class nsAsyncMessageToParent : public nsRunnable
 {
 public:
   nsAsyncMessageToParent(JSContext* aCx,
                          nsInProcessTabChildGlobal* aTabChild,
                          const nsAString& aMessage,
                          const StructuredCloneData& aData,
-                         JS::Handle<JSObject *> aCpows)
+                         JS::Handle<JSObject *> aCpows,
+                         nsIPrincipal* aPrincipal)
     : mRuntime(js::GetRuntime(aCx)),
       mTabChild(aTabChild),
       mMessage(aMessage),
       mCpows(aCpows),
+      mPrincipal(aPrincipal),
       mRun(false)
   {
     if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
       NS_RUNTIMEABORT("OOM");
     }
     if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
       NS_RUNTIMEABORT("OOM");
     }
@@ -90,39 +94,42 @@ public:
       StructuredCloneData data;
       data.mData = mData.data();
       data.mDataLength = mData.nbytes();
       data.mClosure = mClosure;
 
       SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject *>::fromMarkedLocation(&mCpows));
 
       nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
-      mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data, &cpows, nullptr);
+      mm->ReceiveMessage(mTabChild->mOwner, mMessage, false, &data, &cpows,
+                         mPrincipal, nullptr);
     }
     return NS_OK;
   }
   JSRuntime* mRuntime;
   nsRefPtr<nsInProcessTabChildGlobal> mTabChild;
   nsString mMessage;
   JSAutoStructuredCloneBuffer mData;
   StructuredCloneClosure mClosure;
   JSObject* mCpows;
+  nsCOMPtr<nsIPrincipal> mPrincipal;
   // True if this runnable has already been called. This can happen if DoSendSyncMessage
   // is called while waiting for an asynchronous message send.
   bool mRun;
 };
 
 bool
 nsInProcessTabChildGlobal::DoSendAsyncMessage(JSContext* aCx,
                                               const nsAString& aMessage,
                                               const StructuredCloneData& aData,
-                                              JS::Handle<JSObject *> aCpows)
+                                              JS::Handle<JSObject *> aCpows,
+                                              nsIPrincipal* aPrincipal)
 {
   nsCOMPtr<nsIRunnable> ev =
-    new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows);
+    new nsAsyncMessageToParent(aCx, this, aMessage, aData, aCpows, aPrincipal);
   mASyncMessages.AppendElement(ev);
   NS_DispatchToCurrentThread(ev);
   return true;
 }
 
 nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
                                                      nsIContent* aOwner,
                                                      nsFrameMessageManager* aChrome)
--- a/content/base/src/nsInProcessTabChildGlobal.h
+++ b/content/base/src/nsInProcessTabChildGlobal.h
@@ -38,33 +38,37 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
                                            nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              const JS::Value& aObject,
                              const JS::Value& aRemote,
+                             nsIPrincipal* aPrincipal,
                              JSContext* aCx,
                              uint8_t aArgc,
                              JS::Value* aRetval)
   {
     return mMessageManager
-      ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
+      ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
+                                         aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
                             const JS::Value& aObject,
                             const JS::Value& aRemote,
+                            nsIPrincipal* aPrincipal,
                             JSContext* aCx,
                             uint8_t aArgc,
                             JS::Value* aRetval)
   {
     return mMessageManager
-      ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
+      ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
+                                        aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
   NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
   NS_IMETHOD Dump(const nsAString& aStr) MOZ_OVERRIDE
   {
     return mMessageManager ? mMessageManager->Dump(aStr) : NS_OK;
   }
@@ -78,22 +82,24 @@ public:
 
   /**
    * MessageManagerCallback methods that we override.
    */
   virtual bool DoSendBlockingMessage(JSContext* aCx,
                                       const nsAString& aMessage,
                                       const mozilla::dom::StructuredCloneData& aData,
                                       JS::Handle<JSObject *> aCpows,
+                                      nsIPrincipal* aPrincipal,
                                       InfallibleTArray<nsString>* aJSONRetVal,
                                       bool aIsSync) MOZ_OVERRIDE;
   virtual bool DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows);
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
 
   virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
   NS_IMETHOD AddEventListener(const nsAString& aType,
                               nsIDOMEventListener* aListener,
                               bool aUseCapture)
   {
     // By default add listeners only for trusted events!
     return nsDOMEventTargetHelper::AddEventListener(aType, aListener,
--- a/content/base/test/chrome.ini
+++ b/content/base/test/chrome.ini
@@ -1,4 +1,5 @@
 [DEFAULT]
 
 [test_bug357450.js]
 [test_copypaste.xul]
+[test_messagemanager_principal.html]
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_messagemanager_principal.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for Principal in MessageManager</title>
+  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+</head>
+<body>
+
+  <script type="application/javascript;version=1.7">
+    "use strict";
+
+    const Ci = Components.interfaces;
+    const Cc = Components.classes;
+    const Cu = Components.utils;
+
+    var permManager = Cc["@mozilla.org/permissionmanager;1"]
+                        .getService(Ci.nsIPermissionManager);
+
+    SimpleTest.waitForExplicitFinish();
+
+    const childFrameURL =
+      "data:text/html,<!DOCTYPE HTML><html><body></body></html>";
+
+    function childFrameScript() {
+      "use strict";
+
+      addMessageListener("test:ipcMessage", function(message) {
+        sendAsyncMessage(message.name, "principal: " + (message.principal ? "OK" : "KO"));
+
+        sendAsyncMessage(message.name, "principal.appId: " +
+                         ("appId" in message.principal ? "OK" : "KO"));
+
+        sendAsyncMessage(message.name, "principal.origin: " +
+                         ("origin" in message.principal ? "OK" : "KO"));
+
+        sendAsyncMessage(message.name, "principal.isInBrowserElement: " +
+                         ("isInBrowserElement" in message.principal ? "OK" : "KO"));
+
+        sendAsyncMessage(message.name, "DONE");
+      });
+    }
+
+    function runTests() {
+      ok("Browser prefs set.");
+
+      let iframe = document.createElement("iframe");
+      SpecialPowers.wrap(iframe).mozbrowser = true;
+      iframe.id = "iframe";
+      iframe.src = childFrameURL;
+
+      iframe.addEventListener("mozbrowserloadend", function() {
+        ok(true, "Got iframe load event.");
+
+        let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
+        mm.addMessageListener("test:ipcMessage", function(message) {
+          // We need to wrap to access message.json, and unwrap to do the
+          // identity check.
+          var msg = SpecialPowers.unwrap(SpecialPowers.wrap(message).json);
+          if (/OK$/.exec(msg)) {
+            ok(true, msg);
+          } else if(/KO$/.exec(msg)) {
+            ok(true, false);
+          } else if (/DONE/.exec(msg)) {
+            permManager.removeFromPrincipal(window.document.nodePrincipal, "browser",
+                                            Ci.nsIPermissionManager.ALLOW_ACTION);
+            SimpleTest.finish();
+          }
+        });
+        mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
+                           false);
+
+        mm.sendAsyncMessage("test:ipcMessage", 42, null, window.document.nodePrincipal);
+      });
+
+      document.body.appendChild(iframe);
+    }
+
+    addEventListener("load", function() {
+      info("Got load event.");
+
+      permManager.addFromPrincipal(window.document.nodePrincipal, "browser",
+                                   Ci.nsIPermissionManager.ALLOW_ACTION);
+
+      SpecialPowers.pushPrefEnv({
+        "set": [
+          ["dom.mozBrowserFramesEnabled", true],
+          ["browser.pagethumbnails.capturing_disabled", true]
+        ]
+      }, runTests);
+    });
+  </script>
+</body>
+</html>
--- a/content/html/content/src/HTMLOptionElement.cpp
+++ b/content/html/content/src/HTMLOptionElement.cpp
@@ -206,34 +206,37 @@ HTMLOptionElement::BeforeSetAttr(int32_t
   // true it doesn't matter what value mIsSelected has.
   NS_ASSERTION(!mSelectedChanged, "Shouldn't be here");
 
   bool inSetDefaultSelected = mIsInSetDefaultSelected;
   mIsInSetDefaultSelected = true;
 
   int32_t index = Index();
   uint32_t mask = HTMLSelectElement::SET_DISABLED;
-  if (aValue) {
+  bool defaultSelected = aValue;
+  if (defaultSelected) {
     mask |= HTMLSelectElement::IS_SELECTED;
   }
 
   if (aNotify) {
     mask |= HTMLSelectElement::NOTIFY;
   }
 
   // This should end up calling SetSelectedInternal, which we will allow to
   // take effect so that parts of SetOptionsSelectedByIndex that might depend
   // on it working don't get confused.
   selectInt->SetOptionsSelectedByIndex(index, index, mask);
 
   // Now reset our members; when we finish the attr set we'll end up with the
   // rigt selected state.
   mIsInSetDefaultSelected = inSetDefaultSelected;
-  mSelectedChanged = false;
-  // mIsSelected doesn't matter while mSelectedChanged is false
+  // mIsSelected has already been set by SetOptionsSelectedByIndex.
+  // Possibly more than once; make sure our mSelectedChanged state is
+  // set correctly.
+  mSelectedChanged = mIsSelected != defaultSelected;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLOptionElement::GetText(nsAString& aText)
 {
   nsAutoString text;
--- a/content/html/content/test/mochitest.ini
+++ b/content/html/content/test/mochitest.ini
@@ -397,16 +397,17 @@ support-files =
 [test_meta_attributes_reflection.html]
 [test_mod_attributes_reflection.html]
 [test_mozaudiochannel.html]
 [test_named_options.html]
 [test_nested_invalid_fieldsets.html]
 [test_object_attributes_reflection.html]
 [test_object_plugin_nav.html]
 [test_ol_attributes_reflection.html]
+[test_option_defaultSelected.html]
 [test_param_attributes_reflection.html]
 [test_q_attributes_reflection.html]
 [test_restore_from_parser_fragment.html]
 [test_rowscollection.html]
 [test_srcdoc-2.html]
 [test_srcdoc.html]
 [test_style_attributes_reflection.html]
 [test_track.html]
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_option_defaultSelected.html
@@ -0,0 +1,47 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=927796
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 927796</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=927796">Mozilla Bug 927796</a>
+<p id="display">
+<select id="s1">
+  <option selected>one</option>
+  <option>two</option>
+</select>
+<select id="s2" size="5">
+  <option selected>one</option>
+  <option>two</option>
+</select>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+</pre>
+  <script type="application/javascript">
+
+  /** Test for Bug 927796 **/
+  var s1 = $("s1");
+  s1.options[0].defaultSelected = false;
+  is(s1.options[0].selected, true,
+     "First option in combobox should still be selected");
+  is(s1.options[1].selected, false,
+     "Second option in combobox should not be selected");
+
+  var s2 = $("s2");
+  s2.options[0].defaultSelected = false;
+  is(s2.options[0].selected, false,
+     "First option in listbox should not be selected");
+  is(s2.options[1].selected, false,
+     "Second option in listbox should not be selected");
+  </script>
+</body>
+</html>
--- a/content/media/BufferMediaResource.h
+++ b/content/media/BufferMediaResource.h
@@ -124,24 +124,16 @@ public:
     return NS_OK;
   }
 
   virtual nsresult Open(nsIStreamListener** aStreamListener)
   {
     return NS_ERROR_FAILURE;
   }
 
-#ifdef MOZ_DASH
-  virtual nsresult OpenByteRange(nsIStreamListener** aStreamListener,
-                                 MediaByteRange const &aByteRange)
-  {
-    return NS_ERROR_FAILURE;
-  }
-#endif
-
   virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges)
   {
     aRanges.AppendElement(MediaByteRange(0, mLength));
     return NS_OK;
   }
 
   bool IsTransportSeekable() MOZ_OVERRIDE { return true; }
 
--- a/content/media/DecoderTraits.cpp
+++ b/content/media/DecoderTraits.cpp
@@ -44,19 +44,16 @@
 #include "MediaOmxReader.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #endif
 #ifdef MOZ_RTSP
 #include "RtspOmxDecoder.h"
 #include "RtspOmxReader.h"
 #endif
-#ifdef MOZ_DASH
-#include "DASHDecoder.h"
-#endif
 #ifdef MOZ_WMF
 #include "WMFDecoder.h"
 #include "WMFReader.h"
 #endif
 #ifdef MOZ_DIRECTSHOW
 #include "DirectShowDecoder.h"
 #include "DirectShowReader.h"
 #endif
@@ -280,34 +277,16 @@ IsMediaPluginsType(const nsACString& aTy
 
   static const char* supportedTypes[] = {
     "audio/mpeg", "audio/mp4", "video/mp4", nullptr
   };
   return CodecListContains(supportedTypes, aType);
 }
 #endif
 
-#ifdef MOZ_DASH
-/* static */
-static const char* const gDASHMPDTypes[2] = {
-  "application/dash+xml",
-  nullptr
-};
-
-static bool
-IsDASHMPDType(const nsACString& aType)
-{
-  if (!MediaDecoder::IsDASHEnabled()) {
-    return false;
-  }
-
-  return CodecListContains(gDASHMPDTypes, aType);
-}
-#endif
-
 #ifdef MOZ_WMF
 static bool
 IsWMFSupportedType(const nsACString& aType)
 {
   return WMFDecoder::GetSupportedCodecs(aType, nullptr);
 }
 #endif
 
@@ -394,23 +373,16 @@ DecoderTraits::CanHandleMediaType(const 
   }
 #endif
 #ifdef MOZ_WEBM
   if (IsWebMType(nsDependentCString(aMIMEType))) {
     codecList = gWebMCodecs;
     result = CANPLAY_YES;
   }
 #endif
-#ifdef MOZ_DASH
-  if (IsDASHMPDType(nsDependentCString(aMIMEType))) {
-    // DASH manifest uses WebM codecs only.
-    codecList = gWebMCodecs;
-    result = CANPLAY_YES;
-  }
-#endif
 #ifdef MOZ_GSTREAMER
   if (GStreamerDecoder::CanHandleMediaType(nsDependentCString(aMIMEType),
                                            aHaveRequestedCodecs ? &aRequestedCodecs : nullptr)) {
     if (aHaveRequestedCodecs)
       return CANPLAY_YES;
     return CANPLAY_MAYBE;
   }
 #endif
@@ -525,21 +497,16 @@ DecoderTraits::CreateDecoder(const nsACS
     decoder = new MediaPluginDecoder(aType);
   }
 #endif
 #ifdef MOZ_WEBM
   if (IsWebMType(aType)) {
     decoder = new WebMDecoder();
   }
 #endif
-#ifdef MOZ_DASH
-  if (IsDASHMPDType(aType)) {
-    decoder = new DASHDecoder();
-  }
-#endif
 #ifdef MOZ_DIRECTSHOW
   // Note: DirectShow decoder must come before WMFDecoder, else the pref
   // "media.directshow.preferred" won't be honored.
   if (IsDirectShowSupportedType(aType)) {
     decoder = new DirectShowDecoder();
   }
 #endif
 #ifdef MOZ_WMF
@@ -612,19 +579,16 @@ MediaDecoderReader* DecoderTraits::Creat
     decoderReader = new WMFReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_APPLEMEDIA
   if (IsAppleMediaSupportedType(aType)) {
     decoderReader = new AppleMP3Reader(aDecoder);
   } else
 #endif
-#ifdef MOZ_DASH
-  // The DASH decoder is not supported.
-#endif
   if (false) {} // dummy if to take care of the dangling else
 
   return decoderReader;
 }
 
 /* static */
 bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
 {
@@ -635,19 +599,16 @@ bool DecoderTraits::IsSupportedInVideoDo
 #ifdef MOZ_OMX_DECODER
     // We support amr inside WebApps on firefoxOS but not in general web content.
     // Ensure we dont create a VideoDocument when accessing amr URLs directly.
     (IsOmxSupportedType(aType) && !aType.EqualsASCII("audio/amr")) ||
 #endif
 #ifdef MOZ_WEBM
     IsWebMType(aType) ||
 #endif
-#ifdef MOZ_DASH
-    IsDASHMPDType(aType) ||
-#endif
 #ifdef MOZ_GSTREAMER
     IsGStreamerSupportedType(aType) ||
 #endif
 #ifdef MOZ_MEDIA_PLUGINS
     (MediaDecoder::IsMediaPluginsEnabled() && IsMediaPluginsType(aType)) ||
 #endif
 #ifdef MOZ_WMF
     (IsWMFSupportedType(aType) &&
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -1734,24 +1734,16 @@ MediaDecoder::IsOmxEnabled()
 #ifdef MOZ_MEDIA_PLUGINS
 bool
 MediaDecoder::IsMediaPluginsEnabled()
 {
   return Preferences::GetBool("media.plugins.enabled");
 }
 #endif
 
-#ifdef MOZ_DASH
-bool
-MediaDecoder::IsDASHEnabled()
-{
-  return Preferences::GetBool("media.dash.enabled");
-}
-#endif
-
 #ifdef MOZ_WMF
 bool
 MediaDecoder::IsWMFEnabled()
 {
   return WMFDecoder::IsEnabled();
 }
 #endif
 
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -782,20 +782,16 @@ public:
 #ifdef MOZ_OMX_DECODER
   static bool IsOmxEnabled();
 #endif
 
 #ifdef MOZ_MEDIA_PLUGINS
   static bool IsMediaPluginsEnabled();
 #endif
 
-#ifdef MOZ_DASH
-  static bool IsDASHEnabled();
-#endif
-
 #ifdef MOZ_WMF
   static bool IsWMFEnabled();
 #endif
 
 #ifdef MOZ_APPLEMEDIA
   static bool IsAppleMP3Enabled();
 #endif
 
--- a/content/media/MediaDecoderReader.h
+++ b/content/media/MediaDecoderReader.h
@@ -483,21 +483,16 @@ public:
   virtual nsresult ResetDecode();
 
   // Decodes an unspecified amount of audio data, enqueuing the audio data
   // in mAudioQueue. Returns true when there's more audio to decode,
   // false if the audio is finished, end of file has been reached,
   // or an un-recoverable read error has occured.
   virtual bool DecodeAudioData() = 0;
 
-#ifdef MOZ_DASH
-  // Steps to carry out at the start of the |DecodeLoop|.
-  virtual void PrepareToDecode() { }
-#endif
-
   // Reads and decodes one video frame. Packets with a timestamp less
   // than aTimeThreshold will be decoded (unless they're not keyframes
   // and aKeyframeSkip is true), but will not be added to the queue.
   virtual bool DecodeVideoFrame(bool &aKeyframeSkip,
                                 int64_t aTimeThreshold) = 0;
 
   virtual bool HasAudio() = 0;
   virtual bool HasVideo() = 0;
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -848,20 +848,16 @@ void MediaDecoderStateMachine::DecodeLoo
 
   // Main decode loop.
   bool videoPlaying = HasVideo();
   bool audioPlaying = HasAudio();
   while ((mState == DECODER_STATE_DECODING || mState == DECODER_STATE_BUFFERING) &&
          !mStopDecodeThread &&
          (videoPlaying || audioPlaying))
   {
-#ifdef MOZ_DASH
-    mReader->PrepareToDecode();
-#endif
-
     // We don't want to consider skipping to the next keyframe if we've
     // only just started up the decode loop, so wait until we've decoded
     // some frames before enabling the keyframe skip logic on video.
     if (videoPump &&
         (static_cast<uint32_t>(mReader->VideoQueue().GetSize())
          >= videoPumpThreshold * mPlaybackRate))
     {
       videoPump = false;
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -54,22 +54,16 @@ ChannelMediaResource::ChannelMediaResour
                                            const nsACString& aContentType)
   : BaseMediaResource(aDecoder, aChannel, aURI, aContentType),
     mOffset(0), mSuspendCount(0),
     mReopenOnError(false), mIgnoreClose(false),
     mCacheStream(MOZ_THIS_IN_INITIALIZER_LIST()),
     mLock("ChannelMediaResource.mLock"),
     mIgnoreResume(false),
     mSeekingForMetadata(false),
-#ifdef MOZ_DASH
-    mByteRangeDownloads(false),
-    mByteRangeFirstOpen(true),
-    mSeekOffsetMonitor("media.dashseekmonitor"),
-    mSeekOffset(-1),
-#endif
     mIsTransportSeekable(true)
 {
 #ifdef PR_LOGGING
   if (!gMediaResourceLog) {
     gMediaResourceLog = PR_NewLogModule("MediaResource");
   }
 #endif
 }
@@ -412,26 +406,16 @@ ChannelMediaResource::OnStopRequest(nsIR
   NS_ASSERTION(mSuspendCount == 0,
                "How can OnStopRequest fire while we're suspended?");
 
   {
     MutexAutoLock lock(mLock);
     mChannelStatistics->Stop();
   }
 
-#ifdef MOZ_DASH
-  // If we were loading a byte range, notify decoder and return.
-  // Skip this for unterminated byte range requests, e.g. seeking for whole
-  // file downloads.
-  if (mByteRangeDownloads) {
-    mDecoder->NotifyDownloadEnded(aStatus);
-    return NS_OK;
-  }
-#endif
-
   // Note that aStatus might have succeeded --- this might be a normal close
   // --- even in situations where the server cut us off because we were
   // suspended. So we need to "reopen on error" in that case too. The only
   // cases where we don't need to reopen are when *we* closed the stream.
   // But don't reopen if we need to seek and we don't think we can... that would
   // cause us to just re-read the stream, which would be really bad.
   if (mReopenOnError &&
       aStatus != NS_ERROR_PARSED_DATA_CACHED && aStatus != NS_BINDING_ABORTED &&
@@ -485,28 +469,16 @@ ChannelMediaResource::CopySegmentToCache
                                          uint32_t aToOffset,
                                          uint32_t aCount,
                                          uint32_t *aWriteCount)
 {
   CopySegmentClosure* closure = static_cast<CopySegmentClosure*>(aClosure);
 
   closure->mResource->mDecoder->NotifyDataArrived(aFromSegment, aCount, closure->mResource->mOffset);
 
-#ifdef MOZ_DASH
-  // For byte range downloads controlled by |DASHDecoder|, there are cases in
-  // which the reader's offset is different enough from the channel offset that
-  // |MediaCache| requests a |CacheClientSeek| to the reader's offset. This
-  // can happen between calls to |CopySegmentToCache|. To avoid copying at
-  // incorrect offsets, ensure |MediaCache| copies to the location that
-  // |ChannelMediaResource| expects.
-  if (closure->mResource->mByteRangeDownloads) {
-    closure->mResource->mCacheStream.NotifyDataStarted(closure->mResource->mOffset);
-  }
-#endif
-
   // Keep track of where we're up to.
   LOG("%p [ChannelMediaResource]: CopySegmentToCache at mOffset [%lld] add "
       "[%d] bytes for decoder[%p]",
       closure->mResource, closure->mResource->mOffset, aCount,
       closure->mResource->mDecoder);
   closure->mResource->mOffset += aCount;
 
   closure->mResource->mCacheStream.NotifyDataReceived(aCount, aFromSegment,
@@ -543,49 +515,16 @@ ChannelMediaResource::OnDataAvailable(ns
       return rv;
     NS_ASSERTION(read > 0, "Read 0 bytes while data was available?");
     count -= read;
   }
 
   return NS_OK;
 }
 
-#ifdef MOZ_DASH
-/* |OpenByteRange|
- * For terminated byte range requests, use this function.
- * Callback is |MediaDecoder|::|NotifyByteRangeDownloaded|().
- * See |CacheClientSeek| also.
- */
-
-nsresult
-ChannelMediaResource::OpenByteRange(nsIStreamListener** aStreamListener,
-                                    MediaByteRange const & aByteRange)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
-
-  mByteRangeDownloads = true;
-  mByteRange = aByteRange;
-
-  // OpenByteRange may be called multiple times; same URL, different ranges.
-  // For the first call using this URL, forward to Open for some init.
-  if (mByteRangeFirstOpen) {
-    mByteRangeFirstOpen = false;
-    return Open(aStreamListener);
-  }
-
-  // For subsequent calls, ensure channel is recreated with correct byte range.
-  CloseChannel();
-
-  nsresult rv = RecreateChannel();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return OpenChannel(aStreamListener);
-}
-#endif
-
 nsresult ChannelMediaResource::Open(nsIStreamListener **aStreamListener)
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
   if (!mChannelStatistics) {
     mChannelStatistics = new MediaChannelStatistics();
   }
 
@@ -827,23 +766,16 @@ nsresult ChannelMediaResource::ReadAt(in
 }
 
 nsresult ChannelMediaResource::Seek(int32_t aWhence, int64_t aOffset)
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
 
   CMLOG("Seek requested for aOffset [%lld] for decoder [%p]",
         aOffset, mDecoder);
-#ifdef MOZ_DASH
-  // Remember |aOffset|, because Media Cache may request a diff offset later.
-  if (mByteRangeDownloads) {
-    ReentrantMonitorAutoEnter mon(mSeekOffsetMonitor);
-    mSeekOffset = aOffset;
-  }
-#endif
   return mCacheStream.Seek(aWhence, aOffset);
 }
 
 void ChannelMediaResource::StartSeekingForMetadata()
 {
   mSeekingForMetadata = true;
 }
 
@@ -1040,118 +972,24 @@ ChannelMediaResource::CacheClientNotifyP
 nsresult
 ChannelMediaResource::CacheClientSeek(int64_t aOffset, bool aResume)
 {
   NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
 
   CMLOG("CacheClientSeek requested for aOffset [%lld] for decoder [%p]",
         aOffset, mDecoder);
 
-#ifndef MOZ_DASH
   CloseChannel();
-#else
-  // |CloseChannel| immediately for non-byte-range downloads.
-  if (!mByteRangeDownloads) {
-    CloseChannel();
-  } else if (mChannel) {
-    // Only close byte range channels if they are not in pending state.
-    bool isPending = false;
-    nsresult rv = mChannel->IsPending(&isPending);
-    NS_ENSURE_SUCCESS(rv, rv);
-    if (!isPending) {
-      CloseChannel();
-    }
-  }
-#endif
 
   if (aResume) {
     NS_ASSERTION(mSuspendCount > 0, "Too many resumes!");
     // No need to mess with the channel, since we're making a new one
     --mSuspendCount;
   }
 
-#ifdef MOZ_DASH  // Note: For chunked downloads, e.g. DASH, we need to determine which chunk
-  // contains the requested offset, |mOffset|. This is either previously
-  // requested in |Seek| or updated to the most recent bytes downloaded.
-  // So the process below is:
-  //   1 - Query decoder for chunk containing desired offset, |mOffset|.
-  //       Return silently if the offset is not available; suggests decoder is
-  //         yet to get range information.
-  //       Return with NetworkError for all other errors.
-  //
-  //   2 - Adjust |mByteRange|.mStart to |aOffset|, requested by media cache.
-  //       For seeking, the media cache always requests the start of the cache
-  //       block, so we need to adjust the first chunk of a seek.
-  //       E.g. For "DASH-WebM On Demand" this means the first chunk after
-  //       seeking will most likely be larger than the subsegment (cluster).
-  //
-  //   3 - Call |OpenByteRange| requesting |mByteRange| bytes.
-
-  if (mByteRangeDownloads) {
-    // Query decoder for chunk containing desired offset.
-    nsresult rv;
-    {
-      ReentrantMonitorAutoEnter mon(mSeekOffsetMonitor);
-      // Only continue with seek request if a prior call to |Seek| was made.
-      // If |Seek| was not called previously, it means the media cache is
-      // seeking on its own.
-      // E.g. For those WebM files which are encoded with cues at the end of
-      // the file, when the cues are parsed, the reader and media cache
-      // automatically return to the first offset not downloaded, normally the
-      // first byte after init data. This results in |MediaCache| requesting
-      // |aOffset| = 0 (aligning to the start of the cache block. Ignore this
-      // and let |DASHDecoder| decide which bytes to download and when.
-      if (mSeekOffset >= 0) {
-        rv = mDecoder->GetByteRangeForSeek(mSeekOffset, mByteRange);
-        // Cache may try to seek from the next uncached byte: this offset may
-        // be after the byte range being seeked, i.e. the range containing
-        // |mSeekOffset|, which is the offset actually requested by the reader.
-        // This case means that the seeked range is already cached. For byte
-        // range downloads, we do not permit the cache to request bytes outside
-        // the seeked range. Instead, the decoder is responsible for
-        // controlling the sequence of byte range downloads. As such, return
-        // silently, and do NOT request a new download.
-        if (NS_SUCCEEDED(rv) && !mByteRange.IsNull() &&
-            aOffset > mByteRange.mEnd) {
-          rv = NS_ERROR_NOT_AVAILABLE;
-          mByteRange.Clear();
-        }
-        mSeekOffset = -1;
-      } else if (mByteRange.mStart <= aOffset && aOffset <= mByteRange.mEnd) {
-        CMLOG("Trying to resume download at offset [%lld].", aOffset);
-        rv = NS_OK;
-      } else {
-        CMLOG("MediaCache [%p] trying to seek independently to offset [%lld].",
-            &mCacheStream, aOffset);
-        rv = NS_ERROR_NOT_AVAILABLE;
-      }
-    }
-    if (rv == NS_ERROR_NOT_AVAILABLE) {
-      // Decoder will not make byte ranges available for non-active streams, or
-      // if range information is not yet available, or for metadata bytes if
-      // they have already been downloaded and read. In all cases, it is ok to
-      // return silently and assume that the decoder will request the correct
-      // byte range when range information becomes available.
-      CMLOG("Byte range not available for decoder [%p]; returning "
-            "silently.", mDecoder);
-      return NS_OK;
-    } else if (NS_FAILED(rv) || mByteRange.IsNull()) {
-      // Decoder reported an error we don't want to handle here; just return.
-      CMLOG("Error getting byte range: seek offset[%lld] cache offset[%lld] "
-            "decoder[%p]", mSeekOffset, aOffset, mDecoder);
-      mDecoder->NetworkError();
-      CloseChannel();
-      return rv;
-    }
-    // Adjust the byte range to start where the media cache requested.
-    mByteRange.mStart = mOffset = aOffset;
-    return OpenByteRange(nullptr, mByteRange);
-  }
-#endif
-
   mOffset = aOffset;
 
   if (mSuspendCount > 0) {
     // Close the existing channel to force the channel to be recreated at
     // the correct offset upon resume.
     if (mChannel) {
       mIgnoreClose = true;
       CloseChannel();
--- a/content/media/MediaResource.h
+++ b/content/media/MediaResource.h
@@ -2,19 +2,16 @@
 /* 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 !defined(MediaResource_h_)
 #define MediaResource_h_
 
 #include "mozilla/Mutex.h"
-#ifdef MOZ_DASH
-#include "mozilla/ReentrantMonitor.h"
-#endif
 #include "nsIChannel.h"
 #include "nsIURI.h"
 #include "nsIStreamingProtocolController.h"
 #include "nsIStreamListener.h"
 #include "nsIChannelEventSink.h"
 #include "nsIInterfaceRequestor.h"
 #include "MediaCache.h"
 #include "mozilla/Attributes.h"
@@ -357,29 +354,16 @@ public:
   static already_AddRefed<MediaResource> Create(MediaDecoder* aDecoder, nsIChannel* aChannel);
 
   /**
    * Open the stream. This creates a stream listener and returns it in
    * aStreamListener; this listener needs to be notified of incoming data.
    */
   virtual nsresult Open(nsIStreamListener** aStreamListener) = 0;
 
-#ifdef MOZ_DASH
-  /**
-   * Open the stream using a specific byte range only. Creates a stream
-   * listener and returns it in aStreamListener; this listener needs to be
-   * notified of incoming data. Byte range is specified in aByteRange.
-   */
-  virtual nsresult OpenByteRange(nsIStreamListener** aStreamListener,
-                                 MediaByteRange const &aByteRange)
-  {
-    return Open(aStreamListener);
-  }
-#endif
-
   /**
    * Fills aRanges with MediaByteRanges representing the data which is cached
    * in the media cache. Stream should be pinned during call and while
    * aRanges is being used.
    */
   virtual nsresult GetCachedRanges(nsTArray<MediaByteRange>& aRanges) = 0;
 
   // Ensure that the media cache writes any data held in its partial block.
@@ -517,20 +501,16 @@ public:
   // Called on the main thread.
   virtual void FlushCache() MOZ_OVERRIDE;
 
   // Notify that the last data byte range was loaded.
   virtual void NotifyLastByteRange() MOZ_OVERRIDE;
 
   // Main thread
   virtual nsresult Open(nsIStreamListener** aStreamListener);
-#ifdef MOZ_DASH
-  virtual nsresult OpenByteRange(nsIStreamListener** aStreamListener,
-                                 MediaByteRange const & aByteRange);
-#endif
   virtual nsresult Close();
   virtual void     Suspend(bool aCloseImmediately);
   virtual void     Resume();
   virtual already_AddRefed<nsIPrincipal> GetCurrentPrincipal();
   // Return true if the stream has been closed.
   bool IsClosed() const { return mCacheStream.IsClosed(); }
   virtual bool     CanClone();
   virtual already_AddRefed<MediaResource> CloneData(MediaDecoder* aDecoder);
@@ -662,30 +642,16 @@ protected:
   bool mIgnoreResume;
 
   // True if we are seeking to get the real duration of the file.
   bool mSeekingForMetadata;
 
   // Start and end offset of the bytes to be requested.
   MediaByteRange mByteRange;
 
-#ifdef MOZ_DASH
-  // True if resource was opened with a byte rage request.
-  bool mByteRangeDownloads;
-
-  // Set to false once first byte range request has been made.
-  bool mByteRangeFirstOpen;
-
-  // For byte range requests, set to the offset requested in |Seek|.
-  // Used in |CacheClientSeek| to find the originally requested byte range.
-  // Read/Write on multiple threads; use |mSeekMonitor|.
-  ReentrantMonitor mSeekOffsetMonitor;
-  int64_t mSeekOffset;
-#endif
-
   // True if the stream can seek into unbuffered ranged, i.e. if the
   // connection supports byte range requests.
   bool mIsTransportSeekable;
 };
 
 } // namespace mozilla
 
 #endif
deleted file mode 100644
--- a/content/media/dash/DASHDecoder.cpp
+++ /dev/null
@@ -1,1387 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP.
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * Interaction with MediaDecoderStateMachine, HTMLMediaElement,
- * ChannelMediaResource and sub-decoders (WebMDecoder).
- *
- *
- *        MediaDecoderStateMachine      HTMLMediaElement
- *               1 /           \ 1           / 1
- *                /             \           /
- *             1 /               \ 1       / 1
- * DASHReader ------ DASHDecoder ------------ ChannelMediaResource
- *          |1          1      1     |1      \1             (for MPD Manifest)
- *          |                        |        ------------
- *          |*                       |*                   \*
- *     WebMReader ------- DASHRepDecoder ------- ChannelMediaResource
- *                 1       1                      1       1 (for media streams)
- *
- * One decoder and state-machine, as with current, non-DASH decoders.
- *
- * DASH adds multiple readers, decoders and resources, in order to manage
- * download and decode of the MPD manifest and individual media streams.
- *
- * Rep/|Representation| is for an individual media stream, e.g. audio
- * DASHRepDecoder is the decoder for a rep/|Representation|.
- *
- * FLOW
- *
- * 1 - Download and parse the MPD (DASH XML-based manifest).
- *
- * Media element creates new |DASHDecoder| object:
- *   member var initialization to default values, including a/v sub-decoders.
- *   MediaDecoder and MediaDecoder constructors are called.
- *   MediaDecoder::Init() is called.
- *
- * Media element creates new |ChannelMediaResource|:
- *   used to download MPD manifest.
- *
- * Media element calls |DASHDecoder|->Load() to download the MPD file:
- *   creates an |DASHReader| object to forward calls to multiple
- *     WebMReaders (corresponding to MPD |Representation|s i.e. streams).
- *     Note: 1 |DASHReader| per DASH/WebM MPD.
- *
- *   also calls |ChannelMediaResource|::Open().
- *     uses nsHttpChannel to download MPD; notifies DASHDecoder.
- *
- * Meanwhile, back in |DASHDecoder|->Load():
- *   MediaDecoderStateMachine is created.
- *     has ref to |DASHReader| object.
- *     state machine is scheduled.
- *
- * Media element finishes decoder setup:
- *   element added to media URI table etc.
- *
- * -- At this point, objects are waiting on HTTP returning MPD data.
- *
- * MPD Download (Async |ChannelMediaResource| channel callbacks):
- *   calls DASHDecoder::|NotifyDownloadEnded|().
- *     DASHDecoder parses MPD XML to DOM to MPD classes.
- *       gets |Segment| URLs from MPD for audio and video streams.
- *       creates |nsIChannel|s, |ChannelMediaResource|s.
- *         stores resources as member vars (to forward function calls later).
- *       creates |WebMReader|s and |DASHRepDecoder|s.
- *         DASHreader creates |WebMReader|s.
- *         |Representation| decoders are connected to the |ChannelMediaResource|s.
- *
- *     |DASHDecoder|->|LoadRepresentations|() starts download and decode.
- *
- *
- * 2 - Media Stream, Byte Range downloads.
- *
- * -- At this point the Segment media stream downloads are managed by
- *    individual |ChannelMediaResource|s and |WebMReader|s.
- *    A single |DASHDecoder| and |MediaDecoderStateMachine| manage them
- *    and communicate to |HTMLMediaElement|.
- *
- * Each |DASHRepDecoder| gets init range and index range from its MPD
- * |Representation|. |DASHRepDecoder| uses ChannelMediaResource to start the
- * byte range downloads, calling |OpenByteRange| with a |MediaByteRange|
- * object.
- * Once the init and index segments have been downloaded and |ReadMetadata| has
- * completed, each |WebMReader| notifies it's peer |DASHRepDecoder|.
- * Note: the decoder must wait until index data is parsed because it needs to
- *       get the offsets of the subsegments (WebM clusters) from the media file
- *       itself.
- * Since byte ranges for subsegments are obtained, |nsDASHRepdecoder| continues
- * downloading the files in byte range chunks.
- *
- * XXX Note that this implementation of DASHRepDecoder is focused on DASH
- *     WebM On Demand profile: on the todo list is an action item to make this
- *     more abstract.
- *
- * Note on |Seek|: Currently, |MediaCache| requires that seeking start at the
- *                 beginning of the block in which the desired offset would be
- *                 found. As such, when |ChannelMediaResource| does a seek
- *                 using DASH WebM subsegments (clusters), it requests a start
- *                 offset that corresponds to the beginning of the block, not
- *                 the start offset of the cluster. For DASH Webm, which has
- *                 media encoded in single files, this is fine. Future work on
- *                 other profiles will require this to be re-examined.
- */
-
-#include <limits>
-#include <prdtoa.h>
-#include "nsIURI.h"
-#include "nsIFileURL.h"
-#include "nsNetUtil.h"
-#include "VideoUtils.h"
-#include "nsThreadUtils.h"
-#include "nsContentUtils.h"
-#include "nsIContentPolicy.h"
-#include "nsIContentSecurityPolicy.h"
-#include "nsICachingChannel.h"
-#include "MediaDecoderStateMachine.h"
-#include "WebMDecoder.h"
-#include "WebMReader.h"
-#include "DASHReader.h"
-#include "nsDASHMPDParser.h"
-#include "DASHRepDecoder.h"
-#include "DASHDecoder.h"
-#include <algorithm>
-
-namespace mozilla {
-
-#ifdef PR_LOGGING
-extern PRLogModuleInfo* gMediaDecoderLog;
-#define LOG(msg, ...) PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, \
-                             ("%p [DASHDecoder] " msg, this, __VA_ARGS__))
-#define LOG1(msg) PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, \
-                         ("%p [DASHDecoder] " msg, this))
-#else
-#define LOG(msg, ...)
-#define LOG1(msg)
-#endif
-
-DASHDecoder::DASHDecoder() :
-  MediaDecoder(),
-  mNotifiedLoadAborted(false),
-  mBuffer(nullptr),
-  mBufferLength(0),
-  mMPDReaderThread(nullptr),
-  mPrincipal(nullptr),
-  mDASHReader(nullptr),
-  mVideoAdaptSetIdx(-1),
-  mAudioRepDecoderIdx(-1),
-  mVideoRepDecoderIdx(-1),
-  mAudioSubsegmentIdx(0),
-  mVideoSubsegmentIdx(0),
-  mAudioMetadataReadCount(0),
-  mVideoMetadataReadCount(0),
-  mSeeking(false),
-  mStatisticsLock("DASHDecoder.mStatisticsLock")
-{
-  MOZ_COUNT_CTOR(DASHDecoder);
-  mAudioStatistics = new MediaChannelStatistics();
-  mVideoStatistics = new MediaChannelStatistics();
-}
-
-DASHDecoder::~DASHDecoder()
-{
-  MOZ_COUNT_DTOR(DASHDecoder);
-}
-
-MediaDecoderStateMachine*
-DASHDecoder::CreateStateMachine()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  return new MediaDecoderStateMachine(this, mDASHReader);
-}
-
-void
-DASHDecoder::ReleaseStateMachine()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-
-  // Since state machine owns mDASHReader, remove reference to it.
-  mDASHReader = nullptr;
-
-  MediaDecoder::ReleaseStateMachine();
-  for (uint i = 0; i < mAudioRepDecoders.Length(); i++) {
-    mAudioRepDecoders[i]->ReleaseStateMachine();
-  }
-  for (uint i = 0; i < mVideoRepDecoders.Length(); i++) {
-    mVideoRepDecoders[i]->ReleaseStateMachine();
-  }
-}
-
-nsresult
-DASHDecoder::Load(nsIStreamListener** aStreamListener,
-                  MediaDecoder* aCloneDonor)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  mDASHReader = new DASHReader(this);
-
-  nsresult rv = OpenResource(aStreamListener);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  mDecoderStateMachine = CreateStateMachine();
-  if (!mDecoderStateMachine) {
-    LOG1("Failed to create state machine!");
-    return NS_ERROR_FAILURE;
-  }
-  return NS_OK;
-}
-
-void
-DASHDecoder::NotifyDownloadEnded(nsresult aStatus)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  // Should be no download ended notification if MPD Manager exists.
-  if (mMPDManager) {
-    LOG("Network Error! Repeated MPD download notification but MPD Manager "
-        "[%p] already exists!", mMPDManager.get());
-    NetworkError();
-    return;
-  }
-
-  if (NS_SUCCEEDED(aStatus)) {
-    LOG1("MPD downloaded.");
-
-    // mPrincipal must be set on main thread before dispatch to parser thread.
-    mPrincipal = GetCurrentPrincipal();
-
-    // Create reader thread for |ChannelMediaResource|::|Read|.
-    nsCOMPtr<nsIRunnable> event =
-      NS_NewRunnableMethod(this, &DASHDecoder::ReadMPDBuffer);
-    NS_ENSURE_TRUE_VOID(event);
-
-    nsresult rv = NS_NewNamedThread("DASH MPD Reader",
-                                    getter_AddRefs(mMPDReaderThread),
-                                    event,
-                                    MEDIA_THREAD_STACK_SIZE);
-    if (NS_FAILED(rv) || !mMPDReaderThread) {
-      LOG("Error creating MPD reader thread: rv[%x] thread [%p].",
-          rv, mMPDReaderThread.get());
-      DecodeError();
-      return;
-    }
-  } else if (aStatus == NS_BINDING_ABORTED) {
-    LOG("MPD download has been cancelled by the user: aStatus [%x].", aStatus);
-    if (mOwner) {
-      mOwner->LoadAborted();
-    }
-    return;
-  } else if (aStatus != NS_BASE_STREAM_CLOSED) {
-    LOG("Network error trying to download MPD: aStatus [%x].", aStatus);
-    NetworkError();
-  }
-}
-
-void
-DASHDecoder::ReadMPDBuffer()
-{
-  NS_ASSERTION(!NS_IsMainThread(), "Should not be on main thread.");
-
-  LOG1("Started reading from the MPD buffer.");
-
-  int64_t length = mResource->GetLength();
-  if (length <= 0 || length > DASH_MAX_MPD_SIZE) {
-    LOG("MPD is larger than [%d]MB.", DASH_MAX_MPD_SIZE/(1024*1024));
-    DecodeError();
-    return;
-  }
-
-  mBuffer = new char[length];
-
-  uint32_t count = 0;
-  nsresult rv = mResource->Read(mBuffer, length, &count);
-  // By this point, all bytes should be available for reading.
-  if (NS_FAILED(rv) || count != length) {
-    LOG("Error reading MPD buffer: rv [%x] count [%d] length [%d].",
-        rv, count, length);
-    DecodeError();
-    return;
-  }
-  // Store buffer length for processing on main thread.
-  mBufferLength = static_cast<uint32_t>(length);
-
-  LOG1("Finished reading MPD buffer; back to main thread for parsing.");
-
-  // Dispatch event to Main thread to parse MPD buffer.
-  nsCOMPtr<nsIRunnable> event =
-    NS_NewRunnableMethod(this, &DASHDecoder::OnReadMPDBufferCompleted);
-  rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
-  if (NS_FAILED(rv)) {
-    LOG("Error dispatching parse event to main thread: rv[%x]", rv);
-    DecodeError();
-    return;
-  }
-}
-
-void
-DASHDecoder::OnReadMPDBufferCompleted()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  if (mShuttingDown) {
-    LOG1("Shutting down! Ignoring OnReadMPDBufferCompleted().");
-    return;
-  }
-
-  // Shutdown the thread.
-  if (!mMPDReaderThread) {
-    LOG1("Error: MPD reader thread does not exist!");
-    DecodeError();
-    return;
-  }
-  nsresult rv = mMPDReaderThread->Shutdown();
-  if (NS_FAILED(rv)) {
-    LOG("MPD reader thread did not shutdown correctly! rv [%x]", rv);
-    DecodeError();
-    return;
-  }
-  mMPDReaderThread = nullptr;
-
-  // Start parsing the MPD data and loading the media.
-  rv = ParseMPDBuffer();
-  if (NS_FAILED(rv)) {
-    LOG("Error parsing MPD buffer! rv [%x]", rv);
-    DecodeError();
-    return;
-  }
-  rv = CreateRepDecoders();
-  if (NS_FAILED(rv)) {
-    LOG("Error creating decoders for Representations! rv [%x]", rv);
-    DecodeError();
-    return;
-  }
-
-  rv = LoadRepresentations();
-  if (NS_FAILED(rv)) {
-    LOG("Error loading Representations! rv [%x]", rv);
-    NetworkError();
-    return;
-  }
-
-  // Notify reader that it can start reading metadata. Sub-readers will still
-  // block until sub-resources have downloaded data into the media cache.
-  mDASHReader->ReadyToReadMetadata();
-}
-
-nsresult
-DASHDecoder::ParseMPDBuffer()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE(mBuffer, NS_ERROR_NULL_POINTER);
-
-  LOG1("Started parsing the MPD buffer.");
-
-  // Parse MPD buffer and get root DOM element.
-  nsAutoPtr<nsDASHMPDParser> parser;
-  parser = new nsDASHMPDParser(mBuffer.forget(), mBufferLength, mPrincipal,
-                               mResource->URI());
-  mozilla::net::DASHMPDProfile profile;
-  parser->Parse(getter_Transfers(mMPDManager), &profile);
-  mBuffer = nullptr;
-  NS_ENSURE_TRUE(mMPDManager, NS_ERROR_NULL_POINTER);
-
-  LOG("Finished parsing the MPD buffer. Profile is [%d].", profile);
-
-  return NS_OK;
-}
-
-nsresult
-DASHDecoder::CreateRepDecoders()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE(mMPDManager, NS_ERROR_NULL_POINTER);
-
-  // Global settings for the presentation.
-  int64_t startTime = mMPDManager->GetStartTime();
-  SetDuration(mMPDManager->GetDuration());
-  NS_ENSURE_TRUE(startTime >= 0 && mDuration > 0, NS_ERROR_ILLEGAL_VALUE);
-
-  // For each audio/video stream, create a |ChannelMediaResource| object.
-
-  for (uint32_t i = 0; i < mMPDManager->GetNumAdaptationSets(); i++) {
-    IMPDManager::AdaptationSetType asType = mMPDManager->GetAdaptationSetType(i);
-    if (asType == IMPDManager::DASH_VIDEO_STREAM) {
-      mVideoAdaptSetIdx = i;
-    }
-    for (uint32_t j = 0; j < mMPDManager->GetNumRepresentations(i); j++) {
-      // Get URL string.
-      nsAutoString segmentUrl;
-      nsresult rv = mMPDManager->GetFirstSegmentUrl(i, j, segmentUrl);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      // Get segment |nsIURI|; use MPD's base URI in case of relative paths.
-      nsCOMPtr<nsIURI> url;
-      rv = NS_NewURI(getter_AddRefs(url), segmentUrl, nullptr, mResource->URI());
-      NS_ENSURE_SUCCESS(rv, rv);
-#ifdef PR_LOGGING
-      nsAutoCString newUrl;
-      rv = url->GetSpec(newUrl);
-      NS_ENSURE_SUCCESS(rv, rv);
-      LOG("Using URL=\"%s\" for AdaptationSet [%d] Representation [%d]",
-          newUrl.get(), i, j);
-#endif
-
-      // 'file://' URLs are not supported.
-      nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(url);
-      NS_ENSURE_FALSE(fileURL, NS_ERROR_ILLEGAL_VALUE);
-
-      // Create |DASHRepDecoder| objects for each representation.
-      if (asType == IMPDManager::DASH_VIDEO_STREAM) {
-        Representation const * rep = mMPDManager->GetRepresentation(i, j);
-        NS_ENSURE_TRUE(rep, NS_ERROR_NULL_POINTER);
-        rv = CreateVideoRepDecoder(url, rep);
-        NS_ENSURE_SUCCESS(rv, rv);
-      } else if (asType == IMPDManager::DASH_AUDIO_STREAM) {
-        Representation const * rep = mMPDManager->GetRepresentation(i, j);
-        NS_ENSURE_TRUE(rep, NS_ERROR_NULL_POINTER);
-        rv = CreateAudioRepDecoder(url, rep);
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-    }
-  }
-
-  NS_ENSURE_TRUE(VideoRepDecoder(), NS_ERROR_NOT_INITIALIZED);
-  NS_ENSURE_TRUE(AudioRepDecoder(), NS_ERROR_NOT_INITIALIZED);
-
-  return NS_OK;
-}
-
-nsresult
-DASHDecoder::CreateAudioRepDecoder(nsIURI* aUrl,
-                                   mozilla::net::Representation const * aRep)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_ARG(aUrl);
-  NS_ENSURE_ARG(aRep);
-  NS_ENSURE_TRUE(mOwner, NS_ERROR_NOT_INITIALIZED);
-
-  // Create subdecoder and init with media element.
-  DASHRepDecoder* audioDecoder = new DASHRepDecoder(this);
-  NS_ENSURE_TRUE(audioDecoder->Init(mOwner), NS_ERROR_NOT_INITIALIZED);
-
-  // Set current decoder to the first one created.
-  if (mAudioRepDecoderIdx == -1) {
-    mAudioRepDecoderIdx = 0;
-  }
-  mAudioRepDecoders.AppendElement(audioDecoder);
-
-  // Create sub-reader; attach to DASH reader and sub-decoder.
-  WebMReader* audioReader = new WebMReader(audioDecoder);
-  if (mDASHReader) {
-    audioReader->SetMainReader(mDASHReader);
-    mDASHReader->AddAudioReader(audioReader);
-  }
-  audioDecoder->SetReader(audioReader);
-
-  // Create media resource with URL and connect to sub-decoder.
-  MediaResource* audioResource
-    = CreateAudioSubResource(aUrl, static_cast<MediaDecoder*>(audioDecoder));
-  NS_ENSURE_TRUE(audioResource, NS_ERROR_NOT_INITIALIZED);
-
-  audioDecoder->SetResource(audioResource);
-  audioDecoder->SetMPDRepresentation(aRep);
-
-  LOG("Created audio DASHRepDecoder [%p]", audioDecoder);
-
-  return NS_OK;
-}
-
-nsresult
-DASHDecoder::CreateVideoRepDecoder(nsIURI* aUrl,
-                                   mozilla::net::Representation const * aRep)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_ARG(aUrl);
-  NS_ENSURE_ARG(aRep);
-  NS_ENSURE_TRUE(mOwner, NS_ERROR_NOT_INITIALIZED);
-
-  // Create subdecoder and init with media element.
-  DASHRepDecoder* videoDecoder = new DASHRepDecoder(this);
-  NS_ENSURE_TRUE(videoDecoder->Init(mOwner), NS_ERROR_NOT_INITIALIZED);
-
-  // Set current decoder to the first one created.
-  if (mVideoRepDecoderIdx == -1) {
-    mVideoRepDecoderIdx = 0;
-  }
-  mVideoRepDecoders.AppendElement(videoDecoder);
-
-  // Create sub-reader; attach to DASH reader and sub-decoder.
-  WebMReader* videoReader = new WebMReader(videoDecoder);
-  if (mDASHReader) {
-    videoReader->SetMainReader(mDASHReader);
-    mDASHReader->AddVideoReader(videoReader);
-  }
-  videoDecoder->SetReader(videoReader);
-
-  // Create media resource with URL and connect to sub-decoder.
-  MediaResource* videoResource
-    = CreateVideoSubResource(aUrl, static_cast<MediaDecoder*>(videoDecoder));
-  NS_ENSURE_TRUE(videoResource, NS_ERROR_NOT_INITIALIZED);
-
-  videoDecoder->SetResource(videoResource);
-  videoDecoder->SetMPDRepresentation(aRep);
-
-  LOG("Created video DASHRepDecoder [%p]", videoDecoder);
-
-  return NS_OK;
-}
-
-MediaResource*
-DASHDecoder::CreateAudioSubResource(nsIURI* aUrl,
-                                    MediaDecoder* aAudioDecoder)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE(aUrl, nullptr);
-  NS_ENSURE_TRUE(aAudioDecoder, nullptr);
-
-  // Create channel for representation.
-  nsCOMPtr<nsIChannel> channel;
-  nsresult rv = CreateSubChannel(aUrl, getter_AddRefs(channel));
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  // Create resource for representation.
-  MediaResource* audioResource
-    = MediaResource::Create(aAudioDecoder, channel);
-  NS_ENSURE_TRUE(audioResource, nullptr);
-
-  audioResource->RecordStatisticsTo(mAudioStatistics);
-  return audioResource;
-}
-
-MediaResource*
-DASHDecoder::CreateVideoSubResource(nsIURI* aUrl,
-                                    MediaDecoder* aVideoDecoder)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE(aUrl, nullptr);
-  NS_ENSURE_TRUE(aVideoDecoder, nullptr);
-
-  // Create channel for representation.
-  nsCOMPtr<nsIChannel> channel;
-  nsresult rv = CreateSubChannel(aUrl, getter_AddRefs(channel));
-  NS_ENSURE_SUCCESS(rv, nullptr);
-
-  // Create resource for representation.
-  MediaResource* videoResource
-    = MediaResource::Create(aVideoDecoder, channel);
-  NS_ENSURE_TRUE(videoResource, nullptr);
-
-  videoResource->RecordStatisticsTo(mVideoStatistics);
-  return videoResource;
-}
-
-nsresult
-DASHDecoder::CreateSubChannel(nsIURI* aUrl, nsIChannel** aChannel)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_ARG(aUrl);
-
-  NS_ENSURE_TRUE(mOwner, NS_ERROR_NULL_POINTER);
-  HTMLMediaElement* element = mOwner->GetMediaElement();
-  NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
-
-  nsCOMPtr<nsILoadGroup> loadGroup =
-    element->GetDocumentLoadGroup();
-  NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
-
-  // Check for a Content Security Policy to pass down to the channel
-  // created to load the media content.
-  nsCOMPtr<nsIChannelPolicy> channelPolicy;
-  nsCOMPtr<nsIContentSecurityPolicy> csp;
-  nsresult rv = element->NodePrincipal()->GetCsp(getter_AddRefs(csp));
-  NS_ENSURE_SUCCESS(rv,rv);
-  if (csp) {
-    channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1");
-    channelPolicy->SetContentSecurityPolicy(csp);
-    channelPolicy->SetLoadType(nsIContentPolicy::TYPE_MEDIA);
-  }
-  nsCOMPtr<nsIChannel> channel;
-  rv = NS_NewChannel(getter_AddRefs(channel),
-                     aUrl,
-                     nullptr,
-                     loadGroup,
-                     nullptr,
-                     nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY,
-                     channelPolicy);
-  NS_ENSURE_SUCCESS(rv,rv);
-  NS_ENSURE_TRUE(channel, NS_ERROR_NULL_POINTER);
-
-  NS_ADDREF(*aChannel = channel);
-  return NS_OK;
-}
-
-nsresult
-DASHDecoder::LoadRepresentations()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  nsresult rv;
-  {
-    // Hold the lock while we do this to set proper lock ordering
-    // expectations for dynamic deadlock detectors: decoder lock(s)
-    // should be grabbed before the cache lock.
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-    // Load the decoders for each |Representation|'s media streams.
-    // XXX Prob ok to load all audio decoders, since there should only be one
-    //     created, but need to review the rest of the file.
-    if (AudioRepDecoder()) {
-      rv = AudioRepDecoder()->Load();
-      NS_ENSURE_SUCCESS(rv, rv);
-      mAudioMetadataReadCount++;
-    }
-    // Load all video decoders.
-    for (uint32_t i = 0; i < mVideoRepDecoders.Length(); i++) {
-      rv = mVideoRepDecoders[i]->Load();
-      NS_ENSURE_SUCCESS(rv, rv);
-      mVideoMetadataReadCount++;
-    }
-    if (AudioRepDecoder()) {
-      AudioRepDecoder()->SetStateMachine(mDecoderStateMachine);
-    }
-    for (uint32_t i = 0; i < mVideoRepDecoders.Length(); i++) {
-      mVideoRepDecoders[i]->SetStateMachine(mDecoderStateMachine);
-    }
-  }
-
-  // Ensure decoder is set to play if its already been requested.
-  if (mPlayState == PLAY_STATE_PLAYING) {
-    mNextState = PLAY_STATE_PLAYING;
-  }
-
-  // Now that subreaders are init'd, it's ok to init state machine.
-  return InitializeStateMachine(nullptr);
-}
-
-void
-DASHDecoder::NotifyDownloadEnded(DASHRepDecoder* aRepDecoder,
-                                 nsresult aStatus,
-                                 int32_t const aSubsegmentIdx)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  if (mShuttingDown) {
-    LOG1("Shutting down! Ignoring NotifyDownloadEnded().");
-    return;
-  }
-
-  // MPD Manager must exist, indicating MPD has been downloaded and parsed.
-  if (!mMPDManager) {
-    LOG1("Network Error! MPD Manager must exist, indicating MPD has been "
-        "downloaded and parsed");
-    NetworkError();
-    return;
-  }
-
-  // Decoder for the media |Representation| must not be null.
-  if (!aRepDecoder) {
-    LOG1("Decoder for Representation is reported as null.");
-    DecodeError();
-    return;
-  }
-
-  if (NS_SUCCEEDED(aStatus)) {
-    LOG("Byte range downloaded: decoder [%p] subsegmentIdx [%d]",
-        aRepDecoder, aSubsegmentIdx);
-
-    if (aSubsegmentIdx < 0) {
-      LOG("Last subsegment for decoder [%p] was downloaded",
-          aRepDecoder);
-      return;
-    }
-
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    nsRefPtr<DASHRepDecoder> decoder = aRepDecoder;
-    {
-      if (!IsDecoderAllowedToDownloadSubsegment(aRepDecoder,
-                                                aSubsegmentIdx)) {
-        NS_WARNING("Decoder downloaded subsegment but it is not allowed!");
-        LOG("Error! Decoder [%p] downloaded subsegment [%d] but it is not "
-            "allowed!", aRepDecoder, aSubsegmentIdx);
-        return;
-      }
-
-      if (aRepDecoder == VideoRepDecoder() &&
-          mVideoSubsegmentIdx == aSubsegmentIdx) {
-        IncrementSubsegmentIndex(aRepDecoder);
-      } else if (aRepDecoder == AudioRepDecoder() &&
-          mAudioSubsegmentIdx == aSubsegmentIdx) {
-        IncrementSubsegmentIndex(aRepDecoder);
-      } else {
-        return;
-      }
-
-      // Do Stream Switching here before loading next bytes.
-      // Audio stream switching not supported.
-      if (aRepDecoder == VideoRepDecoder() &&
-          (uint32_t)mVideoSubsegmentIdx < VideoRepDecoder()->GetNumDataByteRanges()) {
-        nsresult rv = PossiblySwitchDecoder(aRepDecoder);
-        if (NS_FAILED(rv)) {
-          LOG("Failed possibly switching decoder rv[0x%x]", rv);
-          DecodeError();
-          return;
-        }
-        decoder = VideoRepDecoder();
-      }
-    }
-
-    // Check that decoder is valid.
-    if (!decoder || (decoder != AudioRepDecoder() &&
-                     decoder != VideoRepDecoder())) {
-      LOG("Invalid decoder [%p]: video idx [%d] audio idx [%d]",
-          decoder.get(), AudioRepDecoder(), VideoRepDecoder());
-      DecodeError();
-      return;
-    }
-
-    // Before loading, note the index of the decoder which will downloaded the
-    // next video subsegment.
-    if (decoder == VideoRepDecoder()) {
-      if (mVideoSubsegmentLoads.IsEmpty() ||
-          (uint32_t)mVideoSubsegmentIdx >= mVideoSubsegmentLoads.Length()) {
-        LOG("Appending decoder [%d] [%p] to mVideoSubsegmentLoads at index "
-            "[%d] before load; mVideoSubsegmentIdx[%d].",
-            mVideoRepDecoderIdx, VideoRepDecoder(),
-            mVideoSubsegmentLoads.Length(), mVideoSubsegmentIdx);
-        mVideoSubsegmentLoads.AppendElement(mVideoRepDecoderIdx);
-      } else {
-        // Change an existing load, and keep subsequent entries to help
-        // determine if subsegments are cached already.
-        LOG("Setting decoder [%d] [%p] in mVideoSubsegmentLoads at index "
-            "[%d] before load; mVideoSubsegmentIdx[%d].",
-            mVideoRepDecoderIdx, VideoRepDecoder(),
-            mVideoSubsegmentIdx, mVideoSubsegmentIdx);
-        mVideoSubsegmentLoads[mVideoSubsegmentIdx] = mVideoRepDecoderIdx;
-      }
-      LOG("Notifying switch decided for video subsegment [%d]",
-          mVideoSubsegmentIdx);
-      mon.NotifyAll();
-    }
-
-    // Load the next range of data bytes. If the range is already cached,
-    // this function will be called again to adaptively download the next
-    // subsegment.
-    bool resourceLoaded = false;
-    if (decoder.get() == AudioRepDecoder()) {
-      LOG("Requesting load for audio decoder [%p] subsegment [%d].",
-        decoder.get(), mAudioSubsegmentIdx);
-      if (mAudioSubsegmentIdx >= decoder->GetNumDataByteRanges()) {
-        resourceLoaded = true;
-      }
-    } else if (decoder.get() == VideoRepDecoder()) {
-      LOG("Requesting load for video decoder [%p] subsegment [%d].",
-        decoder.get(), mVideoSubsegmentIdx);
-      if (mVideoSubsegmentIdx >= decoder->GetNumDataByteRanges()) {
-        resourceLoaded = true;
-      }
-    }
-    if (resourceLoaded) {
-      ResourceLoaded();
-      return;
-    }
-    decoder->LoadNextByteRange();
-  } else if (aStatus == NS_BINDING_ABORTED) {
-    LOG("Media download has been cancelled by the user: aStatus[%x]", aStatus);
-    if (mOwner) {
-      mOwner->LoadAborted();
-    }
-    return;
-  } else if (aStatus != NS_BASE_STREAM_CLOSED) {
-    LOG("Network error trying to download MPD: aStatus [%x].", aStatus);
-    NetworkError();
-  }
-}
-
-void
-DASHDecoder::LoadAborted()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  if (!mNotifiedLoadAborted && mOwner) {
-    LOG1("Load Aborted! Notifying media element.");
-    mOwner->LoadAborted();
-    mNotifiedLoadAborted = true;
-  }
-}
-
-void
-DASHDecoder::Suspend()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // Suspend MPD download if not yet complete.
-  if (!mMPDManager && mResource) {
-    LOG1("Suspending MPD download.");
-    mResource->Suspend(true);
-    return;
-  }
-
-  // Otherwise, forward |Suspend| to active rep decoders.
-  if (AudioRepDecoder()) {
-    LOG("Suspending download for audio decoder [%p].", AudioRepDecoder());
-    AudioRepDecoder()->Suspend();
-  }
-  if (VideoRepDecoder()) {
-    LOG("Suspending download for video decoder [%p].", VideoRepDecoder());
-    VideoRepDecoder()->Suspend();
-  }
-}
-
-void
-DASHDecoder::Resume(bool aForceBuffering)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  // Resume MPD download if not yet complete.
-  if (!mMPDManager) {
-    if (mResource) {
-      LOG1("Resuming MPD download.");
-      mResource->Resume();
-    }
-    if (aForceBuffering) {
-      ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-      if (mDecoderStateMachine) {
-        mDecoderStateMachine->StartBuffering();
-      }
-    }
-  }
-
-  // Otherwise, forward |Resume| to active rep decoders.
-  if (AudioRepDecoder()) {
-    LOG("Resuming download for audio decoder [%p].", AudioRepDecoder());
-    AudioRepDecoder()->Resume(aForceBuffering);
-  }
-  if (VideoRepDecoder()) {
-    LOG("Resuming download for video decoder [%p].", VideoRepDecoder());
-    VideoRepDecoder()->Resume(aForceBuffering);
-  }
-}
-
-void
-DASHDecoder::Shutdown()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  LOG1("Shutting down.");
-
-  // Notify reader of shutdown first.
-  if (mDASHReader) {
-    mDASHReader->NotifyDecoderShuttingDown();
-  }
-
-  // Call parent class shutdown.
-  MediaDecoder::Shutdown();
-  NS_ENSURE_TRUE_VOID(mShuttingDown);
-
-  // Shutdown reader thread if not already done.
-  if (mMPDReaderThread) {
-    nsresult rv = mMPDReaderThread->Shutdown();
-    NS_ENSURE_SUCCESS_VOID(rv);
-    mMPDReaderThread = nullptr;
-  }
-
-  // Forward to sub-decoders.
-  for (uint i = 0; i < mAudioRepDecoders.Length(); i++) {
-    if (mAudioRepDecoders[i]) {
-      mAudioRepDecoders[i]->Shutdown();
-    }
-  }
-  for (uint i = 0; i < mVideoRepDecoders.Length(); i++) {
-    if (mVideoRepDecoders[i]) {
-      mVideoRepDecoders[i]->Shutdown();
-    }
-  }
-}
-
-void
-DASHDecoder::DecodeError()
-{
-  if (NS_IsMainThread()) {
-    MediaDecoder::DecodeError();
-  } else {
-    nsCOMPtr<nsIRunnable> event =
-      NS_NewRunnableMethod(this, &MediaDecoder::DecodeError);
-    nsresult rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
-    if (NS_FAILED(rv)) {
-      LOG("Error dispatching DecodeError event to main thread: rv[%x]", rv);
-    }
-  }
-}
-
-void
-DASHDecoder::OnReadMetadataCompleted(DASHRepDecoder* aRepDecoder)
-{
-  if (mShuttingDown) {
-    LOG1("Shutting down! Ignoring OnReadMetadataCompleted().");
-    return;
-  }
-
-  NS_ASSERTION(aRepDecoder, "aRepDecoder is null!");
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-  LOG("Metadata loaded for decoder[%p]", aRepDecoder);
-
-  // Decrement audio|video metadata read counter and get ref to active decoder.
-  nsRefPtr<DASHRepDecoder> activeDecoder;
-  {
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    for (uint32_t i = 0; i < mAudioRepDecoders.Length(); i++) {
-      if (aRepDecoder == mAudioRepDecoders[i]) {
-        --mAudioMetadataReadCount;
-        break;
-      }
-    }
-    for (uint32_t i = 0; i < mVideoRepDecoders.Length(); i++) {
-      if (aRepDecoder == mVideoRepDecoders[i]) {
-        --mVideoMetadataReadCount;
-        break;
-      }
-    }
-  }
-
-  // Once all metadata is downloaded for audio|video decoders, start loading
-  // data for the active decoder.
-  if (mAudioMetadataReadCount == 0 && mVideoMetadataReadCount == 0) {
-    if (AudioRepDecoder()) {
-      LOG("Dispatching load event for audio decoder [%p]", AudioRepDecoder());
-      nsCOMPtr<nsIRunnable> event =
-        NS_NewRunnableMethod(AudioRepDecoder(), &DASHRepDecoder::LoadNextByteRange);
-      nsresult rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
-      if (NS_FAILED(rv)) {
-        LOG("Error dispatching audio decoder [%p] load event to main thread: "
-            "rv[%x]", AudioRepDecoder(), rv);
-        DecodeError();
-        return;
-      }
-    }
-    if (VideoRepDecoder()) {
-      LOG("Dispatching load event for video decoder [%p]", VideoRepDecoder());
-      // Add decoder to subsegment load history.
-      NS_ASSERTION(mVideoSubsegmentLoads.IsEmpty(),
-                   "No subsegment loads should be recorded at this stage!");
-      NS_ASSERTION(mVideoSubsegmentIdx == 0,
-                   "Current subsegment should be 0 at this stage!");
-      LOG("Appending decoder [%d] [%p] to mVideoSubsegmentLoads at index "
-          "[%d] before load; mVideoSubsegmentIdx[%d].",
-          mVideoRepDecoderIdx, VideoRepDecoder(),
-          (uint32_t)mVideoSubsegmentLoads.Length(), mVideoSubsegmentIdx);
-      mVideoSubsegmentLoads.AppendElement(mVideoRepDecoderIdx);
-
-      nsCOMPtr<nsIRunnable> event =
-        NS_NewRunnableMethod(VideoRepDecoder(), &DASHRepDecoder::LoadNextByteRange);
-      nsresult rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
-      if (NS_FAILED(rv)) {
-        LOG("Error dispatching video decoder [%p] load event to main thread: "
-            "rv[%x]", VideoRepDecoder(), rv);
-        DecodeError();
-        return;
-      }
-    }
-  }
-}
-
-nsresult
-DASHDecoder::PossiblySwitchDecoder(DASHRepDecoder* aRepDecoder)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_FALSE(mShuttingDown, NS_ERROR_UNEXPECTED);
-  NS_ENSURE_TRUE(aRepDecoder == VideoRepDecoder(), NS_ERROR_ILLEGAL_VALUE);
-  NS_ASSERTION((uint32_t)mVideoRepDecoderIdx < mVideoRepDecoders.Length(),
-               "Index for video decoder is out of bounds!");
-  NS_ASSERTION((uint32_t)mVideoSubsegmentIdx < VideoRepDecoder()->GetNumDataByteRanges(),
-               "Can't switch to a byte range out of bounds.");
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  // Now, determine if and which decoder to switch to.
-  // XXX This download rate is averaged over time, and only refers to the bytes
-  // downloaded for the video decoder. A running average would be better, and
-  // something that includes all downloads. But this will do for now.
-  NS_ASSERTION(VideoRepDecoder(), "Video decoder should not be null.");
-  NS_ASSERTION(VideoRepDecoder()->GetResource(),
-               "Video resource should not be null");
-  bool reliable = false;
-  double downloadRate = 0;
-  {
-    MutexAutoLock lock(mStatisticsLock);
-    downloadRate = mVideoStatistics->GetRate(&reliable);
-  }
-  uint32_t bestRepIdx = UINT32_MAX;
-  bool noRepAvailable = !mMPDManager->GetBestRepForBandwidth(mVideoAdaptSetIdx,
-                                                             downloadRate,
-                                                             bestRepIdx);
-  LOG("downloadRate [%0.2f kbps] reliable [%s] bestRepIdx [%d] noRepAvailable [%s]",
-      downloadRate/1000.0, (reliable ? "yes" : "no"), bestRepIdx,
-      (noRepAvailable ? "yes" : "no"));
-
-  // If there is a higher bitrate stream that can be downloaded with the
-  // current estimated bandwidth, step up to the next stream, for a graceful
-  // increase in quality.
-  uint32_t toDecoderIdx = mVideoRepDecoderIdx;
-  if (bestRepIdx > toDecoderIdx) {
-    toDecoderIdx = std::min(toDecoderIdx+1, mVideoRepDecoders.Length()-1);
-  } else if (toDecoderIdx < bestRepIdx) {
-    // If the bitrate is too much for the current bandwidth, just use that
-    // stream directly.
-    toDecoderIdx = bestRepIdx;
-  }
-
-  // Upgrade |toDecoderIdx| if a better subsegment was previously downloaded and
-  // is still cached.
-  if (mVideoSubsegmentIdx < mVideoSubsegmentLoads.Length() &&
-      toDecoderIdx < mVideoSubsegmentLoads[mVideoSubsegmentIdx]) {
-    // Check if the subsegment is cached.
-    uint32_t betterRepIdx = mVideoSubsegmentLoads[mVideoSubsegmentIdx];
-    if (mVideoRepDecoders[betterRepIdx]->IsSubsegmentCached(mVideoSubsegmentIdx)) {
-      toDecoderIdx = betterRepIdx;
-    }
-  }
-
-  NS_ENSURE_TRUE(toDecoderIdx < mVideoRepDecoders.Length(),
-                 NS_ERROR_ILLEGAL_VALUE);
-
-  // Notify reader and sub decoders and do the switch.
-  if (toDecoderIdx != (uint32_t)mVideoRepDecoderIdx) {
-    LOG("*** Switching video decoder from [%d] [%p] to [%d] [%p] at "
-        "subsegment [%d]", mVideoRepDecoderIdx, VideoRepDecoder(),
-        toDecoderIdx, mVideoRepDecoders[toDecoderIdx].get(),
-        mVideoSubsegmentIdx);
-
-    // Tell main reader to switch subreaders at |subsegmentIdx| - equates to
-    // switching data source for reading.
-    mDASHReader->RequestVideoReaderSwitch(mVideoRepDecoderIdx, toDecoderIdx,
-                                          mVideoSubsegmentIdx);
-    // Notify decoder it is about to be switched.
-    mVideoRepDecoders[mVideoRepDecoderIdx]->PrepareForSwitch();
-    // Switch video decoders - equates to switching download source.
-    mVideoRepDecoderIdx = toDecoderIdx;
-  }
-
-  return NS_OK;
-}
-
-nsresult
-DASHDecoder::Seek(double aTime)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_FALSE(mShuttingDown, NS_ERROR_UNEXPECTED);
-
-  LOG("Seeking to [%.2fs]", aTime);
-
-  {
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    // Set the seeking flag, so that when current subsegments download (if
-    // any), the next subsegment will not be downloaded.
-    mSeeking = true;
-  }
-
-  return MediaDecoder::Seek(aTime);
-}
-
-void
-DASHDecoder::NotifySeekInVideoSubsegment(int32_t aRepDecoderIdx,
-                                         int32_t aSubsegmentIdx)
-{
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  NS_ASSERTION(0 <= aRepDecoderIdx &&
-               aRepDecoderIdx < mVideoRepDecoders.Length(),
-               "Video decoder index is out of bounds");
-
-  // Reset current subsegment to match the one being seeked.
-  mVideoSubsegmentIdx = aSubsegmentIdx;
-  // Reset current decoder to match the one returned by
-  // |GetRepIdxForVideoSubsegmentLoad|.
-  mVideoRepDecoderIdx = aRepDecoderIdx;
-
-  mSeeking = false;
-
-  LOG("Dispatching load for video decoder [%d] [%p]: seek in subsegment [%d]",
-      mVideoRepDecoderIdx, VideoRepDecoder(), aSubsegmentIdx);
-
-  nsCOMPtr<nsIRunnable> event =
-    NS_NewRunnableMethod(VideoRepDecoder(),
-                         &DASHRepDecoder::LoadNextByteRange);
-  nsresult rv = NS_DispatchToMainThread(event);
-  if (NS_FAILED(rv)) {
-    LOG("Error dispatching video byte range load: rv[0x%x].",
-        rv);
-    NetworkError();
-    return;
-  }
-}
-
-void
-DASHDecoder::NotifySeekInAudioSubsegment(int32_t aSubsegmentIdx)
-{
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  // Reset current subsegment to match the one being seeked.
-  mAudioSubsegmentIdx = aSubsegmentIdx;
-
-  LOG("Dispatching seeking load for audio decoder [%d] [%p]: subsegment [%d]",
-     mAudioRepDecoderIdx, AudioRepDecoder(), aSubsegmentIdx);
-
-  nsCOMPtr<nsIRunnable> event =
-    NS_NewRunnableMethod(AudioRepDecoder(),
-                         &DASHRepDecoder::LoadNextByteRange);
-  nsresult rv = NS_DispatchToMainThread(event);
-  if (NS_FAILED(rv)) {
-    LOG("Error dispatching audio byte range load: rv[0x%x].",
-        rv);
-    NetworkError();
-    return;
-  }
-}
-
-bool
-DASHDecoder::IsDecoderAllowedToDownloadData(DASHRepDecoder* aRepDecoder)
-{
-  NS_ASSERTION(aRepDecoder, "DASHRepDecoder pointer is null.");
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  LOG("Checking aRepDecoder [%p] with AudioRepDecoder [%p] metadataReadCount "
-      "[%d] and VideoRepDecoder [%p] metadataReadCount [%d]",
-      aRepDecoder, AudioRepDecoder(), mAudioMetadataReadCount,
-      VideoRepDecoder(), mVideoMetadataReadCount);
-  // Only return true if |aRepDecoder| is active and metadata for all
-  // representations has been downloaded.
-  return ((aRepDecoder == AudioRepDecoder() && mAudioMetadataReadCount == 0) ||
-          (aRepDecoder == VideoRepDecoder() && mVideoMetadataReadCount == 0));
-}
-
-bool
-DASHDecoder::IsDecoderAllowedToDownloadSubsegment(DASHRepDecoder* aRepDecoder,
-                                                  int32_t const aSubsegmentIdx)
-{
-  NS_ASSERTION(aRepDecoder, "DASHRepDecoder pointer is null.");
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  // Forbid any downloads until we've been told what subsegment to seek to.
-  if (mSeeking) {
-    return false;
-  }
-  // Return false if there is still metadata to be downloaded.
-  if (mAudioMetadataReadCount != 0 || mVideoMetadataReadCount != 0) {
-    return false;
-  }
-  // No audio switching; allow the audio decoder to download all subsegments.
-  if (aRepDecoder == AudioRepDecoder()) {
-    return true;
-  }
-
-  int32_t videoDecoderIdx = GetRepIdxForVideoSubsegmentLoad(aSubsegmentIdx);
-  if (aRepDecoder == mVideoRepDecoders[videoDecoderIdx]) {
-    return true;
-  }
-  return false;
-}
-
-void
-DASHDecoder::SetSubsegmentIndex(DASHRepDecoder* aRepDecoder,
-                                int32_t aSubsegmentIdx)
-{
-  NS_ASSERTION(0 <= aSubsegmentIdx,
-               "Subsegment index should not be negative!");
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  if (aRepDecoder == AudioRepDecoder()) {
-    mAudioSubsegmentIdx = aSubsegmentIdx;
-  } else if (aRepDecoder == VideoRepDecoder()) {
-    // If this is called in the context of a Seek, we need to cancel downloads
-    // from other rep decoders, or all rep decoders if we're not seeking in the
-    // current subsegment.
-    // Note: NotifySeekInSubsegment called from DASHReader will already have
-    // set the current decoder.
-    mVideoSubsegmentIdx = aSubsegmentIdx;
-  }
-}
-
-double
-DASHDecoder::ComputePlaybackRate(bool* aReliable)
-{
-  GetReentrantMonitor().AssertCurrentThreadIn();
-  MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread());
-  NS_ASSERTION(aReliable, "Bool pointer aRelible should not be null!");
-
-  // While downloading the MPD, return 0; do not count manifest as media data.
-  if (mResource && !mMPDManager) {
-    return 0;
-  }
-
-  // Once MPD is downloaded, use the rate from the video decoder.
-  // XXX Not ideal, but since playback rate is used to estimate if we have
-  // enough data to continue playing, this should be sufficient.
-  double videoRate = 0;
-  if (VideoRepDecoder()) {
-    videoRate = VideoRepDecoder()->ComputePlaybackRate(aReliable);
-  }
-  return videoRate;
-}
-
-void
-DASHDecoder::UpdatePlaybackRate()
-{
-  MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread());
-  GetReentrantMonitor().AssertCurrentThreadIn();
-  // While downloading the MPD, return silently; playback rate has no meaning
-  // for the manifest.
-  if (mResource && !mMPDManager) {
-    return;
-  }
-  // Once MPD is downloaded and audio/video decoder(s) are loading, forward to
-  // active rep decoders.
-  if (AudioRepDecoder()) {
-    AudioRepDecoder()->UpdatePlaybackRate();
-  }
-  if (VideoRepDecoder()) {
-    VideoRepDecoder()->UpdatePlaybackRate();
-  }
-}
-
-void
-DASHDecoder::NotifyPlaybackStarted()
-{
-  GetReentrantMonitor().AssertCurrentThreadIn();
-  // While downloading the MPD, return silently; playback rate has no meaning
-  // for the manifest.
-  if (mResource && !mMPDManager) {
-    return;
-  }
-  // Once MPD is downloaded and audio/video decoder(s) are loading, forward to
-  // active rep decoders.
-  if (AudioRepDecoder()) {
-    AudioRepDecoder()->NotifyPlaybackStarted();
-  }
-  if (VideoRepDecoder()) {
-    VideoRepDecoder()->NotifyPlaybackStarted();
-  }
-}
-
-void
-DASHDecoder::NotifyPlaybackStopped()
-{
-  GetReentrantMonitor().AssertCurrentThreadIn();
-  // While downloading the MPD, return silently; playback rate has no meaning
-  // for the manifest.
-  if (mResource && !mMPDManager) {
-    return;
-  }
-  // Once  // Once MPD is downloaded and audio/video decoder(s) are loading, forward to
-  // active rep decoders.
-  if (AudioRepDecoder()) {
-    AudioRepDecoder()->NotifyPlaybackStopped();
-  }
-  if (VideoRepDecoder()) {
-    VideoRepDecoder()->NotifyPlaybackStopped();
-  }
-}
-
-MediaDecoder::Statistics
-DASHDecoder::GetStatistics()
-{
-  MOZ_ASSERT(NS_IsMainThread() || OnStateMachineThread());
-  Statistics result;
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  if (mResource && !mMPDManager) {
-    return MediaDecoder::GetStatistics();
-  }
-
-  // XXX Use video decoder and its media resource to get stats.
-  // This assumes that the following getter functions are getting relevant
-  // video data only.
-  if (VideoRepDecoder() && VideoRepDecoder()->GetResource()) {
-    MediaResource *resource = VideoRepDecoder()->GetResource();
-    // Note: this rate reflects the rate observed for all video downloads.
-    result.mDownloadRate =
-      resource->GetDownloadRate(&result.mDownloadRateReliable);
-    result.mDownloadPosition =
-      resource->GetCachedDataEnd(VideoRepDecoder()->mDecoderPosition);
-    result.mTotalBytes = resource->GetLength();
-    result.mPlaybackRate = ComputePlaybackRate(&result.mPlaybackRateReliable);
-    result.mDecoderPosition = VideoRepDecoder()->mDecoderPosition;
-    result.mPlaybackPosition = VideoRepDecoder()->mPlaybackPosition;
-  }
-  else {
-    result.mDownloadRate = 0;
-    result.mDownloadRateReliable = true;
-    result.mPlaybackRate = 0;
-    result.mPlaybackRateReliable = true;
-    result.mDecoderPosition = 0;
-    result.mPlaybackPosition = 0;
-    result.mDownloadPosition = 0;
-    result.mTotalBytes = 0;
-  }
-
-  return result;
-}
-
-bool
-DASHDecoder::IsDataCachedToEndOfResource()
-{
-  NS_ASSERTION(!mShuttingDown, "Don't call during shutdown!");
-  GetReentrantMonitor().AssertCurrentThreadIn();
-
-  if (!mMPDManager || !mResource) {
-    return false;
-  }
-
-  bool resourceIsLoaded = false;
-  if (VideoRepDecoder()) {
-    resourceIsLoaded = VideoRepDecoder()->IsDataCachedToEndOfResource();
-    LOG("IsDataCachedToEndOfResource for VideoRepDecoder %p = %s",
-       VideoRepDecoder(), resourceIsLoaded ? "yes" : "no");
-  }
-  if (AudioRepDecoder()) {
-    bool isAudioResourceLoaded =
-      AudioRepDecoder()->IsDataCachedToEndOfResource();
-    LOG("IsDataCachedToEndOfResource for AudioRepDecoder %p = %s",
-       AudioRepDecoder(), isAudioResourceLoaded ? "yes" : "no");
-    resourceIsLoaded = resourceIsLoaded && isAudioResourceLoaded;
-  }
-
-  return resourceIsLoaded;
-}
-
-void
-DASHDecoder::StopProgressUpdates()
-{
-  MOZ_ASSERT(OnStateMachineThread() || OnDecodeThread());
-  GetReentrantMonitor().AssertCurrentThreadIn();
-  mIgnoreProgressData = true;
-  for (uint32_t i = 0; i < mVideoRepDecoders.Length(); i++) {
-    mVideoRepDecoders[i]->StopProgressUpdates();
-  }
-  for (uint32_t i = 0; i < mAudioRepDecoders.Length(); i++) {
-    mAudioRepDecoders[i]->StopProgressUpdates();
-  }
-}
-
-void
-DASHDecoder::StartProgressUpdates()
-{
-  MOZ_ASSERT(OnStateMachineThread() || OnDecodeThread());
-  GetReentrantMonitor().AssertCurrentThreadIn();
-  mIgnoreProgressData = false;
-  for (uint32_t i = 0; i < mVideoRepDecoders.Length(); i++) {
-    mVideoRepDecoders[i]->StartProgressUpdates();
-  }
-  for (uint32_t i = 0; i < mAudioRepDecoders.Length(); i++) {
-    mAudioRepDecoders[i]->StartProgressUpdates();
-  }
-}
-
-int32_t
-DASHDecoder::GetRepIdxForVideoSubsegmentLoadAfterSeek(int32_t aSubsegmentIndex)
-{
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  // Should not be requesting decoder index for the first subsegment, nor any
-  // after the final subsegment.
-  if (aSubsegmentIndex < 1 ||
-      aSubsegmentIndex >= VideoRepDecoder()->GetNumDataByteRanges()) {
-    return -1;
-  }
-  // Wait if we are still loading the subsegment previous to the one that was
-  // queried. Note: |mVideoSubsegmentIdx| should have been updated to reflect
-  // loads of the seeked subsegment before |DASHRepReader|::|Seek| was called,
-  // i.e. before this function was called.
-  while (mVideoSubsegmentIdx == aSubsegmentIndex-1) {
-    LOG("Waiting for switching decision for video subsegment [%d].",
-        aSubsegmentIndex);
-    mon.Wait();
-  }
-
-  return mVideoSubsegmentLoads[aSubsegmentIndex];
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/content/media/dash/DASHDecoder.h
+++ /dev/null
@@ -1,412 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * see DASHDecoder.cpp for info on DASH interaction with the media engine.*/
-
-#if !defined(DASHDecoder_h_)
-#define DASHDecoder_h_
-
-#include "nsTArray.h"
-#include "nsIURI.h"
-#include "nsITimer.h"
-#include "MediaDecoder.h"
-#include "DASHReader.h"
-
-namespace mozilla {
-namespace net {
-class IMPDManager;
-class nsDASHMPDParser;
-class Representation;
-}// net
-
-class DASHRepDecoder;
-
-class DASHDecoder : public MediaDecoder
-{
-public:
-  typedef class mozilla::net::IMPDManager IMPDManager;
-  typedef class mozilla::net::nsDASHMPDParser nsDASHMPDParser;
-  typedef class mozilla::net::Representation Representation;
-
-  // XXX Arbitrary max file size for MPD. 50MB seems generously large.
-  static const uint32_t DASH_MAX_MPD_SIZE = 50*1024*1024;
-
-  DASHDecoder();
-  ~DASHDecoder();
-
-  MediaDecoder* Clone() MOZ_OVERRIDE {
-    if (!IsDASHEnabled()) {
-      return nullptr;
-    }
-    return new DASHDecoder();
-  }
-
-  // Creates a single state machine for all stream decoders.
-  // Called from Load on the main thread only.
-  MediaDecoderStateMachine* CreateStateMachine();
-
-  // Loads the MPD from the network and subsequently loads the media streams.
-  // Called from the main thread only.
-  virtual nsresult Load(nsIStreamListener** aListener,
-                        MediaDecoder* aCloneDonor) MOZ_OVERRIDE;
-
-  // Notifies download of MPD file has ended.
-  // Called on the main thread only.
-  void NotifyDownloadEnded(nsresult aStatus);
-
-  // Notification from |DASHReader| that a seek has occurred in
-  // |aSubsegmentIdx|. Passes notification onto subdecoder which downloaded
-  // the subsegment already, if download is in the past. Otherwise, it returns.
-  void NotifySeekInVideoSubsegment(int32_t aRepDecoderIdx,
-                                   int32_t aSubsegmentIdx);
-  void NotifySeekInAudioSubsegment(int32_t aSubsegmentIdx);
-
-  // Notifies that a byte range download has ended. As per the DASH spec, this
-  // allows for stream switching at the boundaries of the byte ranges.
-  // Called on the main thread only.
-  void NotifyDownloadEnded(DASHRepDecoder* aRepDecoder,
-                           nsresult aStatus,
-                           int32_t const aSubsegmentIdx);
-
-  // Notification from an |MediaDecoderReader| class that metadata has been
-  // read. Declared here to allow overloading.
-  void OnReadMetadataCompleted() MOZ_OVERRIDE { }
-
-  // Seeks to aTime in seconds
-  nsresult Seek(double aTime) MOZ_OVERRIDE;
-
-  // Notification from |DASHRepDecoder| that a metadata has been read.
-  // |DASHDecoder| will initiate load of data bytes for active audio/video
-  // decoders. Called on the decode thread.
-  void OnReadMetadataCompleted(DASHRepDecoder* aRepDecoder);
-
-  // Returns true if all subsegments from current decode position are
-  // downloaded. Must be in monitor. Call from any thread.
-  bool IsDataCachedToEndOfResource() MOZ_OVERRIDE;
-
-  // Refers to downloading data bytes, i.e. non metadata.
-  // Returns true if |aRepDecoder| is an active audio or video sub decoder AND
-  // if metadata for all audio or video decoders has been read.
-  // Could be called from any thread; enters decoder monitor.
-  bool IsDecoderAllowedToDownloadData(DASHRepDecoder* aRepDecoder);
-
-  // Refers to downloading data bytes during SEEKING.
-  // Returns true if |aRepDecoder| is the active audio sub decoder, OR if
-  // it is a video decoder and is allowed to download this subsegment.
-  // Returns false if there is still some metadata to download.
-  // Could be called from any thread; enters decoder monitor.
-  bool IsDecoderAllowedToDownloadSubsegment(DASHRepDecoder* aRepDecoder,
-                                            int32_t const aSubsegmentIdx);
-
-  // Determines if rep/sub decoders should be switched, and if so switches
-  // them. Notifies |DASHReader| if and when it should switch readers.
-  // Returns a pointer to the new active decoder.
-  // Called on the main thread.
-  nsresult PossiblySwitchDecoder(DASHRepDecoder* aRepDecoder);
-
-  // Sets the byte range index for audio|video downloads. Will only increment
-  // for current active decoders. Could be called from any thread.
-  // Requires monitor because of write to |mAudioSubsegmentIdx| or
-  // |mVideoSubsegmentIdx|.
-  void SetSubsegmentIndex(DASHRepDecoder* aRepDecoder,
-                          int32_t aSubsegmentIdx);
-
-  // Suspend any media downloads that are in progress. Called by the
-  // media element when it is sent to the bfcache, or when we need
-  // to throttle the download. Call on the main thread only. This can
-  // be called multiple times, there's an internal "suspend count".
-  void Suspend() MOZ_OVERRIDE;
-
-  // Resume any media downloads that have been suspended. Called by the
-  // media element when it is restored from the bfcache, or when we need
-  // to stop throttling the download. Call on the main thread only.
-  // The download will only actually resume once as many Resume calls
-  // have been made as Suspend calls. When aForceBuffering is true,
-  // we force the decoder to go into buffering state before resuming
-  // playback.
-  void Resume(bool aForceBuffering) MOZ_OVERRIDE;
-private:
-  // Increments the byte range index for audio|video downloads. Will only
-  // increment for current active decoders. Could be called from any thread.
-  // Requires monitor because of write to |mAudioSubsegmentIdx| or
-  // |mVideoSubsegmentIdx|.
-  void IncrementSubsegmentIndex(DASHRepDecoder* aRepDecoder)
-  {
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    if (aRepDecoder == AudioRepDecoder()) {
-      mAudioSubsegmentIdx++;
-    } else if (aRepDecoder == VideoRepDecoder()) {
-      mVideoSubsegmentIdx++;
-    }
-  }
-public:
-  // Gets the byte range index for audio|video downloads. Will only increment
-  // for current active decoders. Could be called from any thread. Will enter
-  // monitor for read access off the decode thread.
-  int32_t GetSubsegmentIndex(DASHRepDecoder* aRepDecoder)
-  {
-    ReentrantMonitorConditionallyEnter mon(!OnDecodeThread(),
-                                           GetReentrantMonitor());
-    if (aRepDecoder == AudioRepDecoder()) {
-      return mAudioSubsegmentIdx;
-    } else if (aRepDecoder == VideoRepDecoder()) {
-      return mVideoSubsegmentIdx;
-    }
-    return (-1);
-  }
-
-  // Returns the total number of subsegments that have been loaded. Will enter
-  // monitor for read access off the decode thread.
-  uint32_t GetNumSubsegmentLoads() {
-    ReentrantMonitorConditionallyEnter mon(!OnDecodeThread(),
-                                           GetReentrantMonitor());
-    return mVideoSubsegmentLoads.Length();
-  }
-
-  // Returns the index of the rep decoder used to load a subsegment. Will enter
-  // monitor for read access off the decode thread.
-  int32_t GetRepIdxForVideoSubsegmentLoad(int32_t aSubsegmentIdx)
-  {
-    NS_ASSERTION(0 <= aSubsegmentIdx, "Subsegment index should not be negative.");
-    ReentrantMonitorConditionallyEnter mon(!OnDecodeThread(),
-                                           GetReentrantMonitor());
-    if ((uint32_t)aSubsegmentIdx < mVideoSubsegmentLoads.Length()) {
-      return mVideoSubsegmentLoads[aSubsegmentIdx];
-    } else {
-      // If it hasn't been downloaded yet, use the lowest bitrate decoder.
-      return 0;
-    }
-  }
-
-  // Returns the index of the rep decoder used to load a subsegment, after a
-  // seek. Called on the decode thread, and will block if the subsegment
-  // previous to the one specified has not yet been loaded. This ensures that
-  // |DASHDecoder| has had a chance to determine which decoder should load the
-  // next subsegment, in the case where |DASHRepReader|::|DecodeToTarget| has
-  // read all the data for the current subsegment from the cache, and needs to
-  // know which reader (including itself) to use next.
-  int32_t GetRepIdxForVideoSubsegmentLoadAfterSeek(int32_t aSubsegmentIndex);
-
-  int32_t GetSwitchCountAtVideoSubsegment(int32_t aSubsegmentIdx)
-  {
-    ReentrantMonitorConditionallyEnter mon(!OnDecodeThread(),
-                                           GetReentrantMonitor());
-    NS_ASSERTION(0 <= aSubsegmentIdx, "Subsegment index should not be negative.");
-    if (aSubsegmentIdx == 0) {
-      // Do the zeroeth switch next.
-      return 0;
-    }
-    int32_t switchCount = 0;
-    for (uint32_t i = 1;
-         i < mVideoSubsegmentLoads.Length() &&
-         i <= (uint32_t)aSubsegmentIdx;
-         i++) {
-      if (mVideoSubsegmentLoads[i-1] != mVideoSubsegmentLoads[i]) {
-        switchCount++;
-      }
-    }
-    return switchCount;
-  }
-
-  // The actual playback rate computation. The monitor must be held.
-  // XXX Computes playback for the current video rep decoder only.
-  double ComputePlaybackRate(bool* aReliable) MOZ_OVERRIDE;
-
-  // Something has changed that could affect the computed playback rate,
-  // so recompute it. The monitor must be held. Will be forwarded to current
-  // audio and video rep decoders.
-  void UpdatePlaybackRate() MOZ_OVERRIDE;
-
-  // Stop updating the bytes downloaded for progress notifications. Called
-  // when seeking to prevent wild changes to the progress notification.
-  // Forwarded to sub-decoders. Must be called with the decoder monitor held.
-  void StopProgressUpdates() MOZ_OVERRIDE;
-
-  // Allow updating the bytes downloaded for progress notifications.
-  // Forwarded to sub-decoders. Must be called with the decoder monitor held.
-  void StartProgressUpdates() MOZ_OVERRIDE;
-
-  // Used to estimate rates of data passing through the decoder's channel.
-  // Records activity starting on the channel. The monitor must be held.
-  virtual void NotifyPlaybackStarted() MOZ_OVERRIDE;
-
-  // Used to estimate rates of data passing through the decoder's channel.
-  // Records activity stopping on the channel. The monitor must be held.
-  virtual void NotifyPlaybackStopped() MOZ_OVERRIDE;
-
-  // Return statistics. This is used for progress events and other things.
-  // This can be called from any thread. It's only a snapshot of the
-  // current state, since other threads might be changing the state
-  // at any time.
-  // XXX Stats are calculated based on the current video rep decoder, with the
-  // exception of download rate, which is based on all video downloads.
-  virtual Statistics GetStatistics() MOZ_OVERRIDE;
-
-  // Drop reference to state machine and tell sub-decoders to do the same.
-  // Only called during shutdown dance, on main thread only.
-  void ReleaseStateMachine();
-
-  // Overridden to forward |Shutdown| to sub-decoders.
-  // Called on the main thread only.
-  void Shutdown();
-
-  // Called by sub-decoders when load has been aborted. Will notify media
-  // element only once. Called on the main thread only.
-  void LoadAborted();
-
-  // Notifies the element that decoding has failed. On main thread, call is
-  // forwarded to |MediaDecoder|::|Error| immediately. On other threads,
-  // a call is dispatched for execution on the main thread.
-  void DecodeError();
-
-private:
-  // Reads the MPD data from resource to a byte stream.
-  // Called on the MPD reader thread.
-  void ReadMPDBuffer();
-
-  // Called when MPD data is completely read.
-  // On the main thread.
-  void OnReadMPDBufferCompleted();
-
-  // Parses the copied MPD byte stream.
-  // On the main thread: DOM APIs complain when off the main thread.
-  nsresult ParseMPDBuffer();
-
-  // Creates the sub-decoders for a |Representation|, i.e. media streams.
-  // On the main thread.
-  nsresult CreateRepDecoders();
-
-  // Creates audio/video decoders for individual |Representation|s.
-  // On the main thread.
-  nsresult CreateAudioRepDecoder(nsIURI* aUrl, Representation const * aRep);
-  nsresult CreateVideoRepDecoder(nsIURI* aUrl, Representation const * aRep);
-
-  // Get audio sub-decoder for current audio |Representation|. Will return
-  // nullptr for out of range indexes.
-  // Enters monitor for read access off the decode thread.
-  // XXX Note: Although an array of audio decoders is provided, audio stream
-  // switching is not yet supported.
-  DASHRepDecoder* AudioRepDecoder() {
-    ReentrantMonitorConditionallyEnter mon(!OnDecodeThread(),
-                                           GetReentrantMonitor());
-    if (0 == mAudioRepDecoders.Length()) {
-      return nullptr;
-    }
-    NS_ENSURE_TRUE((uint32_t)mAudioRepDecoderIdx < mAudioRepDecoders.Length(),
-                   nullptr);
-    if (mAudioRepDecoderIdx < 0) {
-      return nullptr;
-    } else {
-      return mAudioRepDecoders[mAudioRepDecoderIdx];
-    }
-  }
-
-  // Get video sub-decoder for current video |Representation|. Will return
-  // nullptr for out of range indexes.
-  // Enters monitor for read access off the decode thread.
-  DASHRepDecoder* VideoRepDecoder() {
-    ReentrantMonitorConditionallyEnter mon(!OnDecodeThread(),
-                                           GetReentrantMonitor());
-    if (0 == mVideoRepDecoders.Length()) {
-      return nullptr;
-    }
-    NS_ENSURE_TRUE((uint32_t)mVideoRepDecoderIdx < mVideoRepDecoders.Length(),
-                   nullptr);
-    if (mVideoRepDecoderIdx < 0) {
-      return nullptr;
-    } else {
-      return mVideoRepDecoders[mVideoRepDecoderIdx];
-    }
-  }
-
-  // Creates audio/video resources for individual |Representation|s.
-  // On the main thread.
-  MediaResource* CreateAudioSubResource(nsIURI* aUrl,
-                                        MediaDecoder* aAudioDecoder);
-  MediaResource* CreateVideoSubResource(nsIURI* aUrl,
-                                        MediaDecoder* aVideoDecoder);
-
-  // Creates an http channel for a |Representation|.
-  // On the main thread.
-  nsresult CreateSubChannel(nsIURI* aUrl, nsIChannel** aChannel);
-
-  // Loads the media |Representations|, i.e. the media streams.
-  // On the main thread.
-  nsresult LoadRepresentations();
-
-  // True when media element has already been notified of an aborted load.
-  bool mNotifiedLoadAborted;
-
-  // Ptr for the MPD data.
-  nsAutoArrayPtr<char>         mBuffer;
-  // Length of the MPD data.
-  uint32_t                     mBufferLength;
-  // Ptr to the MPD Reader thread.
-  nsCOMPtr<nsIThread>          mMPDReaderThread;
-  // Document Principal.
-  nsCOMPtr<nsIPrincipal>       mPrincipal;
-
-  // MPD Manager provides access to the MPD information.
-  nsAutoPtr<IMPDManager>       mMPDManager;
-
-  // Main reader object; manages all sub-readers for |Representation|s. Owned by
-  // state machine; destroyed in state machine's destructor.
-  DASHReader* mDASHReader;
-
-  // Sub-decoder vars. Note: For all following members, the decode monitor
-  // should be held for write access on decode thread, and all read/write off
-  // the decode thread.
-
-  // Index of the video |AdaptationSet|.
-  int32_t mVideoAdaptSetIdx;
-
-  // Indexes for the current audio and video decoders.
-  int32_t mAudioRepDecoderIdx;
-  int32_t mVideoRepDecoderIdx;
-
-  // Array of pointers for the |Representation|s in the audio/video
-  // |AdaptationSet|.
-  nsTArray<nsRefPtr<DASHRepDecoder> > mAudioRepDecoders;
-  nsTArray<nsRefPtr<DASHRepDecoder> > mVideoRepDecoders;
-
-  // Current index of subsegments downloaded for audio/video decoder.
-  int32_t mAudioSubsegmentIdx;
-  int32_t mVideoSubsegmentIdx;
-
-  // Count for the number of readers which have called |OnReadMetadataCompleted|.
-  // Initialised to 0; incremented for every decoder which has |Load| called;
-  // and decremented for every call to |OnReadMetadataCompleted|. When it is
-  // zero again, all metadata has been read for audio or video, and data bytes
-  // can be downloaded.
-  uint32_t mAudioMetadataReadCount;
-  uint32_t mVideoMetadataReadCount;
-
-  // Array records the index of the decoder/Representation which loaded each
-  // subsegment.
-  nsTArray<int32_t> mVideoSubsegmentLoads;
-
-  // True when Seek is called; will block any downloads until
-  // |NotifySeekInSubsegment| is called, which will set it to false, and will
-  // start a new series of downloads from the seeked subsegment.
-  bool mSeeking;
-
-  // Mutex for statistics.
-  Mutex mStatisticsLock;
-  // Stores snapshot statistics, such as download rate, for the audio|video
-  // data streams. |mStatisticsLock| must be locked for access.
-  nsRefPtr<MediaChannelStatistics> mAudioStatistics;
-  nsRefPtr<MediaChannelStatistics> mVideoStatistics;
-};
-
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/content/media/dash/DASHReader.cpp
+++ /dev/null
@@ -1,674 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * see DASHDecoder.cpp for info on DASH interaction with the media engine.*/
-
-#include "mozilla/dom/TimeRanges.h"
-#include "VideoFrameContainer.h"
-#include "AbstractMediaDecoder.h"
-#include "DASHReader.h"
-#include "DASHDecoder.h"
-#include <algorithm>
-
-namespace mozilla {
-
-#ifdef PR_LOGGING
-PRLogModuleInfo* gDASHReaderLog;
-#define LOG(msg, ...) PR_LOG(gDASHReaderLog, PR_LOG_DEBUG, \
-                             ("%p [DASHReader] " msg, this, __VA_ARGS__))
-#define LOG1(msg) PR_LOG(gDASHReaderLog, PR_LOG_DEBUG, \
-                         ("%p [DASHReader] " msg, this))
-#else
-#define LOG(msg, ...)
-#define LOG1(msg)
-#endif
-
-DASHReader::DASHReader(AbstractMediaDecoder* aDecoder) :
-  MediaDecoderReader(aDecoder),
-  mReadMetadataMonitor("media.dashreader.readmetadata"),
-  mReadyToReadMetadata(false),
-  mDecoderIsShuttingDown(false),
-  mAudioReader(this),
-  mVideoReader(this),
-  mAudioReaders(this),
-  mVideoReaders(this),
-  mSwitchVideoReaders(false),
-  mSwitchCount(-1)
-{
-  MOZ_COUNT_CTOR(DASHReader);
-#ifdef PR_LOGGING
-  if (!gDASHReaderLog) {
-    gDASHReaderLog = PR_NewLogModule("DASHReader");
-  }
-#endif
-}
-
-DASHReader::~DASHReader()
-{
-  MOZ_COUNT_DTOR(DASHReader);
-}
-
-nsresult
-DASHReader::ResetDecode()
-{
-  MediaDecoderReader::ResetDecode();
-  nsresult rv;
-  for (uint i = 0; i < mAudioReaders.Length(); i++) {
-    rv = mAudioReaders[i]->ResetDecode();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  for (uint i = 0; i < mVideoReaders.Length(); i++) {
-    rv = mVideoReaders[i]->ResetDecode();
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  return NS_OK;
-}
-
-nsresult
-DASHReader::Init(MediaDecoderReader* aCloneDonor)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  NS_ASSERTION(mAudioReaders.Length() != 0 && mVideoReaders.Length() != 0,
-               "Audio and video readers should exist already.");
-
-  nsresult rv;
-  for (uint i = 0; i < mAudioReaders.Length(); i++) {
-    rv = mAudioReaders[i]->Init(nullptr);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  for (uint i = 0; i < mVideoReaders.Length(); i++) {
-    rv = mVideoReaders[i]->Init(nullptr);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  return NS_OK;
-}
-
-void
-DASHReader::AddAudioReader(DASHRepReader* aAudioReader)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE_VOID(aAudioReader);
-
-  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-
-  mAudioReaders.AppendElement(aAudioReader);
-  // XXX For now, just pick the first reader to be default.
-  if (!mAudioReader)
-    mAudioReader = aAudioReader;
-}
-
-void
-DASHReader::AddVideoReader(DASHRepReader* aVideoReader)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE_VOID(aVideoReader);
-
-  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-
-  mVideoReaders.AppendElement(aVideoReader);
-  // XXX For now, just pick the first reader to be default.
-  if (!mVideoReader)
-    mVideoReader = aVideoReader;
-}
-
-bool
-DASHReader::HasAudio()
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  return mAudioReader ? mAudioReader->HasAudio() : false;
-}
-
-bool
-DASHReader::HasVideo()
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  return mVideoReader ? mVideoReader->HasVideo() : false;
-}
-
-int64_t
-DASHReader::VideoQueueMemoryInUse()
-{
-  ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
-                                         mDecoder->GetReentrantMonitor());
-  return VideoQueueMemoryInUse();
-}
-
-int64_t
-DASHReader::AudioQueueMemoryInUse()
-{
-  ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
-                                         mDecoder->GetReentrantMonitor());
-  return AudioQueueMemoryInUse();
-}
-
-bool
-DASHReader::DecodeVideoFrame(bool &aKeyframeSkip,
-                             int64_t aTimeThreshold)
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  if (mVideoReader) {
-   return mVideoReader->DecodeVideoFrame(aKeyframeSkip, aTimeThreshold);
-  } else {
-   return false;
-  }
-}
-
-bool
-DASHReader::DecodeAudioData()
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  return (mAudioReader ? mAudioReader->DecodeAudioData() : false);
-}
-
-nsresult
-DASHReader::ReadMetadata(MediaInfo* aInfo,
-                         MetadataTags** aTags)
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-
-  // Wait for MPD to be parsed and child readers created.
-  LOG1("Waiting for metadata download.");
-  nsresult rv = WaitForMetadata();
-  // If we get an abort, return silently; the decoder is shutting down.
-  if (NS_ERROR_ABORT == rv) {
-    return NS_OK;
-  }
-  // Verify no other errors before continuing.
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  NS_ASSERTION(aTags, "Called with null MetadataTags**.");
-  *aTags = nullptr;
-
-  // Get metadata from child readers.
-  MediaInfo audioInfo, videoInfo;
-
-  // Read metadata for all video streams.
-  for (uint i = 0; i < mVideoReaders.Length(); i++) {
-    // Use an nsAutoPtr here to ensure |tags| memory does not leak.
-    nsAutoPtr<HTMLMediaElement::MetadataTags> tags;
-    rv = mVideoReaders[i]->ReadMetadata(&videoInfo, getter_Transfers(tags));
-    NS_ENSURE_SUCCESS(rv, rv);
-    // Use metadata from current video sub reader to populate aInfo.
-    if (mVideoReaders[i] == mVideoReader) {
-      mInfo.mVideo = videoInfo.mVideo;
-    }
-  }
-  // Read metadata for audio stream.
-  // Note: Getting metadata tags from audio reader only for now.
-  // XXX Audio stream switching not yet supported.
-  if (mAudioReader) {
-    rv = mAudioReader->ReadMetadata(&audioInfo, aTags);
-    NS_ENSURE_SUCCESS(rv, rv);
-    mInfo.mAudio = audioInfo.mAudio;
-  }
-
-  *aInfo = mInfo;
-
-  return NS_OK;
-}
-
-nsresult
-DASHReader::Seek(int64_t aTime,
-                 int64_t aStartTime,
-                 int64_t aEndTime,
-                 int64_t aCurrentTime)
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-
-  NS_ENSURE_SUCCESS(ResetDecode(), NS_ERROR_FAILURE);
-
-  LOG("Seeking to [%.2fs]", aTime/1000000.0);
-
-  nsresult rv;
-  DASHDecoder* dashDecoder = static_cast<DASHDecoder*>(mDecoder);
-
-  if (mAudioReader) {
-    int64_t subsegmentIdx = -1;
-    {
-      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-      subsegmentIdx = mAudioReader->GetSubsegmentForSeekTime(aTime);
-      NS_ENSURE_TRUE(0 <= subsegmentIdx, NS_ERROR_ILLEGAL_VALUE);
-    }
-    dashDecoder->NotifySeekInAudioSubsegment(subsegmentIdx);
-
-    rv = mAudioReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  if (mVideoReader) {
-    // Determine the video subsegment we're seeking to.
-    int32_t subsegmentIdx = -1;
-    {
-      ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-      subsegmentIdx = mVideoReader->GetSubsegmentForSeekTime(aTime);
-      NS_ENSURE_TRUE(0 <= subsegmentIdx, NS_ERROR_ILLEGAL_VALUE);
-    }
-
-    LOG("Seek to [%.2fs] found in video subsegment [%d]",
-        aTime/1000000.0, subsegmentIdx);
-
-    // Determine if/which video reader previously downloaded this subsegment.
-    int32_t readerIdx = dashDecoder->GetRepIdxForVideoSubsegmentLoad(subsegmentIdx);
-
-    dashDecoder->NotifySeekInVideoSubsegment(readerIdx, subsegmentIdx);
-
-    if (0 <= readerIdx) {
-      NS_ENSURE_TRUE(readerIdx < mVideoReaders.Length(),
-                     NS_ERROR_ILLEGAL_VALUE);
-      // Switch to this reader and do the Seek.
-      DASHRepReader* fromReader = mVideoReader;
-      DASHRepReader* toReader = mVideoReaders[readerIdx];
-
-      {
-        ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-        if (fromReader != toReader) {
-          LOG("Switching video readers now from [%p] to [%p] for a seek to "
-              "[%.2fs] in subsegment [%d]",
-              fromReader, toReader, aTime/1000000.0, subsegmentIdx);
-
-          mVideoReader = toReader;
-        }
-      }
-
-      rv = mVideoReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
-      if (NS_FAILED(rv)) {
-        NS_ENSURE_SUCCESS(rv, rv);
-      }
-
-      // Go back to the appropriate count in the switching history, and setup
-      // this main reader and the sub readers for the next switch (if any).
-      {
-        ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-        mSwitchCount = dashDecoder->GetSwitchCountAtVideoSubsegment(subsegmentIdx);
-        LOG("After mVideoReader->Seek() mSwitchCount %d", mSwitchCount);
-        NS_ENSURE_TRUE(0 <= mSwitchCount, NS_ERROR_ILLEGAL_VALUE);
-        NS_ENSURE_TRUE(mSwitchCount <= subsegmentIdx, NS_ERROR_ILLEGAL_VALUE);
-      }
-    } else {
-      LOG("Error getting rep idx for video subsegment [%d]",
-          subsegmentIdx);
-    }
-  }
-  return NS_OK;
-}
-
-nsresult
-DASHReader::GetBuffered(TimeRanges* aBuffered,
-                        int64_t aStartTime)
-{
-  NS_ENSURE_ARG(aBuffered);
-
-  MediaResource* resource = nullptr;
-  AbstractMediaDecoder* decoder = nullptr;
-
-  TimeRanges audioBuffered, videoBuffered;
-  uint32_t audioRangeCount = 0, videoRangeCount = 0;
-  bool audioCachedAtEnd = false, videoCachedAtEnd = false;
-
-  nsresult rv = NS_OK;
-
-  // Get all audio and video buffered ranges. Include inactive streams, since
-  // we may have carried out a seek and future subsegments may be in currently
-  // inactive decoders.
-  ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
-                                         mDecoder->GetReentrantMonitor());
-  for (uint32_t i = 0; i < mAudioReaders.Length(); i++) {
-    decoder = mAudioReaders[i]->GetDecoder();
-    NS_ENSURE_TRUE(decoder, NS_ERROR_NULL_POINTER);
-    resource = decoder->GetResource();
-    NS_ENSURE_TRUE(resource, NS_ERROR_NULL_POINTER);
-    resource->Pin();
-    rv = mAudioReaders[i]->GetBuffered(&audioBuffered, aStartTime);
-    NS_ENSURE_SUCCESS(rv, rv);
-    // If data was cached at the end, then the final timestamp refers to the
-    // end of the data. Use this later to extend end time if necessary.
-    if (!audioCachedAtEnd) {
-      audioCachedAtEnd = mAudioReaders[i]->IsDataCachedAtEndOfSubsegments();
-    }
-    resource->Unpin();
-  }
-  for (uint32_t i = 0; i < mVideoReaders.Length(); i++) {
-    decoder = mVideoReaders[i]->GetDecoder();
-    NS_ENSURE_TRUE(decoder, NS_ERROR_NULL_POINTER);
-    resource = decoder->GetResource();
-    NS_ENSURE_TRUE(resource, NS_ERROR_NULL_POINTER);
-    resource->Pin();
-    rv = mVideoReaders[i]->GetBuffered(&videoBuffered, aStartTime);
-    NS_ENSURE_SUCCESS(rv, rv);
-    // If data was cached at the end, then the final timestamp refers to the
-    // end of the data. Use this later to extend end time if necessary.
-    if (!videoCachedAtEnd) {
-      videoCachedAtEnd = mVideoReaders[i]->IsDataCachedAtEndOfSubsegments();
-    }
-    resource->Unpin();
-  }
-
-  audioBuffered.Normalize();
-  videoBuffered.Normalize();
-
-  rv = audioBuffered.GetLength(&audioRangeCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-  rv = videoBuffered.GetLength(&videoRangeCount);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-#ifdef PR_LOGGING
-  double start = 0, end = 0;
-  for (uint32_t i = 0; i < audioRangeCount; i++) {
-    rv = audioBuffered.Start(i, &start);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = audioBuffered.End(i, &end);
-    NS_ENSURE_SUCCESS(rv, rv);
-    LOG("audioBuffered[%d] = (%f, %f)",
-        i, start, end);
-  }
-  for (uint32_t i = 0; i < videoRangeCount; i++) {
-    rv = videoBuffered.Start(i, &start);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = videoBuffered.End(i, &end);
-    NS_ENSURE_SUCCESS(rv, rv);
-    LOG("videoBuffered[%d] = (%f, %f)",
-        i, start, end);
-  }
-#endif
-
-  // If audio and video are cached to the end of their subsegments, extend the
-  // end time of the shorter of the two. Presentation of the shorter stream
-  // will stop at the end, while the other continues until the combined
-  // playback is complete.
-  // Note: Only in cases where the shorter stream is fully cached, and the
-  // longer stream is partially cached, but with more time buffered than the
-  // shorter stream.
-  //
-  // Audio ========|
-  //               20
-  // Video ============|----|
-  //                   30   40
-  // Combo ============|      <----- End time EXTENDED.
-  //
-  // For example, audio is fully cached to 20s, but video is partially cached
-  // to 30s, full duration 40s. In this case, the buffered end time should be
-  // extended to the video's end time.
-  //
-  // Audio =================|
-  //                        40
-  // Video ========|----|
-  //               20   30
-  // Combo ========|          <------ End time NOT EXTENDED.
-  //
-  // Conversely, if the longer stream is fully cached, but the shorter one is
-  // not, no extension of end time should occur - we should consider the
-  // partially cached, shorter end time to be the end time of the combined
-  // stream
-
-  if (audioCachedAtEnd || videoCachedAtEnd) {
-    NS_ENSURE_TRUE(audioRangeCount, NS_ERROR_FAILURE);
-    NS_ENSURE_TRUE(videoRangeCount, NS_ERROR_FAILURE);
-
-    double audioEndTime = 0, videoEndTime = 0;
-    // Get end time of the last range of buffered audio.
-    audioEndTime = audioBuffered.GetFinalEndTime();
-    NS_ENSURE_TRUE(audioEndTime > 0, NS_ERROR_ILLEGAL_VALUE);
-    // Get end time of the last range of buffered video.
-    videoEndTime = videoBuffered.GetFinalEndTime();
-    NS_ENSURE_TRUE(videoEndTime > 0, NS_ERROR_ILLEGAL_VALUE);
-
-    // API for TimeRanges requires extending through adding and normalizing.
-    if (videoCachedAtEnd && audioEndTime > videoEndTime) {
-      videoBuffered.Add(videoEndTime, audioEndTime);
-      videoBuffered.Normalize();
-      LOG("videoBuffered extended to %f", audioEndTime);
-    } else if (audioCachedAtEnd && videoEndTime > audioEndTime) {
-      audioBuffered.Add(audioEndTime, videoEndTime);
-      audioBuffered.Normalize();
-      LOG("audioBuffered extended to %f", videoEndTime);
-    }
-  }
-
-  // Calculate intersecting ranges for video and audio.
-  if (!mAudioReaders.IsEmpty() && !mVideoReaders.IsEmpty()) {
-    for (uint32_t i = 0; i < audioRangeCount; i++) {
-      // |A|udio, |V|ideo, |I|ntersect.
-      double startA, startV, startI;
-      double endA, endV, endI;
-      rv = audioBuffered.Start(i, &startA);
-      NS_ENSURE_SUCCESS(rv, rv);
-      rv = audioBuffered.End(i, &endA);
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      for (uint32_t j = 0; j < videoRangeCount; j++) {
-        rv = videoBuffered.Start(i, &startV);
-        NS_ENSURE_SUCCESS(rv, rv);
-        rv = videoBuffered.End(i, &endV);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        // If video block is before audio block, compare next video block.
-        if (startA > endV) {
-          continue;
-        // If video block is after audio block, all of them are; compare next
-        // audio block.
-        } else if (endA < startV) {
-          break;
-        }
-        // Calculate intersections of current audio and video blocks.
-        startI = (startA > startV) ? startA : startV;
-        endI = (endA > endV) ? endV : endA;
-        aBuffered->Add(startI, endI);
-      }
-    }
-  } else if (!mAudioReaders.IsEmpty()) {
-    *aBuffered = audioBuffered;
-  } else if (!mVideoReaders.IsEmpty()) {
-    *aBuffered = videoBuffered;
-  } else {
-    return NS_ERROR_NOT_INITIALIZED;
-  }
-
-  return NS_OK;
-}
-
-VideoData*
-DASHReader::FindStartTime(int64_t& aOutStartTime)
-{
-  NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
-               "Should be on state machine or decode thread.");
-
-  // Extract the start times of the bitstreams in order to calculate
-  // the duration.
-  int64_t videoStartTime = INT64_MAX;
-  int64_t audioStartTime = INT64_MAX;
-  VideoData* videoData = nullptr;
-
-  ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
-                                         mDecoder->GetReentrantMonitor());
-  if (HasVideo()) {
-    // Forward to video reader.
-    videoData = mVideoReader->DecodeToFirstVideoData();
-    if (videoData) {
-      videoStartTime = videoData->mTime;
-    }
-  }
-  if (HasAudio()) {
-    // Forward to audio reader.
-    AudioData* audioData = mAudioReader->DecodeToFirstAudioData();
-    if (audioData) {
-      audioStartTime = audioData->mTime;
-    }
-  }
-
-  int64_t startTime = std::min(videoStartTime, audioStartTime);
-  if (startTime != INT64_MAX) {
-    aOutStartTime = startTime;
-  }
-
-  return videoData;
-}
-
-MediaQueue<AudioData>&
-DASHReader::AudioQueue()
-{
-  ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
-                                         mDecoder->GetReentrantMonitor());
-  NS_ASSERTION(mAudioReader, "mAudioReader is NULL!");
-  return mAudioQueue;
-}
-
-MediaQueue<VideoData>&
-DASHReader::VideoQueue()
-{
-  ReentrantMonitorConditionallyEnter mon(!mDecoder->OnDecodeThread(),
-                                         mDecoder->GetReentrantMonitor());
-  NS_ASSERTION(mVideoReader, "mVideoReader is NULL!");
-  return mVideoQueue;
-}
-
-void
-DASHReader::RequestVideoReaderSwitch(uint32_t aFromReaderIdx,
-                                     uint32_t aToReaderIdx,
-                                     uint32_t aSubsegmentIdx)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ASSERTION(aFromReaderIdx < mVideoReaders.Length(),
-               "From index is greater than number of video readers!");
-  NS_ASSERTION(aToReaderIdx < mVideoReaders.Length(),
-               "To index is greater than number of video readers!");
-  NS_ASSERTION(aToReaderIdx != aFromReaderIdx,
-               "Don't request switches to same reader!");
-  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
-
-  if (mSwitchCount < 0) {
-    mSwitchCount = 0;
-  }
-
-  DASHRepReader* fromReader = mVideoReaders[aFromReaderIdx];
-  DASHRepReader* toReader = mVideoReaders[aToReaderIdx];
-
-  LOG("Switch requested from reader [%d] [%p] to reader [%d] [%p] "
-      "at subsegment[%d].",
-      aFromReaderIdx, fromReader, aToReaderIdx, toReader, aSubsegmentIdx);
-
-  // Append the subsegment index to the list of pending switches.
-  for (uint32_t i = 0; i < mSwitchToVideoSubsegmentIndexes.Length(); i++) {
-    if (mSwitchToVideoSubsegmentIndexes[i] == aSubsegmentIdx) {
-      // A backwards |Seek| has changed the switching history; delete from
-      // this point on.
-      mSwitchToVideoSubsegmentIndexes.TruncateLength(i);
-      break;
-    }
-  }
-  mSwitchToVideoSubsegmentIndexes.AppendElement(aSubsegmentIdx);
-
-  // Tell the SWITCH FROM reader when it should stop reading.
-  fromReader->RequestSwitchAtSubsegment(aSubsegmentIdx, toReader);
-
-  // Tell the SWITCH TO reader to seek to the correct offset.
-  toReader->RequestSeekToSubsegment(aSubsegmentIdx);
-
-  mSwitchVideoReaders = true;
-}
-
-void
-DASHReader::PossiblySwitchVideoReaders()
-{
-  NS_ASSERTION(mDecoder, "Decoder should not be null");
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-
-  // Flag to switch streams is set in |RequestVideoReaderSwitch|.
-  if (!mSwitchVideoReaders) {
-    return;
-  }
-
-  // Only switch if we reached a switch access point.
-  NS_ENSURE_TRUE_VOID(0 <= mSwitchCount);
-  NS_ENSURE_TRUE_VOID((uint32_t)mSwitchCount < mSwitchToVideoSubsegmentIndexes.Length());
-  uint32_t switchIdx = mSwitchToVideoSubsegmentIndexes[mSwitchCount];
-  if (!mVideoReader->HasReachedSubsegment(switchIdx)) {
-    return;
-  }
-
-  // Get Representation index to switch to.
-  DASHDecoder* dashDecoder = static_cast<DASHDecoder*>(mDecoder);
-  int32_t toReaderIdx = dashDecoder->GetRepIdxForVideoSubsegmentLoad(switchIdx);
-  NS_ENSURE_TRUE_VOID(0 <= toReaderIdx);
-  NS_ENSURE_TRUE_VOID((uint32_t)toReaderIdx < mVideoReaders.Length());
-
-  DASHRepReader* fromReader = mVideoReader;
-  DASHRepReader* toReader = mVideoReaders[toReaderIdx];
-  NS_ENSURE_TRUE_VOID(fromReader != toReader);
-
-  LOG("Switching video readers now from [%p] to [%p] at subsegment [%d]: "
-      "mSwitchCount [%d].",
-      fromReader, toReader, switchIdx, mSwitchCount);
-
-  // Switch readers while in the monitor.
-  ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-  mVideoReader = toReader;
-
-  // Prep readers for next switch, also while in monitor.
-  if ((uint32_t)++mSwitchCount < mSwitchToVideoSubsegmentIndexes.Length()) {
-    // Get the subsegment at which to switch.
-    switchIdx = mSwitchToVideoSubsegmentIndexes[mSwitchCount];
-
-    // Update from and to reader ptrs for next switch.
-    fromReader = toReader;
-    toReaderIdx = dashDecoder->GetRepIdxForVideoSubsegmentLoad(switchIdx);
-    toReader = mVideoReaders[toReaderIdx];
-    NS_ENSURE_TRUE_VOID((uint32_t)toReaderIdx < mVideoReaders.Length());
-    NS_ENSURE_TRUE_VOID(fromReader != toReader);
-
-    // Tell the SWITCH FROM reader when it should stop reading.
-    fromReader->RequestSwitchAtSubsegment(switchIdx, toReader);
-
-    // Tell the SWITCH TO reader to seek to the correct offset.
-    toReader->RequestSeekToSubsegment(switchIdx);
-  } else {
-    // If there are no more pending switches, unset the switch readers flag.
-    mSwitchVideoReaders = false;
-  }
-}
-
-void
-DASHReader::PrepareToDecode()
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-
-  // Flag to switch streams is set by |DASHDecoder|.
-  if (!mSwitchVideoReaders) {
-    return;
-  }
-
-  PossiblySwitchVideoReaders();
-
-  // Prepare each sub reader for decoding: includes seeking to the correct
-  // offset if a seek was previously requested.
-  for (uint32_t i = 0; i < mVideoReaders.Length(); i++) {
-    mVideoReaders[i]->PrepareToDecode();
-  }
-}
-
-DASHRepReader*
-DASHReader::GetReaderForSubsegment(uint32_t aSubsegmentIdx)
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  DASHDecoder* dashDecoder = static_cast<DASHDecoder*>(mDecoder);
-  int32_t repIdx =
-    dashDecoder->GetRepIdxForVideoSubsegmentLoadAfterSeek((int32_t)aSubsegmentIdx);
-  if (0 <= repIdx && repIdx < mVideoReaders.Length()) {
-    return mVideoReaders[repIdx];
-  } else {
-    return nullptr;
-  }
-}
-
-
-} // namespace mozilla
deleted file mode 100644
--- a/content/media/dash/DASHReader.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * see DASHDecoder.cpp for comments on DASH object interaction
- */
-
-#if !defined(DASHReader_h_)
-#define DASHReader_h_
-
-#include "VideoUtils.h"
-#include "MediaDecoderReader.h"
-#include "DASHRepReader.h"
-
-namespace mozilla {
-
-class DASHRepReader;
-
-class DASHReader : public MediaDecoderReader
-{
-public:
-  DASHReader(AbstractMediaDecoder* aDecoder);
-  ~DASHReader();
-  nsresult ResetDecode() MOZ_OVERRIDE;
-
-  // Adds a pointer to a audio/video reader for a media |Representation|.
-  // Called on the main thread only.
-  void AddAudioReader(DASHRepReader* aAudioReader);
-  void AddVideoReader(DASHRepReader* aVideoReader);
-
-  // Waits for metadata bytes to be downloaded, then reads and parses them.
-  // Called on the decode thread only.
-  nsresult ReadMetadata(MediaInfo* aInfo,
-                        MetadataTags** aTags) MOZ_OVERRIDE;
-
-  // Waits for |ReadyToReadMetadata| or |NotifyDecoderShuttingDown|
-  // notification, whichever comes first. Ensures no attempt to read metadata
-  // during |DASHDecoder|::|Shutdown|. Called on decode thread only.
-  nsresult WaitForMetadata() {
-    NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-    ReentrantMonitorAutoEnter mon(mReadMetadataMonitor);
-    while (true) {
-      // Abort if the decoder has started shutting down.
-      if (mDecoderIsShuttingDown) {
-        return NS_ERROR_ABORT;
-      } else if (mReadyToReadMetadata) {
-        break;
-      }
-      mon.Wait();
-    }
-    return NS_OK;
-  }
-
-  // Called on the main thread by |DASHDecoder| to notify that metadata bytes
-  // have been downloaded.
-  void ReadyToReadMetadata() {
-    NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-    ReentrantMonitorAutoEnter mon(mReadMetadataMonitor);
-    mReadyToReadMetadata = true;
-    mon.NotifyAll();
-  }
-
-  // Called on the main thread by |DASHDecoder| when it starts Shutdown. Will
-  // wake metadata monitor if waiting for a silent return from |ReadMetadata|.
-  void NotifyDecoderShuttingDown() {
-    NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-    ReentrantMonitorAutoEnter metadataMon(mReadMetadataMonitor);
-    mDecoderIsShuttingDown = true;
-    // Notify |ReadMetadata| of the shutdown if it's waiting.
-    metadataMon.NotifyAll();
-  }
-
-  // Audio/video status are dependent on the presence of audio/video readers.
-  // Call on decode thread only.
-  bool HasAudio() MOZ_OVERRIDE;
-  bool HasVideo() MOZ_OVERRIDE;
-
-  // Returns references to the audio/video queues of sub-readers. Called on
-  // decode, state machine and audio threads.
-  MediaQueue<AudioData>& AudioQueue() MOZ_OVERRIDE;
-  MediaQueue<VideoData>& VideoQueue() MOZ_OVERRIDE;
-
-  // Called from MediaDecoderStateMachine on the main thread.
-  nsresult Init(MediaDecoderReader* aCloneDonor) MOZ_OVERRIDE;
-
-  // Used by |MediaMemoryReporter|.
-  int64_t VideoQueueMemoryInUse() MOZ_OVERRIDE;
-  int64_t AudioQueueMemoryInUse() MOZ_OVERRIDE;
-
-  // Called on the decode thread, at the start of the decode loop, before
-  // |DecodeVideoFrame|.  Carries out video reader switch if previously
-  // requested, and tells sub-readers to |PrepareToDecode|.
-  void PrepareToDecode() MOZ_OVERRIDE;
-
-  // Called on the decode thread.
-  bool DecodeVideoFrame(bool &aKeyframeSkip, int64_t aTimeThreshold) MOZ_OVERRIDE;
-  bool DecodeAudioData() MOZ_OVERRIDE;
-
-  // Converts seek time to byte offset. Called on the decode thread only.
-  nsresult Seek(int64_t aTime,
-                int64_t aStartTime,
-                int64_t aEndTime,
-                int64_t aCurrentTime) MOZ_OVERRIDE;
-
-  // Called by state machine on multiple threads.
-  nsresult GetBuffered(mozilla::dom::TimeRanges* aBuffered, int64_t aStartTime) MOZ_OVERRIDE;
-
-  // Called on the state machine or decode threads.
-  VideoData* FindStartTime(int64_t& aOutStartTime) MOZ_OVERRIDE;
-
-  // Prepares for an upcoming switch of video readers. Called by
-  // |DASHDecoder| when it has switched download streams. Sets the index of
-  // the reader to switch TO and the index of the subsegment to switch AT
-  // (start offset). (Note: Subsegment boundaries are switch access points for
-  // DASH-WebM). Called on the main thread. Must be in the decode monitor.
-  void RequestVideoReaderSwitch(uint32_t aFromReaderIdx,
-                                uint32_t aToReaderIdx,
-                                uint32_t aSubsegmentIdx);
-
-  // Returns a pointer to the reader which should be used for the specified
-  // subsegment. Called on the decode thread only.
-  DASHRepReader* GetReaderForSubsegment(uint32_t aSubsegmentIdx);
-
-private:
-  // Switches video subreaders if a stream-switch flag has been set, and the
-  // current reader has read up to the switching subsegment (start offset).
-  // Called on the decode thread only.
-  void PossiblySwitchVideoReaders();
-
-  // Monitor and booleans used to wait for metadata bytes to be downloaded, and
-  // skip reading metadata if |DASHDecoder|'s shutdown is in progress.
-  ReentrantMonitor mReadMetadataMonitor;
-  bool mReadyToReadMetadata;
-  bool mDecoderIsShuttingDown;
-
-  // Wrapper class protecting accesses to sub-readers. Asserts that the
-  // decoder monitor has been entered for write access on all threads and read
-  // access on all threads that are not the decode thread. Read access on the
-  // decode thread does not need to be protected.
-  class MonitoredSubReader
-  {
-  public:
-    // Main constructor takes a pointer to the owning |DASHReader| to verify
-    // correct entry into the decoder's |ReentrantMonitor|.
-    MonitoredSubReader(DASHReader* aReader) :
-      mReader(aReader),
-      mSubReader(nullptr)
-    {
-      MOZ_COUNT_CTOR(DASHReader::MonitoredSubReader);
-      NS_ASSERTION(mReader, "Reader is null!");
-    }
-    // Note: |mSubReader|'s refcount will be decremented in this destructor.
-    ~MonitoredSubReader()
-    {
-      MOZ_COUNT_DTOR(DASHReader::MonitoredSubReader);
-    }
-
-    // Override '=' to always assert thread is "in monitor" for writes/changes
-    // to |mSubReader|.
-    MonitoredSubReader& operator=(DASHRepReader* rhs)
-    {
-      NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
-      mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
-      mSubReader = rhs;
-      return *this;
-    }
-
-    // Override '*' to assert threads other than the decode thread are "in
-    // monitor" for ptr reads.
-    operator DASHRepReader*() const
-    {
-      NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
-      if (!mReader->GetDecoder()->OnDecodeThread()) {
-        mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
-      }
-      return mSubReader;
-    }
-
-    // Override '->' to assert threads other than the decode thread are "in
-    // monitor" for |mSubReader| function calls.
-    DASHRepReader* operator->() const
-    {
-      return *this;
-    }
-  private:
-    // Pointer to |DASHReader| object which owns this |MonitoredSubReader|.
-    DASHReader* mReader;
-    // Ref ptr to the sub reader.
-    nsRefPtr<DASHRepReader> mSubReader;
-  };
-
-  // Wrapped ref ptrs to current sub-readers of individual media
-  // |Representation|s. Decoder monitor must be entered for write access on all
-  // threads and read access on all threads that are not the decode thread.
-  // Read access on the decode thread does not need to be protected.
-  // Note: |MonitoredSubReader| class will assert correct monitor use.
-  MonitoredSubReader mAudioReader;
-  MonitoredSubReader mVideoReader;
-
-  // Wrapper class protecting accesses to sub-reader list. Asserts that the
-  // decoder monitor has been entered for write access on all threads and read
-  // access on all threads that are not the decode thread. Read access on the
-  // decode thread does not need to be protected.
-  // Note: Elems accessed via operator[] are not protected with monitor
-  // assertion checks once obtained.
-  class MonitoredSubReaderList
-  {
-  public:
-    // Main constructor takes a pointer to the owning |DASHReader| to verify
-    // correct entry into the decoder's |ReentrantMonitor|.
-    MonitoredSubReaderList(DASHReader* aReader) :
-      mReader(aReader)
-    {
-      MOZ_COUNT_CTOR(DASHReader::MonitoredSubReaderList);
-      NS_ASSERTION(mReader, "Reader is null!");
-    }
-    // Note: Elements in |mSubReaderList| will have their refcounts decremented
-    // in this destructor.
-    ~MonitoredSubReaderList()
-    {
-      MOZ_COUNT_DTOR(DASHReader::MonitoredSubReaderList);
-    }
-
-    // Returns Length of |mSubReaderList| array. Will assert threads other than
-    // the decode thread are "in monitor".
-    uint32_t Length() const
-    {
-      NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
-      if (!mReader->GetDecoder()->OnDecodeThread()) {
-        mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
-      }
-      return mSubReaderList.Length();
-    }
-
-    // Returns true if |mSubReaderList| is empty. Will assert that threads
-    // other than the decode thread are "in monitor".
-    bool IsEmpty() const
-    {
-      NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
-      if (!mReader->GetDecoder()->OnDecodeThread()) {
-        mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
-      }
-      return mSubReaderList.IsEmpty();
-    }
-    // Override '[]' to assert threads other than the decode thread are "in
-    // monitor" for accessing individual elems. Note: elems returned do not
-    // have monitor assertions builtin like |MonitoredSubReader| objects.
-    nsRefPtr<DASHRepReader>& operator[](uint32_t i)
-    {
-      NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
-      if (!mReader->GetDecoder()->OnDecodeThread()) {
-        mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
-      }
-      return mSubReaderList[i];
-    }
-
-    // Appends a reader to the end of |mSubReaderList|. Will always assert that
-    // the thread is "in monitor".
-    void
-    AppendElement(DASHRepReader* aReader)
-    {
-      NS_ASSERTION(mReader->GetDecoder(), "Decoder is null!");
-      mReader->GetDecoder()->GetReentrantMonitor().AssertCurrentThreadIn();
-      mSubReaderList.AppendElement(aReader);
-    }
-  private:
-    // Pointer to |DASHReader| object which owns this |MonitoredSubReader|.
-    DASHReader* mReader;
-    // Ref ptrs to the sub readers.
-    nsTArray<nsRefPtr<DASHRepReader> > mSubReaderList;
-  };
-
-  // Ref ptrs to all sub-readers of individual media |Representation|s.
-  // Decoder monitor must be entered for write access on all threads and read
-  // access on all threads that are not the decode thread. Read acces on the
-  // decode thread does not need to be protected.
-  MonitoredSubReaderList mAudioReaders;
-  MonitoredSubReaderList mVideoReaders;
-
-  // When true, indicates that we should switch reader. Must be in the monitor
-  // for write access and read access off the decode thread.
-  bool mSwitchVideoReaders;
-
-  // Indicates the subsegment index at which the reader should switch. Must be
-  // in the monitor for write access and read access off the decode thread.
-  nsTArray<uint32_t> mSwitchToVideoSubsegmentIndexes;
-
-  // Counts the number of switches that have taken place. Must be in the
-  // monitor for write access and read access off the decode thread.
-  int32_t mSwitchCount;
-};
-
-} // namespace mozilla
-
-#endif
deleted file mode 100644
--- a/content/media/dash/DASHRepDecoder.cpp
+++ /dev/null
@@ -1,517 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * see DASHDecoder.cpp for info on DASH interaction with the media engine.*/
-
-#include "prlog.h"
-#include "VideoUtils.h"
-#include "SegmentBase.h"
-#include "MediaDecoderStateMachine.h"
-#include "DASHReader.h"
-#include "MediaResource.h"
-#include "DASHRepDecoder.h"
-#include "WebMReader.h"
-#include <algorithm>
-
-namespace mozilla {
-
-#ifdef PR_LOGGING
-extern PRLogModuleInfo* gMediaDecoderLog;
-#define LOG(msg, ...) PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, \
-                             ("%p [DASHRepDecoder] " msg, this, __VA_ARGS__))
-#define LOG1(msg) PR_LOG(gMediaDecoderLog, PR_LOG_DEBUG, \
-                         ("%p [DASHRepDecoder] " msg, this))
-#else
-#define LOG(msg, ...)
-#define LOG1(msg)
-#endif
-
-MediaDecoderStateMachine*
-DASHRepDecoder::CreateStateMachine()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  // Do not create; just return current state machine.
-  return mDecoderStateMachine;
-}
-
-nsresult
-DASHRepDecoder::SetStateMachine(MediaDecoderStateMachine* aSM)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  mDecoderStateMachine = aSM;
-  return NS_OK;
-}
-
-void
-DASHRepDecoder::SetResource(MediaResource* aResource)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  mResource = aResource;
-}
-
-void
-DASHRepDecoder::SetMPDRepresentation(Representation const * aRep)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  mMPDRepresentation = aRep;
-}
-
-void
-DASHRepDecoder::SetReader(WebMReader* aReader)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  mReader = aReader;
-}
-
-nsresult
-DASHRepDecoder::Load(nsIStreamListener** aListener,
-                     MediaDecoder* aCloneDonor)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ENSURE_TRUE(mMPDRepresentation, NS_ERROR_NOT_INITIALIZED);
-
-  // Get init range and index range from MPD.
-  SegmentBase const * segmentBase = mMPDRepresentation->GetSegmentBase();
-  NS_ENSURE_TRUE(segmentBase, NS_ERROR_NULL_POINTER);
-
-  // Get and set init range.
-  segmentBase->GetInitRange(&mInitByteRange.mStart, &mInitByteRange.mEnd);
-  NS_ENSURE_TRUE(!mInitByteRange.IsNull(), NS_ERROR_NOT_INITIALIZED);
-  mReader->SetInitByteRange(mInitByteRange);
-
-  // Get and set index range.
-  segmentBase->GetIndexRange(&mIndexByteRange.mStart, &mIndexByteRange.mEnd);
-  NS_ENSURE_TRUE(!mIndexByteRange.IsNull(), NS_ERROR_NOT_INITIALIZED);
-  mReader->SetIndexByteRange(mIndexByteRange);
-
-  // Determine byte range to Open.
-  // For small deltas between init and index ranges, we need to bundle the byte
-  // range requests together in order to deal with |MediaCache|'s control of
-  // seeking (see |MediaCache|::|Update|). |MediaCache| will not initiate a
-  // |ChannelMediaResource|::|CacheClientSeek| for the INDEX byte range if the
-  // delta between it and the INIT byte ranges is less than
-  // |SEEK_VS_READ_THRESHOLD|. To get around this, request all metadata bytes
-  // now so |MediaCache| can assume the bytes are en route.
-  int64_t delta = std::max(mIndexByteRange.mStart, mInitByteRange.mStart)
-                - std::min(mIndexByteRange.mEnd, mInitByteRange.mEnd);
-  MediaByteRange byteRange;
-  if (delta <= SEEK_VS_READ_THRESHOLD) {
-    byteRange.mStart = std::min(mIndexByteRange.mStart, mInitByteRange.mStart);
-    byteRange.mEnd = std::max(mIndexByteRange.mEnd, mInitByteRange.mEnd);
-    // Loading everything in one chunk .
-    mMetadataChunkCount = 1;
-  } else {
-    byteRange = mInitByteRange;
-    // Loading in two chunks: init and index.
-    mMetadataChunkCount = 2;
-  }
-  mCurrentByteRange = byteRange;
-  return mResource->OpenByteRange(nullptr, byteRange);
-}
-
-void
-DASHRepDecoder::NotifyDownloadEnded(nsresult aStatus)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  if (!mMainDecoder) {
-    if (!mShuttingDown) {
-      LOG("Error! Main Decoder is null before shutdown: mMainDecoder [%p] ",
-          mMainDecoder.get());
-      DecodeError();
-    }
-    return;
-  }
-
-  if (NS_SUCCEEDED(aStatus)) {
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    // Decrement counter as metadata chunks are downloaded.
-    // Note: Reader gets next chunk download via |ChannelMediaResource|:|Seek|.
-    if (mMetadataChunkCount > 0) {
-      LOG("Metadata chunk [%d] downloaded: range requested [%lld - %lld] "
-          "subsegmentIdx [%d]",
-          mMetadataChunkCount,
-          mCurrentByteRange.mStart, mCurrentByteRange.mEnd, mSubsegmentIdx);
-      mMetadataChunkCount--;
-    } else {
-      LOG("Byte range downloaded: status [%x] range requested [%lld - %lld] "
-          "subsegmentIdx [%d]",
-          aStatus, mCurrentByteRange.mStart, mCurrentByteRange.mEnd,
-          mSubsegmentIdx);
-      if ((uint32_t)mSubsegmentIdx == mByteRanges.Length()-1) {
-        mResource->NotifyLastByteRange();
-      }
-      // Notify main decoder that a DATA byte range is downloaded.
-      mMainDecoder->NotifyDownloadEnded(this, aStatus, mSubsegmentIdx);
-    }
-  } else if (aStatus == NS_BINDING_ABORTED) {
-    LOG("Media download has been cancelled by the user: aStatus [%x].",
-        aStatus);
-    if (mMainDecoder) {
-      mMainDecoder->LoadAborted();
-    }
-    return;
-  } else if (aStatus != NS_BASE_STREAM_CLOSED) {
-    LOG("Network error trying to download MPD: aStatus [%x].", aStatus);
-    NetworkError();
-  }
-}
-
-void
-DASHRepDecoder::OnReadMetadataCompleted()
-{
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-  // If shutting down, just return silently.
-  if (mShuttingDown) {
-    LOG1("Shutting down! Ignoring OnReadMetadataCompleted().");
-    return;
-  }
-
-  LOG1("Metadata has been read.");
-
-  // Metadata loaded and read for this stream; ok to populate byte ranges.
-  nsresult rv = PopulateByteRanges();
-  if (NS_FAILED(rv) || mByteRanges.IsEmpty()) {
-    LOG("Error populating byte ranges [%x]", rv);
-    DecodeError();
-    return;
-  }
-
-  mMainDecoder->OnReadMetadataCompleted(this);
-}
-
-nsresult
-DASHRepDecoder::PopulateByteRanges()
-{
-  NS_ASSERTION(OnDecodeThread(), "Should be on decode thread.");
-
-  // Should not be called during shutdown.
-  NS_ENSURE_FALSE(mShuttingDown, NS_ERROR_UNEXPECTED);
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  if (!mByteRanges.IsEmpty()) {
-    return NS_OK;
-  }
-  NS_ENSURE_TRUE(mReader, NS_ERROR_NULL_POINTER);
-  LOG1("Populating byte range array.");
-  return mReader->GetSubsegmentByteRanges(mByteRanges);
-}
-
-void
-DASHRepDecoder::LoadNextByteRange()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  NS_ASSERTION(mResource, "Error: resource is reported as null!");
-
-  // Return silently if shutting down.
-  if (mShuttingDown) {
-    LOG1("Shutting down! Ignoring LoadNextByteRange().");
-    return;
-  }
-
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  NS_ASSERTION(mMainDecoder, "Error: main decoder is null!");
-  NS_ASSERTION(mMainDecoder->IsDecoderAllowedToDownloadData(this),
-               "Should not be called on non-active decoders!");
-
-  // Cannot have empty byte ranges.
-  if (mByteRanges.IsEmpty()) {
-    LOG1("Error getting list of subsegment byte ranges.");
-    DecodeError();
-    return;
-  }
-
-  // Get byte range for subsegment.
-  int32_t subsegmentIdx = mMainDecoder->GetSubsegmentIndex(this);
-  NS_ASSERTION(0 <= subsegmentIdx,
-               "Subsegment index should be >= 0 for active decoders");
-  if (subsegmentIdx >= 0 && (uint32_t)subsegmentIdx < mByteRanges.Length()) {
-    mCurrentByteRange = mByteRanges[subsegmentIdx];
-    mSubsegmentIdx = subsegmentIdx;
-  } else {
-    mCurrentByteRange.Clear();
-    mSubsegmentIdx = -1;
-    LOG("End of subsegments: index [%d] out of range.", subsegmentIdx);
-    return;
-  }
-
-  // Request a seek for the first reader. Required so that the reader is
-  // primed to start here, and will block subsequent subsegment seeks unless
-  // the subsegment has been read.
-  if (subsegmentIdx == 0) {
-    ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-    mReader->RequestSeekToSubsegment(0);
-  }
-
-  // Query resource for cached ranges; only download if it's not there.
-  if (IsSubsegmentCached(mSubsegmentIdx)) {
-    LOG("Subsegment [%d] bytes [%lld] to [%lld] already cached. No need to "
-        "download.", mSubsegmentIdx,
-        mCurrentByteRange.mStart, mCurrentByteRange.mEnd);
-    nsCOMPtr<nsIRunnable> event =
-      NS_NewRunnableMethod(this, &DASHRepDecoder::DoNotifyDownloadEnded);
-    nsresult rv = NS_DispatchToMainThread(event);
-    if (NS_FAILED(rv)) {
-      LOG("Error notifying subsegment [%d] cached: rv[0x%x].",
-          mSubsegmentIdx, rv);
-      NetworkError();
-    }
-    return;
-  }
-
-  // Open byte range corresponding to subsegment.
-  nsresult rv = mResource->OpenByteRange(nullptr, mCurrentByteRange);
-  if (NS_FAILED(rv)) {
-    LOG("Error opening byte range [%lld - %lld]: subsegmentIdx [%d] rv [%x].",
-        mCurrentByteRange.mStart, mCurrentByteRange.mEnd, mSubsegmentIdx, rv);
-    NetworkError();
-    return;
-  }
-}
-
-bool
-DASHRepDecoder::IsSubsegmentCached(int32_t aSubsegmentIdx)
-{
-  GetReentrantMonitor().AssertCurrentThreadIn();
-
-  MediaByteRange byteRange = mByteRanges[aSubsegmentIdx];
-  int64_t start = mResource->GetNextCachedData(byteRange.mStart);
-  int64_t end = mResource->GetCachedDataEnd(byteRange.mStart);
-  return (start == byteRange.mStart &&
-          end >= byteRange.mEnd);
-}
-
-void
-DASHRepDecoder::DoNotifyDownloadEnded()
-{
-  NotifyDownloadEnded(NS_OK);
-}
-
-nsresult
-DASHRepDecoder::GetByteRangeForSeek(int64_t const aOffset,
-                                    MediaByteRange& aByteRange)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  // Only check data ranges if they're available and if this decoder is active,
-  // i.e. inactive rep decoders should only load metadata.
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-
-  for (uint32_t i = 0; i < mByteRanges.Length(); i++) {
-    NS_ENSURE_FALSE(mByteRanges[i].IsNull(), NS_ERROR_NOT_INITIALIZED);
-    // Check if |aOffset| lies within the current data range.
-    if (mByteRanges[i].mStart <= aOffset && aOffset <= mByteRanges[i].mEnd) {
-      if (mMainDecoder->IsDecoderAllowedToDownloadSubsegment(this, i)) {
-        mCurrentByteRange = aByteRange = mByteRanges[i];
-        mSubsegmentIdx = i;
-        // XXX Hack: should be setting subsegment outside this function, but
-        // need to review seeking for multiple switches anyhow.
-        mMainDecoder->SetSubsegmentIndex(this, i);
-        LOG("Getting DATA range [%d] for seek offset [%lld]: "
-            "bytes [%lld] to [%lld]",
-            i, aOffset, aByteRange.mStart, aByteRange.mEnd);
-        return NS_OK;
-      }
-      break;
-    }
-  }
-  // Don't allow metadata downloads once they're loaded and byte ranges have
-  // been populated.
-  bool canDownloadMetadata = mByteRanges.IsEmpty();
-  if (canDownloadMetadata) {
-    // Check metadata ranges; init range.
-    if (mInitByteRange.mStart <= aOffset && aOffset <= mInitByteRange.mEnd) {
-      mCurrentByteRange = aByteRange = mInitByteRange;
-      mSubsegmentIdx = 0;
-        LOG("Getting INIT range for seek offset [%lld]: bytes [%lld] to "
-            "[%lld]", aOffset, aByteRange.mStart, aByteRange.mEnd);
-      return NS_OK;
-    }
-    // ... index range.
-    if (mIndexByteRange.mStart <= aOffset && aOffset <= mIndexByteRange.mEnd) {
-      mCurrentByteRange = aByteRange = mIndexByteRange;
-      mSubsegmentIdx = 0;
-      LOG("Getting INDEXES range for seek offset [%lld]: bytes [%lld] to "
-          "[%lld]", aOffset, aByteRange.mStart, aByteRange.mEnd);
-      return NS_OK;
-    }
-  } else {
-    LOG1("Metadata should be read; inhibiting further metadata downloads.");
-  }
-
-  // If no byte range is found by this stage, clear the parameter and return.
-  aByteRange.Clear();
-  if (mByteRanges.IsEmpty() || !canDownloadMetadata) {
-    // Assume mByteRanges will be populated after metadata is read.
-    LOG("Data ranges not populated [%s]; metadata download restricted [%s]: "
-        "offset[%lld].",
-        (mByteRanges.IsEmpty() ? "yes" : "no"),
-        (canDownloadMetadata ? "no" : "yes"), aOffset);
-    return NS_ERROR_NOT_AVAILABLE;
-  } else {
-    // Cannot seek to an unknown offset.
-    // XXX Revisit this for dynamic MPD profiles if MPD is regularly updated.
-    LOG("Error! Offset [%lld] is in an unknown range!", aOffset);
-    return NS_ERROR_ILLEGAL_VALUE;
-  }
-}
-
-void
-DASHRepDecoder::PrepareForSwitch()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  // Ensure that the media cache writes any data held in its partial block.
-  mResource->FlushCache();
-}
-
-void
-DASHRepDecoder::NetworkError()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  if (mMainDecoder) { mMainDecoder->NetworkError(); }
-}
-
-void
-DASHRepDecoder::SetDuration(double aDuration)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  if (mMainDecoder) { mMainDecoder->SetDuration(aDuration); }
-}
-
-void
-DASHRepDecoder::SetInfinite(bool aInfinite)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  if (mMainDecoder) { mMainDecoder->SetInfinite(aInfinite); }
-}
-
-void
-DASHRepDecoder::SetMediaSeekable(bool aMediaSeekable)
-{
-  NS_ASSERTION(NS_IsMainThread() || OnDecodeThread(),
-               "Should be on main thread or decode thread.");
-  if (mMainDecoder) { mMainDecoder->SetMediaSeekable(aMediaSeekable); }
-}
-
-void
-DASHRepDecoder::Progress(bool aTimer)
-{
-  if (mMainDecoder) { mMainDecoder->Progress(aTimer); }
-}
-
-void
-DASHRepDecoder::NotifyDataArrived(const char* aBuffer,
-                                  uint32_t aLength,
-                                  int64_t aOffset)
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-
-  LOG("Data bytes [%lld - %lld] arrived via buffer [%p].",
-      aOffset, aOffset+aLength, aBuffer);
-  // Notify reader directly, since call to |MediaDecoderStateMachine|::
-  // |NotifyDataArrived| will go to |DASHReader|::|NotifyDataArrived|, which
-  // has no way to forward the notification to the correct sub-reader.
-  if (mReader) {
-    mReader->NotifyDataArrived(aBuffer, aLength, aOffset);
-  }
-  // Forward to main decoder which will notify state machine.
-  if (mMainDecoder) {
-    mMainDecoder->NotifyDataArrived(aBuffer, aLength, aOffset);
-  }
-}
-
-void
-DASHRepDecoder::NotifyBytesDownloaded()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  if (mMainDecoder) { mMainDecoder->NotifyBytesDownloaded(); }
-}
-
-void
-DASHRepDecoder::NotifySuspendedStatusChanged()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-  if (mMainDecoder) { mMainDecoder->NotifySuspendedStatusChanged(); }
-}
-
-bool
-DASHRepDecoder::OnStateMachineThread() const
-{
-  return (mMainDecoder ? mMainDecoder->OnStateMachineThread() : false);
-}
-
-bool
-DASHRepDecoder::OnDecodeThread() const
-{
-  return (mMainDecoder ? mMainDecoder->OnDecodeThread() : false);
-}
-
-ReentrantMonitor&
-DASHRepDecoder::GetReentrantMonitor()
-{
-  NS_ASSERTION(mMainDecoder, "Can't get monitor if main decoder is null!");
-  if (mMainDecoder) {
-    return mMainDecoder->GetReentrantMonitor();
-  } else {
-    // XXX If mMainDecoder is gone, most likely we're past shutdown and
-    // a waiting function has been wakened. Just return this decoder's own
-    // monitor and let the function complete.
-    return MediaDecoder::GetReentrantMonitor();
-  }
-}
-
-mozilla::layers::ImageContainer*
-DASHRepDecoder::GetImageContainer()
-{
-  return (mMainDecoder ? mMainDecoder->GetImageContainer() : nullptr);
-}
-
-void
-DASHRepDecoder::DecodeError()
-{
-  if (NS_IsMainThread()) {
-    MediaDecoder::DecodeError();
-  } else {
-    nsCOMPtr<nsIRunnable> event =
-      NS_NewRunnableMethod(this, &MediaDecoder::DecodeError);
-    nsresult rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
-    if (NS_FAILED(rv)) {
-      LOG("Error dispatching DecodeError event to main thread: rv[%x]", rv);
-    }
-  }
-}
-
-void
-DASHRepDecoder::ReleaseStateMachine()
-{
-  NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
-
-  // Since state machine owns mReader, remove reference to it.
-  mReader = nullptr;
-
-  MediaDecoder::ReleaseStateMachine();
-}
-
-void DASHRepDecoder::StopProgressUpdates()
-{
-  NS_ENSURE_TRUE_VOID(mMainDecoder);
-  MediaDecoder::StopProgressUpdates();
-}
-
-void DASHRepDecoder::StartProgressUpdates()
-{
-  NS_ENSURE_TRUE_VOID(mMainDecoder);
-  MediaDecoder::StartProgressUpdates();
-}
-
-} // namespace mozilla
deleted file mode 100644
--- a/content/media/dash/DASHRepDecoder.h
+++ /dev/null
@@ -1,237 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * see DASHDecoder.cpp for info on DASH interaction with the media engine.*/
-
-#if !defined(DASHRepDecoder_h_)
-#define DASHRepDecoder_h_
-
-#include "Representation.h"
-#include "DASHDecoder.h"
-#include "WebMDecoder.h"
-#include "WebMReader.h"
-#include "MediaDecoder.h"
-
-namespace mozilla {
-
-namespace layers {
-class ImageContainer;
-}
-
-class DASHDecoder;
-class DASHRepReader;
-
-class DASHRepDecoder : public MediaDecoder
-{
-public:
-  typedef mozilla::net::Representation Representation;
-  typedef mozilla::net::SegmentBase SegmentBase;
-  typedef mozilla::layers::ImageContainer ImageContainer;
-
-  // Constructor takes a ptr to the main decoder.
-  DASHRepDecoder(DASHDecoder* aMainDecoder) :
-    mMainDecoder(aMainDecoder),
-    mMPDRepresentation(nullptr),
-    mMetadataChunkCount(0),
-    mCurrentByteRange(),
-    mSubsegmentIdx(-1),
-    mReader(nullptr)
-  {
-    MOZ_COUNT_CTOR(DASHRepDecoder);
-  }
-
-  ~DASHRepDecoder()
-  {
-    MOZ_COUNT_DTOR(DASHRepDecoder);
-  }
-
-  // Clone not supported; just return nullptr.
-  virtual MediaDecoder* Clone() { return nullptr; }
-
-  // Called by the main decoder at creation time; points to the main state
-  // machine managed by the main decoder. Called on the main thread only.
-  nsresult SetStateMachine(MediaDecoderStateMachine* aSM);
-
-private:
-  // Overridden to return the ptr set by SetStateMachine. Called on the main
-  // thread only.
-  MediaDecoderStateMachine* CreateStateMachine();
-
-public:
-  // Called by DASHDecoder at creation time; points to the media resource
-  // for this decoder's |Representation|. Called on the main thread only.
-  void SetResource(MediaResource* aResource);
-
-  // Sets the |Representation| object for this decoder. Called on the main
-  // thread.
-  void SetMPDRepresentation(Representation const * aRep);
-
-  // Called from DASHDecoder on main thread; Starts media stream download.
-  virtual nsresult Load(nsIStreamListener** aListener = nullptr,
-                        MediaDecoder* aCloneDonor = nullptr) MOZ_OVERRIDE;
-
-  // Loads the next byte range (or first one on first call). Called on the main
-  // thread only.
-  void LoadNextByteRange();
-
-  // Returns true if the subsegment is already in the media cache.
-  bool IsSubsegmentCached(int32_t aSubsegmentIdx);
-
-  // Calls from DASHRepDecoder. Called on the main thread only.
-  void SetReader(WebMReader* aReader);
-
-  // Called if the media file encounters a network error. Call on the main
-  // thread only.
-  void NetworkError();
-
-  // Called from reader during ReadMetadata. This should be ignored here, and
-  // instead, duration should be set following MPD parsing.
-  void SetMediaDuration(int64_t aDuration) MOZ_OVERRIDE { };
-
-  // Set the duration of the media resource in units of seconds.
-  // This is called via a channel listener if it can pick up the duration
-  // from a content header. Must be called from the main thread only.
-  virtual void SetDuration(double aDuration);
-
-  // Set media stream as infinite. Called on the main thread only.
-  void SetInfinite(bool aInfinite);
-
-  // Sets media stream as seekable. Called on main thread only.
-  void SetMediaSeekable(bool aSeekable);
-
-  // Fire progress events if needed according to the time and byte
-  // constraints outlined in the specification. aTimer is true
-  // if the method is called as a result of the progress timer rather
-  // than the result of downloaded data.
-  void Progress(bool aTimer);
-
-  // Called as data arrives on the stream and is read into the cache.  Called
-  // on the main thread only.
-  void NotifyDataArrived(const char* aBuffer,
-                         uint32_t aLength,
-                         int64_t aOffset);
-
-  // Called by MediaResource when some data has been received.
-  // Call on the main thread only.
-  void NotifyBytesDownloaded();
-
-  // Notify that a byte range request has been completed by the media resource.
-  // Called on the main thread only.
-  void NotifyDownloadEnded(nsresult aStatus);
-
-  // Called asynchronously by |LoadNextByteRange| if the data is already in the
-  // media cache. This will call NotifyDownloadEnded on the main thread with
-  // |aStatus| of NS_OK.
-  void DoNotifyDownloadEnded();
-
-  // Called by MediaResource when the "cache suspended" status changes.
-  // If MediaResource::IsSuspendedByCache returns true, then the decoder
-  // should stop buffering or otherwise waiting for download progress and
-  // start consuming data, if possible, because the cache is full.
-  void NotifySuspendedStatusChanged();
-
-  // Increments the parsed and decoded frame counters by the passed in counts.
-  // Can be called on any thread.
-  void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_OVERRIDE {
-    if (mMainDecoder) {mMainDecoder->NotifyDecodedFrames(aParsed, aDecoded); }
-  }
-
-  // Gets a byte range containing the byte offset. Call on main thread only.
-  nsresult GetByteRangeForSeek(int64_t const aOffset,
-                               MediaByteRange& aByteRange);
-
-  // Gets the number of data byte ranges (not inc. metadata).
-  uint32_t GetNumDataByteRanges() {
-    return mByteRanges.Length();
-  }
-
-  // Notify that a switch is about to happen. Called on the main thread.
-  void PrepareForSwitch();
-
-  // Returns true if the current thread is the state machine thread.
-  bool OnStateMachineThread() const MOZ_OVERRIDE;
-
-  // Returns true if the current thread is the decode thread.
-  bool OnDecodeThread() const MOZ_OVERRIDE;
-
-  // Returns main decoder's monitor for synchronised access.
-  ReentrantMonitor& GetReentrantMonitor() MOZ_OVERRIDE;
-
-  // Called on the decode thread from WebMReader.
-  ImageContainer* GetImageContainer() MOZ_OVERRIDE;
-
-  // Called when Metadata has been read; notifies that index data is read.
-  // Called on the decode thread only.
-  void OnReadMetadataCompleted() MOZ_OVERRIDE;
-
-  // Stop updating the bytes downloaded for progress notifications. Called
-  // when seeking to prevent wild changes to the progress notification.
-  // Must be called with the decoder monitor held.
-  void StopProgressUpdates() MOZ_OVERRIDE;
-
-  // Allow updating the bytes downloaded for progress notifications. Must
-  // be called with the decoder monitor held.
-  void StartProgressUpdates() MOZ_OVERRIDE;
-
-  // Overridden to cleanup ref to |DASHDecoder|. Called on main thread only.
-  void Shutdown() {
-    NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
-    // Remove ref to state machine before |MediaDecoder|::|Shutdown|, since
-    // |DASHDecoder| is responsible for its shutdown.
-    mDecoderStateMachine = nullptr;
-    // Call parent class shutdown.
-    MediaDecoder::Shutdown();
-    NS_ENSURE_TRUE_VOID(mShuttingDown);
-    // Cleanup ref to main decoder.
-    mMainDecoder = nullptr;
-  }
-
-  // Drop reference to state machine and mReader (owned by state machine).
-  // Only called during shutdown dance.
-  void ReleaseStateMachine();
-
-  // Notifies the element that decoding has failed.
-  void DecodeError();
-
-private:
-  // Populates |mByteRanges| by calling |GetIndexByteRanges| from |mReader|.
-  // Called on the main thread only.
-  nsresult PopulateByteRanges();
-
-  // The main decoder.
-  nsRefPtr<DASHDecoder> mMainDecoder;
-  // This decoder's MPD |Representation| object.
-  Representation const * mMPDRepresentation;
-
-  // Countdown var for loading metadata byte ranges.
-  uint16_t        mMetadataChunkCount;
-
-  // All the byte ranges for this |Representation|.
-  nsTArray<MediaByteRange> mByteRanges;
-
-  // Byte range for the init and index bytes.
-  MediaByteRange  mInitByteRange;
-  MediaByteRange  mIndexByteRange;
-
-  // The current byte range being requested.
-  MediaByteRange  mCurrentByteRange;
-  // Index of the current byte range. Initialized to -1.
-  int32_t         mSubsegmentIdx;
-
-  // Ptr to the reader object for this |Representation|. Owned by state
-  // machine.
-  DASHRepReader* mReader;
-};
-
-} // namespace mozilla
-
-#endif //DASHRepDecoder_h_
deleted file mode 100644
--- a/content/media/dash/DASHRepReader.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-
-/* 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/. */
-
-/* DASH - Dynamic Adaptive Streaming over HTTP
- *
- * DASH is an adaptive bitrate streaming technology where a multimedia file is
- * partitioned into one or more segments and delivered to a client using HTTP.
- *
- * see DASHDecoder.cpp for comments on DASH object interaction
- */
-
-#if !defined(DASHRepReader_h_)
-#define DASHRepReader_h_
-
-#include "VideoUtils.h"
-#include "MediaDecoderReader.h"
-#include "DASHReader.h"
-
-namespace mozilla {
-
-class DASHReader;
-
-class DASHRepReader : public MediaDecoderReader
-{
-public:
-  DASHRepReader(AbstractMediaDecoder* aDecoder)
-    : MediaDecoderReader(aDecoder) { }
-  virtual ~DASHRepReader() { }
-
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(DASHRepReader)
-
-  virtual void SetMainReader(DASHReader *aMainReader) = 0;
-
-  // Sets range for initialization bytes; used by DASH.
-  virtual void SetInitByteRange(MediaByteRange &aByteRange) = 0;
-
-  // Sets range for index frame bytes; used by DASH.
-  virtual void SetIndexByteRange(MediaByteRange &aByteRange) = 0;
-
-  // Returns the index of the subsegment which contains the seek time (usecs).
-  virtual int64_t GetSubsegmentForSeekTime(int64_t aSeekToTime) = 0;
-
-  // Returns list of ranges for index frame start/end offsets. Used by DASH.
-  virtual nsresult GetSubsegmentByteRanges(nsTArray<MediaByteRange>& aByteRanges) = 0;
-
-  // Returns true if the reader has reached a DASH switch access point.
-  virtual bool HasReachedSubsegment(uint32_t aSubsegmentIndex) = 0;
-
-  // Requests a seek to the start of a particular DASH subsegment.
-  virtual void RequestSeekToSubsegment(uint32_t aIdx) = 0;
-
-  // Reader should stop reading at the start of the specified subsegment, and
-  // should prepare for the next reader to add data to the video queue.
-  // Should be implemented by a sub-reader, e.g. |nsDASHWebMReader|.
-  virtual void RequestSwitchAtSubsegment(int32_t aCluster,
-                                         MediaDecoderReader* aNextReader) = 0;
-
-  // Returns true if data at the end of the final subsegment has been cached.
-  virtual bool IsDataCachedAtEndOfSubsegments() = 0;
-};
-
-}// namespace mozilla
-
-#endif /*DASHRepReader*/
deleted file mode 100644
--- a/content/media/dash/Makefile.in
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- Mode: makefile; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- #
-# vim: set ts=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/.
-#
-# Contributor(s):
-#     Steve Workman <sworkman@mozilla.com>
-
-include $(topsrcdir)/config/rules.mk
-
-LOCAL_INCLUDES := \
-  -I$(topsrcdir)/netwerk/dash/mpd \
-  -I$(srcdir)/../webm \
-  -I$(srcdir)/../../base/src \
-  -I$(srcdir)/../../html/content/src \
-  $(MOZ_LIBVPX_INCLUDES) \
-  $(NULL)
deleted file mode 100644
--- a/content/media/dash/moz.build
+++ /dev/null
@@ -1,25 +0,0 @@
-# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
-# 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/.
-
-MODULE = 'content'
-
-EXPORTS += [
-    'DASHDecoder.h',
-    'DASHReader.h',
-    'DASHRepDecoder.h',
-    'DASHRepReader.h',
-]
-
-SOURCES += [
-    'DASHDecoder.cpp',
-    'DASHReader.cpp',
-    'DASHRepDecoder.cpp',
-]
-
-LIBRARY_NAME = 'gkcondash_s'
-
-LIBXUL_LIBRARY = True
-
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -21,19 +21,16 @@ if CONFIG['MOZ_WAVE']:
     PARALLEL_DIRS += ['wave']
 
 if CONFIG['MOZ_WEBM']:
     PARALLEL_DIRS += ['webm']
 
 if CONFIG['MOZ_GSTREAMER']:
     PARALLEL_DIRS += ['gstreamer']
 
-if CONFIG['MOZ_DASH']:
-    PARALLEL_DIRS += ['dash']
-
 if CONFIG['MOZ_DIRECTSHOW']:
     PARALLEL_DIRS += ['directshow']
 
 if CONFIG['MOZ_MEDIA_PLUGINS']:
     PARALLEL_DIRS += ['plugins']
 
 if CONFIG['MOZ_WMF']:
     PARALLEL_DIRS += ['wmf']
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -376,36 +376,16 @@ MOCHITEST_FILES += \
 		test_can_play_type_webm.html \
 		$(NULL)
 else
 MOCHITEST_FILES += \
 		test_can_play_type_no_webm.html \
 		$(NULL)
 endif
 
-ifdef MOZ_DASH
-MOCHITEST_FILES += \
-    test_can_play_type_dash.html \
-    dash/dash-manifest.mpd \
-    dash/dash-manifest-sjs.mpd \
-    test_dash_detect_stream_switch.html \
-    dash_detect_stream_switch.sjs \
-    dash/dash-webm-video-320x180.webm \
-    dash/dash-webm-video-428x240.webm \
-    dash/dash-webm-audio-128k.webm \
-    dash/dash-manifest-garbled.mpd \
-    dash/dash-manifest-garbled-webm.mpd \
-    dash/garbled.webm \
-    $(NULL)
-else
-MOCHITEST_FILES += \
-    test_can_play_type_no_dash.html \
-    $(NULL)
-endif
-
 ifdef MOZ_WAVE
 MOCHITEST_FILES += \
 		test_can_play_type_wave.html \
 		$(NULL)
 
 
 # Bug 759221
 MOCHITEST_FILES += \
deleted file mode 100644
--- a/content/media/test/test_can_play_type_dash.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=792935
--->
-<head>
-  <title>Test for Bug 792935: DASH: Add DASH-WebM cases to mochitests</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="text/javascript" src="manifest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=792935">Mozilla Bug 792935: DASH: Add DASH-WebM cases to mochitests</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-
-<video id="v"></video>
-
-<pre id="test">
-<script src="can_play_type_dash.js"></script>
-<script>
-var enabledByPref = SpecialPowers.getBoolPref("media.dash.enabled");
-check_dash(document.getElementById('v'), enabledByPref);
-mediaTestCleanup();
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/content/media/test/test_can_play_type_no_dash.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=792935
--->
-<head>
-  <title>Test for Bug 792935: DASH: Add DASH-WebM cases to mochitests</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="text/javascript" src="manifest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=792935">Mozilla Bug 792935: DASH: Add DASH-WebM cases to mochitests</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-
-<video id="v"></video>
-
-<pre id="test">
-<script src="can_play_type_dash.js"></script>
-<script>
-check_dash(document.getElementById('v'), false);
-mediaTestCleanup();
-</script>
-</pre>
-</body>
-</html>
deleted file mode 100644
--- a/content/media/test/test_dash_detect_stream_switch.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=792935
--->
-<head>
-  <title>Test for Bug 792935 - DASH Stream Switching</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="manifest.js"></script>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=792935">Mozilla Bug 792935</a>
-  
-</div>
-<pre id="test">
-<script type="text/javascript">
-
-var manager = new MediaTestManager;
-
-function createTestArray() {
-  var tests = [];
-  var tmpVid = document.createElement("video");
-
-  for (var testNum=0; testNum<gStreamSwitchTests.length; testNum++) {
-    var test = gStreamSwitchTests[testNum];
-    if (!tmpVid.canPlayType(test.type)) {
-      continue;
-    }
-    tests.push(test);
-  }
-  return tests;
-}
-
-function ended(evt) {
-  var v = evt.target;
-  if (v.parentNode) {
-    v.parentNode.removeChild(v);
-  }
-  ok(true, "Fully played DASH video implies correct byte ranges downloaded.");
-  dump("STREAM-SWITCH-TEST: Finished " + v._name + "\n");
-  manager.finished(v.token);
-}
-
-function error(evt) {
-  var v = evt.target;
-  ok(false, "Error suggests wrong byte range requested for " + v._name);
-}
-
-function startTest(test, token) {
-  var v = document.createElement('video');
-  manager.started(token);
-  v.type = test.type;
-  v.src = test.name;
-  v._name = test.name + " stream switch test";
-  v.token = token;
-  v.autoplay = true;
-
-  v.addEventListener("error", error, false);
-  v.addEventListener("ended", ended, false);
-
-  dump("STREAM-SWITCH-TEST: Started " + name + "\n");
-  document.body.appendChild(v);
-}
-
-var testArray = createTestArray();
-if (testArray && testArray.length > 0) {
-  manager.runTests(testArray, startTest);
-} else {
-  var v = document.createElement('video');
-  var canPlay = v.canPlayType("application/dash+xml");
-  // If the test array is empty even though DASH is enabled, the test should
-  // fail, i.e. canPlay should be false when testArray is empty.
-  todo(canPlay, "No types supported - DASH " +
-                (canPlay ? "enabled" : "disabled"));
-}  
-
-</script>
-</pre>
-</body>
-</html>
--- a/content/media/webm/Makefile.in
+++ b/content/media/webm/Makefile.in
@@ -3,13 +3,8 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 include $(topsrcdir)/config/rules.mk
 
 LOCAL_INCLUDES = \
 		$(MOZ_LIBVPX_CFLAGS) \
 		$(NULL)
 
-ifdef MOZ_DASH
-LOCAL_INCLUDES += \
-  -I$(srcdir)/../dash \
-  $(NULL)
-endif
--- a/content/media/webm/WebMReader.cpp
+++ b/content/media/webm/WebMReader.cpp
@@ -43,19 +43,16 @@ PRLogModuleInfo* gNesteggLog;
 #endif
 #else
 #define LOG(type, msg)
 #define SEEK_LOG(type, msg)
 #endif
 
 static const unsigned NS_PER_USEC = 1000;
 static const double NS_PER_S = 1e9;
-#ifdef MOZ_DASH
-static const double USEC_PER_S = 1e6;
-#endif
 
 // Functions for reading and seeking using MediaResource required for
 // nestegg_io. The 'user data' passed to these functions is the
 // decoder from which the media resource is obtained.
 static int webm_read(void *aBuffer, size_t aLength, void *aUserData)
 {
   NS_ASSERTION(aUserData, "aUserData must point to a valid AbstractMediaDecoder");
   AbstractMediaDecoder* decoder = reinterpret_cast<AbstractMediaDecoder*>(aUserData);
@@ -135,40 +132,26 @@ static void webm_log(nestegg * context,
   PR_vsnprintf(msg+strlen(msg), sizeof(msg)-strlen(msg), format, args);
   PR_LOG(gNesteggLog, PR_LOG_DEBUG, (msg));
 
   va_end(args);
 #endif
 }
 
 WebMReader::WebMReader(AbstractMediaDecoder* aDecoder)
-#ifdef MOZ_DASH
-  : DASHRepReader(aDecoder),
-#else
   : MediaDecoderReader(aDecoder),
-#endif
   mContext(nullptr),
   mPacketCount(0),
   mChannels(0),
   mVideoTrack(0),
   mAudioTrack(0),
   mAudioStartUsec(-1),
   mAudioFrames(0),
   mHasVideo(false),
   mHasAudio(false)
-#ifdef MOZ_DASH
-  , mMainReader(nullptr),
-  mSwitchingCluster(-1),
-  mNextReader(nullptr),
-  mSeekToCluster(-1),
-  mCurrentOffset(-1),
-  mNextCluster(1),
-  mPushVideoPacketToNextReader(false),
-  mReachedSwitchAccessPoint(false)
-#endif
 {
   MOZ_COUNT_CTOR(WebMReader);
 #ifdef PR_LOGGING
   if (!gNesteggLog) {
     gNesteggLog = PR_NewLogModule("Nestegg");
   }
 #endif
   // Zero these member vars to avoid crashes in VP8 destroy and Vorbis clear
@@ -229,59 +212,38 @@ nsresult WebMReader::ResetDecode()
   // Ignore failed results from vorbis_synthesis_restart. They
   // aren't fatal and it fails when ResetDecode is called at a
   // time when no vorbis data has been read.
   vorbis_synthesis_restart(&mVorbisDsp);
 
   mVideoPackets.Reset();
   mAudioPackets.Reset();
 
-#ifdef MOZ_DASH
-  LOG(PR_LOG_DEBUG, ("Resetting DASH seek vars"));
-  mSwitchingCluster = -1;
-  mNextReader = nullptr;
-  mSeekToCluster = -1;
-  mCurrentOffset = -1;
-  mPushVideoPacketToNextReader = false;
-  mReachedSwitchAccessPoint = false;
-#endif
-
   return res;
 }
 
 void WebMReader::Cleanup()
 {
   if (mContext) {
     nestegg_destroy(mContext);
     mContext = nullptr;
   }
 }
 
 nsresult WebMReader::ReadMetadata(MediaInfo* aInfo,
                                   MetadataTags** aTags)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
-#ifdef MOZ_DASH
-  LOG(PR_LOG_DEBUG, ("Reader [%p] for Decoder [%p]: Reading WebM Metadata: "
-                     "init bytes [%d - %d] cues bytes [%d - %d]",
-                     this, mDecoder,
-                     mInitByteRange.mStart, mInitByteRange.mEnd,
-                     mCuesByteRange.mStart, mCuesByteRange.mEnd));
-#endif
   nestegg_io io;
   io.read = webm_read;
   io.seek = webm_seek;
   io.tell = webm_tell;
   io.userdata = mDecoder;
-#ifdef MOZ_DASH
-  int64_t maxOffset = mInitByteRange.IsNull() ? -1 : mInitByteRange.mEnd;
-#else
   int64_t maxOffset = -1;
-#endif
   int r = nestegg_init(&mContext, io, &webm_log, maxOffset);
   if (r == -1) {
     return NS_ERROR_FAILURE;
   }
 
   uint64_t duration = 0;
   r = nestegg_duration(mContext, &duration);
   if (r == 0) {
@@ -419,66 +381,23 @@ nsresult WebMReader::ReadMetadata(MediaI
       }
 
       mInfo.mAudio.mRate = mVorbisDsp.vi->rate;
       mInfo.mAudio.mChannels = mVorbisDsp.vi->channels;
       mChannels = mInfo.mAudio.mChannels;
     }
   }
 
-#ifdef MOZ_DASH
-  // Byte range for cues has been specified; load them.
-  if (!mCuesByteRange.IsNull()) {
-    maxOffset = mCuesByteRange.mEnd;
-
-    // Iterate through cluster ranges until nestegg returns the last one
-    NS_ENSURE_TRUE(mClusterByteRanges.IsEmpty(),
-                   NS_ERROR_ALREADY_INITIALIZED);
-    int clusterNum = 0;
-    bool done = false;
-    uint64_t timestamp;
-    do {
-      mClusterByteRanges.AppendElement();
-      r = nestegg_get_cue_point(mContext, clusterNum, maxOffset,
-                                &(mClusterByteRanges[clusterNum].mStart),
-                                &(mClusterByteRanges[clusterNum].mEnd),
-                                &timestamp);
-      if (r != 0) {
-        Cleanup();
-        return NS_ERROR_FAILURE;
-      }
-      LOG(PR_LOG_DEBUG, ("Reader [%p] for Decoder [%p]: Cluster [%d]: "
-                         "start [%lld] end [%lld], timestamp [%.2llfs]",
-                         this, mDecoder, clusterNum,
-                         mClusterByteRanges[clusterNum].mStart,
-                         mClusterByteRanges[clusterNum].mEnd,
-                         timestamp/NS_PER_S));
-      mClusterByteRanges[clusterNum].mStartTime = timestamp/NS_PER_USEC;
-      // Last cluster will have '-1' as end value
-      if (mClusterByteRanges[clusterNum].mEnd == -1) {
-        mClusterByteRanges[clusterNum].mEnd = (mCuesByteRange.mStart-1);
-        done = true;
-      } else {
-        clusterNum++;
-      }
-    } while (!done);
-  }
-#endif
-
   // We can't seek in buffered regions if we have no cues.
   mDecoder->SetMediaSeekable(nestegg_has_cues(mContext) == 1);
 
   *aInfo = mInfo;
 
   *aTags = nullptr;
 
-#ifdef MOZ_DASH
-  mDecoder->OnReadMetadataCompleted();
-#endif
-
   return NS_OK;
 }
 
 ogg_packet WebMReader::InitOggPacket(unsigned char* aData,
                                        size_t aLength,
                                        bool aBOS,
                                        bool aEOS,
                                        int64_t aGranulepos)
@@ -606,103 +525,16 @@ bool WebMReader::DecodeAudioPacket(neste
       }
     }
   }
 
   return true;
 }
 
 nsReturnRef<NesteggPacketHolder> WebMReader::NextPacket(TrackType aTrackType)
-#ifdef MOZ_DASH
-{
-  nsAutoRef<NesteggPacketHolder> holder;
-  // It is possible that following a seek, a requested switching offset could
-  // be reached before |DASHReader| calls |RequestSwitchAtSubsegment|. In this
-  // case |mNextReader| will be null, so check its value and at every possible
-  // switch access point, i.e. cluster boundary, ask |mMainReader| to
-  // |GetReaderForSubsegment|.
-  if (mMainReader && !mNextReader && aTrackType == VIDEO) {
-    WebMReader* nextReader = nullptr;
-    LOG(PR_LOG_DEBUG,
-      ("WebMReader[%p] for decoder [%p] NextPacket mNextReader not set: "
-       "mCurrentOffset[%lld] nextCluster [%d] comparing with offset[%lld]",
-       this, mDecoder, mCurrentOffset, mNextCluster,
-       mClusterByteRanges[mNextCluster].mStart));
-
-    if (mNextCluster < mClusterByteRanges.Length() &&
-        mCurrentOffset == mClusterByteRanges[mNextCluster].mStart) {
-      DASHRepReader* nextDASHRepReader =
-        mMainReader->GetReaderForSubsegment(mNextCluster);
-      nextReader = static_cast<WebMReader*>(nextDASHRepReader);
-      LOG(PR_LOG_DEBUG,
-          ("WebMReader[%p] for decoder [%p] reached SAP at cluster [%d]: next "
-         "reader is [%p]", this, mDecoder, mNextCluster, nextReader));
-      if (nextReader && nextReader != this) {
-        {
-          ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-          // Ensure this reader is set to switch for the next packet.
-          RequestSwitchAtSubsegment(mNextCluster, nextReader);
-          NS_ASSERTION(mNextReader == nextReader, "mNextReader should be set");
-          // Ensure the next reader seeks to |mNextCluster|. |PrepareToDecode|
-          // must be called to ensure the reader's variables are set correctly.
-          nextReader->RequestSeekToSubsegment(mNextCluster);
-          nextReader->PrepareToDecode();
-        }
-      }
-      // Keep mNextCluster up-to-date with the |mCurrentOffset|.
-      if (mNextCluster+1 < mClusterByteRanges.Length()) {
-        // At least one more cluster to go.
-        mNextCluster++;
-      } else {
-        // Reached last cluster; prepare for being in cluster 0 again.
-        mNextCluster = 1;
-      }
-      LOG(PR_LOG_DEBUG,
-          ("WebMReader [%p] for decoder [%p] updating mNextCluster to [%d] "
-           "at offset [%lld]", this, mDecoder, mNextCluster, mCurrentOffset));
-    }
-  }
-
-  // Get packet from next reader if we're at a switching point; most likely we
-  // did not download the next packet for this reader's stream, so we have to
-  // get it from the next one. Note: Switch to next reader only for video;
-  // audio switching is not supported in the DASH-WebM On Demand profile.
-  if (aTrackType == VIDEO &&
-      (uint32_t)mSwitchingCluster < mClusterByteRanges.Length() &&
-      mCurrentOffset == mClusterByteRanges[mSwitchingCluster].mStart) {
-
-    if (mVideoPackets.GetSize() > 0) {
-      holder = NextPacketInternal(VIDEO);
-      LOG(PR_LOG_DEBUG,
-          ("WebMReader[%p] got packet from mVideoPackets @[%lld]",
-           this, holder->mOffset));
-    } else {
-      mReachedSwitchAccessPoint = true;
-      NS_ASSERTION(mNextReader,
-                   "Stream switch has been requested but mNextReader is null");
-      holder = mNextReader->NextPacket(aTrackType);
-      mPushVideoPacketToNextReader = true;
-      // Reset for possible future switches.
-      mSwitchingCluster = -1;
-      LOG(PR_LOG_DEBUG,
-          ("WebMReader[%p] got packet from mNextReader[%p] @[%lld]",
-           this, mNextReader.get(), (holder ? holder->mOffset : 0)));
-    }
-  } else {
-    holder = NextPacketInternal(aTrackType);
-    if (holder) {
-      mCurrentOffset = holder->mOffset;
-    }
-  }
-  return holder.out();
-}
-
-nsReturnRef<NesteggPacketHolder>
-WebMReader::NextPacketInternal(TrackType aTrackType)
-#endif
 {
   // The packet queue that packets will be pushed on if they
   // are not the type we are interested in.
   WebMPacketQueue& otherPackets =
     aTrackType == VIDEO ? mAudioPackets : mVideoPackets;
 
   // The packet queue for the type that we are interested in.
   WebMPacketQueue &packets =
@@ -923,28 +755,17 @@ bool WebMReader::DecodeVideoFrame(bool &
   }
 
   return true;
 }
 
 void
 WebMReader::PushVideoPacket(NesteggPacketHolder* aItem)
 {
-#ifdef MOZ_DASH
-  if (mPushVideoPacketToNextReader) {
-    NS_ASSERTION(mNextReader,
-                 "Stream switch has been requested but mNextReader is null");
-    mNextReader->mVideoPackets.PushFront(aItem);
-    mPushVideoPacketToNextReader = false;
-  } else {
-#endif
     mVideoPackets.PushFront(aItem);
-#ifdef MOZ_DASH
-  }
-#endif
 }
 
 nsresult WebMReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime,
                             int64_t aCurrentTime)
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
 
   LOG(PR_LOG_DEBUG, ("Reader [%p] for Decoder [%p]: About to seek to %fs",
@@ -952,66 +773,19 @@ nsresult WebMReader::Seek(int64_t aTarge
   if (NS_FAILED(ResetDecode())) {
     return NS_ERROR_FAILURE;
   }
   uint32_t trackToSeek = mHasVideo ? mVideoTrack : mAudioTrack;
   int r = nestegg_track_seek(mContext, trackToSeek, aTarget * NS_PER_USEC);
   if (r != 0) {
     return NS_ERROR_FAILURE;
   }
-#ifdef MOZ_DASH
-  // Find next cluster index;
-  MediaResource* resource = mDecoder->GetResource();
-  int64_t newOffset = resource->Tell();
-  for (uint32_t i = 1; i < mClusterByteRanges.Length(); i++) {
-    if (newOffset < mClusterByteRanges[i].mStart) {
-      mNextCluster = i;
-      LOG(PR_LOG_DEBUG,
-          ("WebMReader [%p] for decoder [%p] updating mNextCluster to [%d] "
-           "after seek to offset [%lld]",
-           this, mDecoder, mNextCluster, resource->Tell()));
-      break;
-    }
-  }
-#endif
   return DecodeToTarget(aTarget);
 }
 
-#ifdef MOZ_DASH
-bool WebMReader::IsDataCachedAtEndOfSubsegments()
-{
-  MediaResource* resource = mDecoder->GetResource();
-  NS_ENSURE_TRUE(resource, false);
-  if (resource->IsDataCachedToEndOfResource(0)) {
-     return true;
-  }
-
-  if (mClusterByteRanges.IsEmpty()) {
-    return false;
-  }
-
-  nsTArray<MediaByteRange> ranges;
-  nsresult rv = resource->GetCachedRanges(ranges);
-  NS_ENSURE_SUCCESS(rv, false);
-  if (ranges.IsEmpty()) {
-    return false;
-  }
-
-  // Return true if data at the end of the final subsegment is cached.
-  uint32_t finalSubsegmentIndex = mClusterByteRanges.Length()-1;
-  uint64_t finalSubEndOffset = mClusterByteRanges[finalSubsegmentIndex].mEnd;
-  uint32_t finalRangeIndex = ranges.Length()-1;
-  uint64_t finalRangeStartOffset = ranges[finalRangeIndex].mStart;
-  uint64_t finalRangeEndOffset = ranges[finalRangeIndex].mEnd;
-
-  return (finalRangeStartOffset < finalSubEndOffset &&
-          finalSubEndOffset <= finalRangeEndOffset);
-}
-#endif
-
 nsresult WebMReader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
 {
   MediaResource* resource = mDecoder->GetResource();
 
   uint64_t timecodeScale;
   if (!mContext || nestegg_tstamp_scale(mContext, &timecodeScale) == -1) {
     return NS_OK;
   }
@@ -1039,39 +813,16 @@ nsresult WebMReader::GetBuffered(dom::Ti
     for (uint32_t index = 0; index < ranges.Length(); index++) {
       uint64_t start, end;
       bool rv = mBufferedState->CalculateBufferedForRange(ranges[index].mStart,
                                                           ranges[index].mEnd,
                                                           &start, &end);
       if (rv) {
         double startTime = start * timecodeScale / NS_PER_S - aStartTime;
         double endTime = end * timecodeScale / NS_PER_S - aStartTime;
-#ifdef MOZ_DASH
-        // If this range extends to the end of a cluster, the true end time is
-        // the cluster's end timestamp. Since WebM frames do not have an end
-        // timestamp, a fully cached cluster must be reported with the correct
-        // end time of its final frame. Otherwise, buffered ranges could be
-        // reported with missing frames at cluster boundaries, specifically
-        // boundaries where stream switching has occurred.
-        if (!mClusterByteRanges.IsEmpty()) {
-          for (uint32_t clusterIndex = 0;
-               clusterIndex < (mClusterByteRanges.Length()-1);
-               clusterIndex++) {
-            if (ranges[index].mEnd >= mClusterByteRanges[clusterIndex].mEnd) {
-              double clusterEndTime =
-                  mClusterByteRanges[clusterIndex+1].mStartTime / USEC_PER_S;
-              if (endTime < clusterEndTime) {
-                LOG(PR_LOG_DEBUG, ("End of cluster: endTime becoming %0.3fs",
-                                   clusterEndTime));
-                endTime = clusterEndTime;
-              }
-            }
-          }
-        }
-#endif
         // If this range extends to the end of the file, the true end time
         // is the file's duration.
         if (resource->IsDataCachedToEndOfResource(ranges[index].mStart)) {
           uint64_t duration = 0;
           if (nestegg_duration(mContext, &duration) == 0) {
             endTime = duration / NS_PER_S;
           }
         }
@@ -1084,141 +835,9 @@ nsresult WebMReader::GetBuffered(dom::Ti
   return NS_OK;
 }
 
 void WebMReader::NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset)
 {
   mBufferedState->NotifyDataArrived(aBuffer, aLength, aOffset);
 }
 
-#ifdef MOZ_DASH
-int64_t
-WebMReader::GetSubsegmentForSeekTime(int64_t aSeekToTime)
-{
-  NS_ENSURE_TRUE(0 <= aSeekToTime, -1);
-  // Check the first n-1 subsegments. End time is the start time of the next
-  // subsegment.
-  for (uint32_t i = 1; i < (mClusterByteRanges.Length()); i++) {
-    if (aSeekToTime < mClusterByteRanges[i].mStartTime) {
-      return i-1;
-    }
-  }
-  // Check the last subsegment. End time is the end time of the file.
-  NS_ASSERTION(mDecoder, "Decoder should not be null!");
-  if (aSeekToTime <= mDecoder->GetMediaDuration()) {
-    return mClusterByteRanges.Length()-1;
-  }
-
-  return (-1);
-}
-nsresult
-WebMReader::GetSubsegmentByteRanges(nsTArray<MediaByteRange>& aByteRanges)
-{
-  NS_ENSURE_TRUE(mContext, NS_ERROR_NULL_POINTER);
-  NS_ENSURE_TRUE(aByteRanges.IsEmpty(), NS_ERROR_ALREADY_INITIALIZED);
-  NS_ENSURE_FALSE(mClusterByteRanges.IsEmpty(), NS_ERROR_NOT_INITIALIZED);
-  NS_ENSURE_FALSE(mCuesByteRange.IsNull(), NS_ERROR_NOT_INITIALIZED);
-
-  for (uint32_t i = 0; i < mClusterByteRanges.Length(); i++) {
-    aByteRanges.AppendElement();
-    aByteRanges[i] = mClusterByteRanges[i];
-  }
-
-  return NS_OK;
-}
-
-void
-WebMReader::RequestSwitchAtSubsegment(int32_t aSubsegmentIdx,
-                                      MediaDecoderReader* aNextReader)
-{
-  NS_ASSERTION(NS_IsMainThread() || mDecoder->OnDecodeThread(),
-               "Should be on main thread or decode thread.");
-  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
-
-  // Only allow one switch at a time; ignore if one is already requested.
-  if (mSwitchingCluster != -1) {
-    return;
-  }
-  NS_ENSURE_TRUE_VOID((uint32_t)aSubsegmentIdx < mClusterByteRanges.Length());
-  mSwitchingCluster = aSubsegmentIdx;
-  NS_ENSURE_TRUE_VOID(aNextReader);
-  NS_ENSURE_TRUE_VOID(aNextReader != this);
-  mNextReader = static_cast<WebMReader*>(aNextReader);
-}
-
-void
-WebMReader::RequestSeekToSubsegment(uint32_t aIdx)
-{
-  NS_ASSERTION(NS_IsMainThread() || mDecoder->OnDecodeThread(),
-               "Should be on main thread or decode thread.");
-  NS_ASSERTION(mDecoder, "decoder should not be null!");
-  mDecoder->GetReentrantMonitor().AssertCurrentThreadIn();
-
-  // Don't seek if we're about to switch to another reader.
-  if (mSwitchingCluster != -1) {
-    return;
-  }
-  // Only allow seeking if a request was not already made.
-  if (mSeekToCluster != -1) {
-    return;
-  }
-  NS_ENSURE_TRUE_VOID(aIdx < mClusterByteRanges.Length());
-  mSeekToCluster = aIdx;
-
-  // XXX Hack to get the resource to seek to the correct offset if the decode
-  // thread is in shutdown, e.g. if the video is not autoplay.
-  if (mDecoder->IsShutdown()) {
-    ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
-    mDecoder->GetResource()->Seek(PR_SEEK_SET,
-                                  mClusterByteRanges[mSeekToCluster].mStart);
-  }
-}
-
-void
-WebMReader::PrepareToDecode()
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  if (mSeekToCluster != -1) {
-    ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor());
-    SeekToCluster(mSeekToCluster);
-  }
-}
-
-void
-WebMReader::SeekToCluster(uint32_t aIdx)
-{
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  NS_ENSURE_TRUE_VOID(aIdx < mClusterByteRanges.Length());
-  LOG(PR_LOG_DEBUG, ("Reader [%p] for Decoder [%p]: seeking to "
-                     "subsegment [%lld] at offset [%lld]",
-                     this, mDecoder, aIdx, mClusterByteRanges[aIdx].mStart));
-  int r = nestegg_offset_seek(mContext, mClusterByteRanges[aIdx].mStart);
-  NS_ENSURE_TRUE_VOID(r == 0);
-  if (aIdx + 1 < mClusterByteRanges.Length()) {
-    mNextCluster = aIdx + 1;
-  } else {
-    mNextCluster = 1;
-  }
-  mSeekToCluster = -1;
-}
-
-bool
-WebMReader::HasReachedSubsegment(uint32_t aSubsegmentIndex)
-{
-  NS_ASSERTION(mDecoder, "Decoder is null.");
-  NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
-  NS_ENSURE_TRUE(aSubsegmentIndex < mClusterByteRanges.Length(), false);
-
-  NS_ASSERTION(mDecoder->GetResource(), "Decoder has no media resource.");
-  if (mReachedSwitchAccessPoint) {
-    LOG(PR_LOG_DEBUG,
-        ("Reader [%p] for Decoder [%p]: reached switching offset [%lld] = "
-         "mClusterByteRanges[%d].mStart[%lld]",
-         this, mDecoder, mCurrentOffset, aSubsegmentIndex,
-         mClusterByteRanges[aSubsegmentIndex].mStart));
-    mReachedSwitchAccessPoint = false;
-    return true;
-  }
-  return false;
-}
-#endif /* MOZ_DASH */
-
 } // namespace mozilla
--- a/content/media/webm/WebMReader.h
+++ b/content/media/webm/WebMReader.h
@@ -17,20 +17,16 @@
 #include "vpx/vpx_codec.h"
 
 #ifdef MOZ_TREMOR
 #include "tremor/ivorbiscodec.h"
 #else
 #include "vorbis/codec.h"
 #endif
 
-#ifdef MOZ_DASH
-#include "DASHRepReader.h"
-#endif
-
 namespace mozilla {
 
 class WebMBufferedState;
 
 // Holds a nestegg_packet, and its file offset. This is needed so we
 // know the offset in the file we've played up to, in order to calculate
 // whether it's likely we can play through to the end without needing
 // to stop to buffer, given the current download rate.
@@ -96,21 +92,17 @@ class WebMPacketQueue : private nsDeque 
   
   void Reset() {
     while (GetSize() > 0) {
       delete PopFront();
     }
   }
 };
 
-#ifdef MOZ_DASH
-class WebMReader : public DASHRepReader
-#else
 class WebMReader : public MediaDecoderReader
-#endif
 {
 public:
   WebMReader(AbstractMediaDecoder* aDecoder);
   ~WebMReader();
 
   virtual nsresult Init(MediaDecoderReader* aCloneDonor);
   virtual nsresult ResetDecode();
   virtual bool DecodeAudioData();
@@ -134,109 +126,27 @@ public:
   }
 
   virtual nsresult ReadMetadata(MediaInfo* aInfo,
                                 MetadataTags** aTags);
   virtual nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime);
   virtual nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime);
   virtual void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
 
-#ifdef MOZ_DASH
-  virtual void SetMainReader(DASHReader *aMainReader) MOZ_OVERRIDE {
-    NS_ASSERTION(aMainReader, "aMainReader is null.");
-    mMainReader = aMainReader;
-  }
-
-  // Called by |DASHReader| on the decode thread so that this reader will
-  // start reading at the appropriate subsegment/cluster. If this is not the
-  // current reader and a switch was previously requested, then it will seek to
-  // starting offset of the subsegment at which it is supposed to switch.
-  // Called on the decode thread, enters the decode monitor.
-  void PrepareToDecode() MOZ_OVERRIDE;
-
-  // Returns a reference to the audio/video queue of the main reader.
-  // Allows for a single audio/video queue to be shared among multiple
-  // |WebMReader|s.
-  MediaQueue<AudioData>& AudioQueue() MOZ_OVERRIDE {
-    if (mMainReader) {
-      return mMainReader->AudioQueue();
-    } else {
-      return MediaDecoderReader::AudioQueue();
-    }
-  }
-
-  MediaQueue<VideoData>& VideoQueue() MOZ_OVERRIDE {
-    if (mMainReader) {
-      return mMainReader->VideoQueue();
-    } else {
-      return MediaDecoderReader::VideoQueue();
-    }
-  }
-
-  // Sets byte range for initialization (EBML); used by DASH.
-  void SetInitByteRange(MediaByteRange &aByteRange) MOZ_OVERRIDE {
-    mInitByteRange = aByteRange;
-  }
-
-  // Sets byte range for cue points, i.e. cluster offsets; used by DASH.
-  void SetIndexByteRange(MediaByteRange &aByteRange) MOZ_OVERRIDE {
-    mCuesByteRange = aByteRange;
-  }
-
-  // Returns the index of the subsegment which contains the seek time.
-  int64_t GetSubsegmentForSeekTime(int64_t aSeekToTime) MOZ_OVERRIDE;
-
-  // Returns list of ranges for cluster start and end offsets.
-  nsresult GetSubsegmentByteRanges(nsTArray<MediaByteRange>& aByteRanges)
-                                                                  MOZ_OVERRIDE;
-
-  // Called by |DASHReader|::|PossiblySwitchVideoReaders| to check if this
-  // reader has reached a switch access point and it's ok to switch readers.
-  // Called on the decode thread.
-  bool HasReachedSubsegment(uint32_t aSubsegmentIndex) MOZ_OVERRIDE;
-
-  // Requests that this reader seek to the specified subsegment. Seek will
-  // happen when |PrepareDecodeVideoFrame| is called on the decode
-  // thread.
-  // Called on the main thread or decoder thread. Decode monitor must be held.
-  void RequestSeekToSubsegment(uint32_t aIdx) MOZ_OVERRIDE;
-
-  // Requests that this reader switch to |aNextReader| at the start of the
-  // specified subsegment. This is the reader to switch FROM.
-  // Called on the main thread or decoder thread. Decode monitor must be held.
-  void RequestSwitchAtSubsegment(int32_t aSubsegmentIdx,
-                                 MediaDecoderReader* aNextReader) MOZ_OVERRIDE;
-
-  // Seeks to the beginning of the specified cluster. Called on the decode
-  // thread.
-  void SeekToCluster(uint32_t aIdx);
-
-  // Returns true if data at the end of the final subsegment has been cached.
-  bool IsDataCachedAtEndOfSubsegments() MOZ_OVERRIDE;
-#endif
-
 protected:
   // Value passed to NextPacket to determine if we are reading a video or an
   // audio packet.
   enum TrackType {
     VIDEO = 0,
     AUDIO = 1
   };
 
   // Read a packet from the nestegg file. Returns nullptr if all packets for
   // the particular track have been read. Pass VIDEO or AUDIO to indicate the
   // type of the packet we want to read.
-#ifdef MOZ_DASH
-  nsReturnRef<NesteggPacketHolder> NextPacketInternal(TrackType aTrackType);
-
-  // Read a packet from the nestegg file. Returns nullptr if all packets for
-  // the particular track have been read. Pass VIDEO or AUDIO to indicate the
-  // type of the packet we want to read. If the reader reaches a switch access
-  // point, this function will get a packet from |mNextReader|.
-#endif
   nsReturnRef<NesteggPacketHolder> NextPacket(TrackType aTrackType);
 
   // Pushes a packet to the front of the video packet queue.
   virtual void PushVideoPacket(NesteggPacketHolder* aItem);
 
   // Returns an initialized ogg packet with data obtained from the WebM container.
   ogg_packet InitOggPacket(unsigned char* aData,
                            size_t aLength,
@@ -296,61 +206,13 @@ private:
   nsIntSize mInitialFrame;
 
   // Picture region, as relative to the initial frame size.
   nsIntRect mPicture;
 
   // Booleans to indicate if we have audio and/or video data
   bool mHasVideo;
   bool mHasAudio;
-
-#ifdef MOZ_DASH
-  // Byte range for initialisation data; e.g. specified in DASH manifest.
-  MediaByteRange mInitByteRange;
-
-  // Byte range for cues; e.g. specified in DASH manifest.
-  MediaByteRange mCuesByteRange;
-
-  // Byte ranges for clusters; set internally, derived from cues.
-  nsTArray<TimestampedMediaByteRange> mClusterByteRanges;
-
-  // Pointer to the main |DASHReader|. Set in the constructor.
-  DASHReader* mMainReader;
-
-  // Index of the cluster to switch to. Monitor must be entered for write
-  // access on all threads, read access off the decode thread.
-  int32_t mSwitchingCluster;
-
-  // Pointer to the next reader. Used in |NextPacket| and |PushVideoPacket| at
-  // switch access points. Monitor must be entered for write access on all
-  // threads, read access off the decode thread.
-  nsRefPtr<WebMReader> mNextReader;
-
-  // Index of the cluster to seek to for a DASH stream request. Monitor must be
-  // entered for write access on all threads, read access off the decode
-  // thread.
-  int32_t mSeekToCluster;
-
-  // Current end offset of the last packet read in |NextPacket|. Used to check
-  // if the reader reached the switch access point. Accessed on the decode
-  // thread only.
-  int64_t mCurrentOffset;
-
-  // Index of next cluster to be read. Used to determine the starting offset of
-  // the next cluster. Accessed on the decode thread only.
-  uint32_t mNextCluster;
-
-  // Set in |NextPacket| if we read a packet from the next reader. If true in
-  // |PushVideoPacket|, we will push the packet onto the next reader's
-  // video packet queue (not video data queue!). Accessed on decode thread
-  // only.
-  bool mPushVideoPacketToNextReader;
-
-  // Indicates if the reader has reached a switch access point.  Set in
-  // |NextPacket| and read in |HasReachedSubsegment|. Accessed on
-  // decode thread only.
-  bool mReachedSwitchAccessPoint;
-#endif
 };
 
 } // namespace mozilla
 
 #endif
--- a/content/xml/content/src/Makefile.in
+++ b/content/xml/content/src/Makefile.in
@@ -9,11 +9,8 @@ INCLUDES	+= \
 		-I$(srcdir)/../../../base/src \
 		$(NULL)
 
 EXPORT_RESOURCE_CONTENT = \
 		$(srcdir)/htmlmathml-f.ent \
 		$(NULL)
 libs::
 	$(INSTALL) $(EXPORT_RESOURCE_CONTENT) $(DIST)/bin/res/dtd
-
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(EXPORT_RESOURCE_CONTENT) $(DESTDIR)$(mozappdir)/res/dtd
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -3646,16 +3646,24 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
   return nsDOMGenericSH::NewResolve(wrapper, cx, obj, id, flags, objp,
                                     _retval);
 }
 
 NS_IMETHODIMP
 nsWindowSH::Finalize(nsIXPConnectWrappedNative *wrapper, JSFreeOp *fop,
                      JSObject *obj)
 {
+  // Since this call is virtual, the exact rooting hazard static analysis is
+  // not able to determine that it happens during finalization and should be
+  // ignored. Moreover, the analysis cannot discover and validate the
+  // potential targets of the virtual call to OnFinalize below because of the
+  // indirection through nsCOMMPtr. Thus, we annotate the analysis here so
+  // that it does not report OnFinalize as GCing with |obj| on stack.
+  JS::AutoAssertNoGC nogc;
+
   nsCOMPtr<nsIScriptGlobalObject> sgo(do_QueryWrappedNative(wrapper));
   NS_ENSURE_TRUE(sgo, NS_ERROR_UNEXPECTED);
 
   sgo->OnFinalize(obj);
 
   return NS_OK;
 }
 
--- a/dom/browser-element/mochitest/browserElementTestHelpers.js
+++ b/dom/browser-element/mochitest/browserElementTestHelpers.js
@@ -200,18 +200,20 @@ function expectPriorityChange(childID, e
 
 function expectPriorityWithBackgroundLRUSet(childID, expectedBackgroundLRU) {
   var deferred = Promise.defer();
 
   browserElementTestHelpers.addProcessPriorityObserver(
     'process-priority-with-background-LRU-set',
     function(subject, topic, data) {
 
+      dump("browserElementTestHelpers got notify: topic "+ topic + ", data " + data +"\n");
       [id, priority, cpuPriority, backgroundLRU] = data.split(":");
       if (id != childID) {
+        dump("id(" + id + ") != childID(" + childID + ")\n");
         return;
       }
 
       is(backgroundLRU, expectedBackgroundLRU,
          'Expected backgroundLRU ' + backgroundLRU + ' of childID ' + childID +
          ' to change to ' + expectedBackgroundLRU);
 
       if (backgroundLRU == expectedBackgroundLRU) {
--- a/dom/ipc/AppProcessChecker.cpp
+++ b/dom/ipc/AppProcessChecker.cpp
@@ -20,17 +20,22 @@
 #include "TabParent.h"
 
 #include <algorithm>
 
 using namespace mozilla::dom;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::services;
 #else
+namespace mozilla {
+namespace dom {
 class PContentParent;
+}
+}
+
 class nsIPrincipal;
 #endif
 
 namespace mozilla {
 
 #ifdef MOZ_CHILD_PERMISSIONS
 
 bool
@@ -275,25 +280,25 @@ bool
 AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
                  AssertAppProcessType aType,
                  const char* aCapability)
 {
   return true;
 }
 
 bool
-AssertAppPrincipal(PContentParent* aActor,
+AssertAppPrincipal(mozilla::dom::PContentParent* aActor,
                    nsIPrincipal* aPrincipal)
 {
   return true;
 }
 
 uint32_t
-CheckPermission(PContentParent*,
-                nsIPrincipal*,
-                const char*)
+CheckPermission(mozilla::dom::PContentParent* aActor,
+                nsIPrincipal* aPrincipal,
+                const char* aPermission)
 {
   return nsIPermissionManager::ALLOW_ACTION;
 }
 
 #endif
 
 } // namespace mozilla
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -67,16 +67,18 @@
 #include "mozilla/dom/PMemoryReportRequestChild.h"
 
 #ifdef MOZ_PERMISSIONS
 #include "nsIScriptSecurityManager.h"
 #include "nsPermission.h"
 #include "nsPermissionManager.h"
 #endif
 
+#include "PermissionMessageUtils.h"
+
 #if defined(MOZ_WIDGET_ANDROID)
 #include "APKOpen.h"
 #endif
 
 #if defined(MOZ_WIDGET_GONK)
 #include "nsVolume.h"
 #include "nsVolumeService.h"
 #endif
@@ -1167,24 +1169,25 @@ ContentChild::RecvNotifyVisited(const UR
       history->NotifyVisited(newURI);
     }
     return true;
 }
 
 bool
 ContentChild::RecvAsyncMessage(const nsString& aMsg,
                                const ClonedMessageData& aData,
-                               const InfallibleTArray<CpowEntry>& aCpows)
+                               const InfallibleTArray<CpowEntry>& aCpows,
+                               const IPC::Principal& aPrincipal)
 {
   nsRefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::sChildProcessManager;
   if (cpm) {
     StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForChild(aData);
     CpowIdHolder cpows(GetCPOWManager(), aCpows);
     cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()),
-                        aMsg, false, &cloneData, &cpows, nullptr);
+                        aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
   }
   return true;
 }
 
 bool
 ContentChild::RecvGeolocationUpdate(const GeoPosition& somewhere)
 {
   nsCOMPtr<nsIGeolocationUpdate> gs = do_GetService("@mozilla.org/geolocation/service;1");
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -183,17 +183,18 @@ public:
     nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
 
     virtual bool RecvPreferenceUpdate(const PrefSetting& aPref);
 
     virtual bool RecvNotifyAlertsObserver(const nsCString& aType, const nsString& aData);
 
     virtual bool RecvAsyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData,
-                                  const InfallibleTArray<CpowEntry>& aCpows);
+                                  const InfallibleTArray<CpowEntry>& aCpows,
+                                  const IPC::Principal& aPrincipal);
 
     virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere);
 
     virtual bool RecvAddPermission(const IPC::Permission& permission);
 
     virtual bool RecvScreenSizeChanged(const gfxIntSize &size);
 
     virtual bool RecvFlushMemory(const nsString& reason);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1134,17 +1134,17 @@ ContentParent::ActorDestroy(ActorDestroy
         mForceKillTask->Cancel();
         mForceKillTask = nullptr;
     }
 
     nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
     if (ppm) {
       ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
                           CHILD_PROCESS_SHUTDOWN_MESSAGE, false,
-                          nullptr, nullptr, nullptr);
+                          nullptr, nullptr, nullptr, nullptr);
     }
     nsCOMPtr<nsIThreadObserver>
         kungFuDeathGrip(static_cast<nsIThreadObserver*>(this));
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
         obs->RemoveObserver(static_cast<nsIObserver*>(this), "xpcom-shutdown");
         obs->RemoveObserver(static_cast<nsIObserver*>(this), "memory-pressure");
         obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-memory-reporter-request");
@@ -2860,55 +2860,74 @@ ContentParent::RecvCloseAlert(const nsSt
 
     return true;
 }
 
 bool
 ContentParent::RecvSyncMessage(const nsString& aMsg,
                                const ClonedMessageData& aData,
                                const InfallibleTArray<CpowEntry>& aCpows,
+                               const IPC::Principal& aPrincipal,
                                InfallibleTArray<nsString>* aRetvals)
 {
+  nsIPrincipal* principal = aPrincipal;
+  if (principal && !AssertAppPrincipal(this, principal)) {
+    return false;
+  }
+
   nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
     CpowIdHolder cpows(GetCPOWManager(), aCpows);
+
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
-                        aMsg, true, &cloneData, &cpows, aRetvals);
+                        aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
   }
   return true;
 }
 
 bool
 ContentParent::AnswerRpcMessage(const nsString& aMsg,
                                 const ClonedMessageData& aData,
                                 const InfallibleTArray<CpowEntry>& aCpows,
+                                const IPC::Principal& aPrincipal,
                                 InfallibleTArray<nsString>* aRetvals)
 {
+  nsIPrincipal* principal = aPrincipal;
+  if (principal && !AssertAppPrincipal(this, principal)) {
+    return false;
+  }
+
   nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
     CpowIdHolder cpows(GetCPOWManager(), aCpows);
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
-                        aMsg, true, &cloneData, &cpows, aRetvals);
+                        aMsg, true, &cloneData, &cpows, aPrincipal, aRetvals);
   }
   return true;
 }
 
 bool
 ContentParent::RecvAsyncMessage(const nsString& aMsg,
                                 const ClonedMessageData& aData,
-                                const InfallibleTArray<CpowEntry>& aCpows)
+                                const InfallibleTArray<CpowEntry>& aCpows,
+                                const IPC::Principal& aPrincipal)
 {
+  nsIPrincipal* principal = aPrincipal;
+  if (principal && !AssertAppPrincipal(this, principal)) {
+    return false;
+  }
+
   nsRefPtr<nsFrameMessageManager> ppm = mMessageManager;
   if (ppm) {
     StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
     CpowIdHolder cpows(GetCPOWManager(), aCpows);
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()),
-                        aMsg, false, &cloneData, &cpows, nullptr);
+                        aMsg, false, &cloneData, &cpows, aPrincipal, nullptr);
   }
   return true;
 }
 
 bool
 ContentParent::RecvFilePathUpdateNotify(const nsString& aType,
                                         const nsString& aStorageName,
                                         const nsString& aFilePath,
@@ -3105,27 +3124,28 @@ ContentParent::RecvPrivateDocShellsExist
   }
   return true;
 }
 
 bool
 ContentParent::DoSendAsyncMessage(JSContext* aCx,
                                   const nsAString& aMessage,
                                   const mozilla::dom::StructuredCloneData& aData,
-                                  JS::Handle<JSObject *> aCpows)
+                                  JS::Handle<JSObject *> aCpows,
+                                  nsIPrincipal* aPrincipal)
 {
   ClonedMessageData data;
   if (!BuildClonedMessageDataForParent(this, aData, data)) {
     return false;
   }
   InfallibleTArray<CpowEntry> cpows;
   if (!GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
     return false;
   }
-  return SendAsyncMessage(nsString(aMessage), data, cpows);
+  return SendAsyncMessage(nsString(aMessage), data, cpows, aPrincipal);
 }
 
 bool
 ContentParent::CheckPermission(const nsAString& aPermission)
 {
   return AssertAppProcessPermission(this, NS_ConvertUTF16toUTF8(aPermission).get());
 }
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -112,17 +112,18 @@ public:
     NS_DECL_NSIDOMGEOPOSITIONCALLBACK
 
     /**
      * MessageManagerCallback methods that we override.
      */
     virtual bool DoSendAsyncMessage(JSContext* aCx,
                                     const nsAString& aMessage,
                                     const mozilla::dom::StructuredCloneData& aData,
-                                    JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
+                                    JS::Handle<JSObject *> aCpows,
+                                    nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
     virtual bool CheckPermission(const nsAString& aPermission) MOZ_OVERRIDE;
     virtual bool CheckManifestURL(const nsAString& aManifestURL) MOZ_OVERRIDE;
     virtual bool CheckAppHasPermission(const nsAString& aPermission) MOZ_OVERRIDE;
     virtual bool CheckAppHasStatus(unsigned short aStatus) MOZ_OVERRIDE;
 
     /** Notify that a tab is beginning its destruction sequence. */
     void NotifyTabDestroying(PBrowserParent* aTab);
     /** Notify that a tab was destroyed during normal operation. */
@@ -415,24 +416,27 @@ private:
 
     virtual bool RecvCloseAlert(const nsString& aName);
 
     virtual bool RecvLoadURIExternal(const URIParams& uri);
 
     virtual bool RecvSyncMessage(const nsString& aMsg,
                                  const ClonedMessageData& aData,
                                  const InfallibleTArray<CpowEntry>& aCpows,
+                                 const IPC::Principal& aPrincipal,
                                  InfallibleTArray<nsString>* aRetvals);
     virtual bool AnswerRpcMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData,
                                   const InfallibleTArray<CpowEntry>& aCpows,
+                                  const IPC::Principal& aPrincipal,
                                   InfallibleTArray<nsString>* aRetvals);
     virtual bool RecvAsyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData,
-                                  const InfallibleTArray<CpowEntry>& aCpows);
+                                  const InfallibleTArray<CpowEntry>& aCpows,
+                                  const IPC::Principal& aPrincipal);
 
     virtual bool RecvFilePathUpdateNotify(const nsString& aType,
                                           const nsString& aStorageName,
                                           const nsString& aFilePath,
                                           const nsCString& aReason);
 
     virtual bool RecvAddGeolocationListener(const IPC::Principal& aPrincipal,
                                             const bool& aHighAccuracy);
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -56,33 +56,36 @@ intr protocol PBrowser
     manages PContentDialog;
     manages PDocumentRenderer;
     manages PContentPermissionRequest;
     manages PRenderFrame;
     manages POfflineCacheUpdate;
     manages PIndexedDB;
 
 both:
-    AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
+    AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows,
+                 Principal aPrincipal);
 
 parent:
     /**
      * When child sends this message, parent should move focus to
      * the next or previous focusable element.
      */
     MoveFocus(bool forward);
 
     Event(RemoteDOMEvent aEvent);
 
     intr CreateWindow() returns (PBrowser window);
 
-    sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
+    sync SyncMessage(nsString aMessage, ClonedMessageData aData,
+                     CpowEntry[] aCpows, Principal aPrincipal)
       returns (nsString[] retval);
 
-    rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
+    rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
+                   CpowEntry[] aCpows, Principal aPrincipal)
       returns (nsString[] retval);
 
     /**
      * The IME sequence number (seqno) parameter is used to make sure
      * that a notification is discarded if it arrives at the chrome process
      * too late. If the notification is late and we accept it, we will have
      * an out-of-date view of the content process, which means events that we
      * dispatch based on this out-of-date view will be wrong also.
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -370,20 +370,22 @@ parent:
 
     async LoadURIExternal(URIParams uri);
 
     // PrefService message
     sync ReadPrefsArray() returns (PrefSetting[] prefs);
 
     sync ReadFontList() returns (FontListEntry[] retValue);
 
-    sync SyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
+    sync SyncMessage(nsString aMessage, ClonedMessageData aData,
+                     CpowEntry[] aCpows, Principal aPrincipal)
       returns (nsString[] retval);
 
-    rpc RpcMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows)
+    rpc RpcMessage(nsString aMessage, ClonedMessageData aData,
+                   CpowEntry[] aCpows, Principal aPrincipal)
       returns (nsString[] retval);
 
     ShowAlertNotification(nsString imageUrl,
                           nsString title,
                           nsString text,
                           bool textClickable,
                           nsString cookie,
                           nsString name,
@@ -464,13 +466,14 @@ parent:
     // called by the child (test code only) to propagate volume changes to the parent
     async CreateFakeVolume(nsString fsName, nsString mountPoint);
     async SetFakeVolumeState(nsString fsName, int32_t fsState);
 
     sync KeywordToURI(nsCString keyword)
         returns (OptionalInputStreamParams postData, OptionalURIParams uri);
 
 both:
-     AsyncMessage(nsString aMessage, ClonedMessageData aData, CpowEntry[] aCpows);
+     AsyncMessage(nsString aMessage, ClonedMessageData aData,
+                  CpowEntry[] aCpows, Principal aPrincipal);
 };
 
 }
 }
--- a/dom/ipc/ProcessPriorityManager.cpp
+++ b/dom/ipc/ProcessPriorityManager.cpp
@@ -38,17 +38,19 @@
 #endif
 
 // Use LOGP inside a ParticularProcessPriorityManager method; use LOG
 // everywhere else.  LOGP prints out information about the particular process
 // priority manager.
 //
 // (Wow, our logging story is a huge mess.)
 
-// #define ENABLE_LOGGING 1
+#ifndef HAVE_64BIT_OS
+#define ENABLE_LOGGING 1
+#endif
 
 #if defined(ANDROID) && defined(ENABLE_LOGGING)
 #  include <android/log.h>
 #  define LOG(fmt, ...) \
      __android_log_print(ANDROID_LOG_INFO, \
        "Gecko:ProcessPriorityManager", \
        fmt, ## __VA_ARGS__)
 #  define LOGP(fmt, ...) \
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -57,16 +57,17 @@
 #include "nsIWebProgress.h"
 #include "nsInterfaceHashtable.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
 #include "nsLayoutUtils.h"
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "nsWeakReference.h"
+#include "PermissionMessageUtils.h"
 #include "PCOMContentPermissionRequestChild.h"
 #include "PuppetWidget.h"
 #include "StructuredCloneUtils.h"
 #include "nsViewportInfo.h"
 #include "JavaScriptChild.h"
 #include "APZCCallbackHelper.h"
 #include "nsILoadContext.h"
 #include "ipc/nsGUIEventIPC.h"
@@ -1501,17 +1502,17 @@ TabChild::DispatchMessageManagerMessage(
     }
 
     nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
     // Let the BrowserElementScrolling helper (if it exists) for this
     // content manipulate the frame state.
     nsRefPtr<nsFrameMessageManager> mm =
       static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
     mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
-                       aMessageName, false, &cloneData, nullptr, nullptr);
+                       aMessageName, false, &cloneData, nullptr, nullptr, nullptr);
 }
 
 bool
 TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics)
 {
   MOZ_ASSERT(aFrameMetrics.mScrollId != FrameMetrics::NULL_SCROLL_ID);
 
   if (aFrameMetrics.mScrollId == FrameMetrics::ROOT_SCROLL_ID) {
@@ -2066,26 +2067,27 @@ TabChild::RecvLoadRemoteScript(const nsS
 
   LoadFrameScriptInternal(aURL);
   return true;
 }
 
 bool
 TabChild::RecvAsyncMessage(const nsString& aMessage,
                            const ClonedMessageData& aData,
-                           const InfallibleTArray<CpowEntry>& aCpows)
+                           const InfallibleTArray<CpowEntry>& aCpows,
+                           const IPC::Principal& aPrincipal)
 {
   if (mTabChildGlobal) {
     nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal());
     StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData);
     nsRefPtr<nsFrameMessageManager> mm =
       static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
     CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows);
     mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal),
-                       aMessage, false, &cloneData, &cpows, nullptr);
+                       aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
   }
   return true;
 }
 
 class UnloadScriptEvent : public nsRunnable
 {
 public:
   UnloadScriptEvent(TabChild* aTabChild, TabChildGlobal* aTabChildGlobal)
@@ -2399,53 +2401,60 @@ TabChild::DeallocPIndexedDBChild(PIndexe
   return true;
 }
 
 bool
 TabChild::DoSendBlockingMessage(JSContext* aCx,
                                 const nsAString& aMessage,
                                 const StructuredCloneData& aData,
                                 JS::Handle<JSObject *> aCpows,
+                                nsIPrincipal* aPrincipal,
                                 InfallibleTArray<nsString>* aJSONRetVal,
                                 bool aIsSync)
 {
   ContentChild* cc = Manager();
   ClonedMessageData data;
   if (!BuildClonedMessageDataForChild(cc, aData, data)) {
     return false;
   }
   InfallibleTArray<CpowEntry> cpows;
   if (sCpowsEnabled) {
     if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
   }
-  if (aIsSync)
-    return SendSyncMessage(nsString(aMessage), data, cpows, aJSONRetVal);
-  return CallRpcMessage(nsString(aMessage), data, cpows, aJSONRetVal);
+  if (aIsSync) {
+    return SendSyncMessage(nsString(aMessage), data, cpows, aPrincipal,
+                           aJSONRetVal);
+  }
+
+  return CallRpcMessage(nsString(aMessage), data, cpows, aPrincipal,
+                        aJSONRetVal);
 }
 
 bool
 TabChild::DoSendAsyncMessage(JSContext* aCx,
                              const nsAString& aMessage,
                              const StructuredCloneData& aData,
-                             JS::Handle<JSObject *> aCpows)
+                             JS::Handle<JSObject *> aCpows,
+                             nsIPrincipal* aPrincipal)
 {
   ContentChild* cc = Manager();
   ClonedMessageData data;
   if (!BuildClonedMessageDataForChild(cc, aData, data)) {
     return false;
   }
   InfallibleTArray<CpowEntry> cpows;
   if (sCpowsEnabled) {
     if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
       return false;
     }
   }
-  return SendAsyncMessage(nsString(aMessage), data, cpows);
+  return SendAsyncMessage(nsString(aMessage), data, cpows,
+                          aPrincipal);
 }
 
 TabChild*
 TabChild::GetFrom(nsIPresShell* aPresShell)
 {
   nsIDocument* doc = aPresShell->GetDocument();
   if (!doc) {
       return nullptr;
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -58,33 +58,37 @@ public:
   void Init();
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, nsDOMEventTargetHelper)
   NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
   NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
   NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
                              const JS::Value& aObject,
                              const JS::Value& aRemote,
+                             nsIPrincipal* aPrincipal,
                              JSContext* aCx,
                              uint8_t aArgc,
                              JS::Value* aRetval)
   {
     return mMessageManager
-      ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
+      ? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
+                                         aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
                             const JS::Value& aObject,
                             const JS::Value& aRemote,
+                            nsIPrincipal* aPrincipal,
                             JSContext* aCx,
                             uint8_t aArgc,
                             JS::Value* aRetval)
   {
     return mMessageManager
-      ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote, aCx, aArgc, aRetval)
+      ? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
+                                        aPrincipal, aCx, aArgc, aRetval)
       : NS_ERROR_NULL_POINTER;
   }
   NS_IMETHOD GetContent(nsIDOMWindow** aContent) MOZ_OVERRIDE;
   NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) MOZ_OVERRIDE;
   NS_IMETHOD Dump(const nsAString& aStr) MOZ_OVERRIDE
   {
     return mMessageManager ? mMessageManager->Dump(aStr) : NS_OK;
   }
@@ -189,22 +193,24 @@ public:
 
     /**
      * MessageManagerCallback methods that we override.
      */
     virtual bool DoSendBlockingMessage(JSContext* aCx,
                                        const nsAString& aMessage,
                                        const mozilla::dom::StructuredCloneData& aData,
                                        JS::Handle<JSObject *> aCpows,
+                                       nsIPrincipal* aPrincipal,
                                        InfallibleTArray<nsString>* aJSONRetVal,
                                        bool aIsSync) MOZ_OVERRIDE;
     virtual bool DoSendAsyncMessage(JSContext* aCx,
                                     const nsAString& aMessage,
                                     const mozilla::dom::StructuredCloneData& aData,
-                                    JS::Handle<JSObject *> aCpows) MOZ_OVERRIDE;
+                                    JS::Handle<JSObject *> aCpows,
+                                    nsIPrincipal* aPrincipal) MOZ_OVERRIDE;
 
     virtual bool RecvLoadURL(const nsCString& uri);
     virtual bool RecvCacheFileDescriptor(const nsString& aPath,
                                          const FileDescriptor& aFileDescriptor)
                                          MOZ_OVERRIDE;
     virtual bool RecvShow(const nsIntSize& size);
     virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation);
     virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
@@ -232,17 +238,18 @@ public:
                               const bool&     aPreventDefault);
     virtual bool RecvCompositionEvent(const mozilla::WidgetCompositionEvent& event);
     virtual bool RecvTextEvent(const mozilla::WidgetTextEvent& event);
     virtual bool RecvSelectionEvent(const mozilla::WidgetSelectionEvent& event);
     virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture);
     virtual bool RecvLoadRemoteScript(const nsString& aURL);
     virtual bool RecvAsyncMessage(const nsString& aMessage,
                                   const ClonedMessageData& aData,
-                                  const InfallibleTArray<CpowEntry>& aCpows);
+                                  const InfallibleTArray<CpowEntry>& aCpows,
+                                  const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
 
     virtual PDocumentRendererChild*
     AllocPDocumentRendererChild(const nsRect& documentRect, const gfxMatrix& transform,
                                 const nsString& bgcolor,
                                 const uint32_t& renderFlags, const bool& flushLayout,
                                 const nsIntSize& renderSize);
     virtual bool DeallocPDocumentRendererChild(PDocumentRendererChild* actor);
     virtual bool RecvPDocumentRendererConstructor(PDocumentRendererChild* actor,
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.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/. */
 
 #include "base/basictypes.h"
 
 #include "TabParent.h"
 
+#include "AppProcessChecker.h"
 #include "IDBFactory.h"
 #include "IndexedDBParent.h"
 #include "mozIApplication.h"
 #include "mozilla/BrowserElementParent.h"
 #include "mozilla/docshell/OfflineCacheUpdateParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/Hal.h"
 #include "mozilla/ipc/DocumentRendererParent.h"
@@ -47,16 +48,17 @@
 #include "nsViewManager.h"
 #include "nsIWidget.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIDOMWindow.h"
 #include "nsPrintfCString.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "private/pprio.h"
+#include "PermissionMessageUtils.h"
 #include "StructuredCloneUtils.h"
 #include "JavaScriptParent.h"
 #include "TabChild.h"
 #include "nsNetCID.h"
 #include <algorithm>
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
@@ -294,17 +296,18 @@ TabParent::ActorDestroy(ActorDestroyReas
     mIMETabParent = nullptr;
   }
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   nsRefPtr<nsFrameMessageManager> fmm;
   if (frameLoader) {
     fmm = frameLoader->GetFrameMessageManager();
     nsCOMPtr<Element> frameElement(mFrameElement);
-    ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr);
+    ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
+                   nullptr);
     frameLoader->DestroyChild();
 
     if (why == AbnormalShutdown && os) {
       os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
                           "oop-frameloader-crashed", nullptr);
       nsContentUtils::DispatchTrustedEvent(frameElement->OwnerDoc(), frameElement,
                                            NS_LITERAL_STRING("oop-browser-crashed"),
                                            true, true);
@@ -760,42 +763,63 @@ TabParent::TryCapture(const WidgetGUIEve
   SendRealTouchEvent(event);
   return true;
 }
 
 bool
 TabParent::RecvSyncMessage(const nsString& aMessage,
                            const ClonedMessageData& aData,
                            const InfallibleTArray<CpowEntry>& aCpows,
+                           const IPC::Principal& aPrincipal,
                            InfallibleTArray<nsString>* aJSONRetVal)
 {
+  nsIPrincipal* principal = aPrincipal;
+  ContentParent* parent = static_cast<ContentParent*>(Manager());
+  if (principal && !AssertAppPrincipal(parent, principal)) {
+    return false;
+  }
+
   StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
-  CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
-  return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
+  CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
+  return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
 }
 
 bool
 TabParent::AnswerRpcMessage(const nsString& aMessage,
                             const ClonedMessageData& aData,
                             const InfallibleTArray<CpowEntry>& aCpows,
+                            const IPC::Principal& aPrincipal,
                             InfallibleTArray<nsString>* aJSONRetVal)
 {
+  nsIPrincipal* principal = aPrincipal;
+  ContentParent* parent = static_cast<ContentParent*>(Manager());
+  if (principal && !AssertAppPrincipal(parent, principal)) {
+    return false;
+  }
+
   StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
-  CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
-  return ReceiveMessage(aMessage, true, &cloneData, &cpows, aJSONRetVal);
+  CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
+  return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
 }
 
 bool
 TabParent::RecvAsyncMessage(const nsString& aMessage,
                             const ClonedMessageData& aData,
-                            const InfallibleTArray<CpowEntry>& aCpows)
+                            const InfallibleTArray<CpowEntry>& aCpows,
+                            const IPC::Principal& aPrincipal)
 {
+  nsIPrincipal* principal = aPrincipal;
+  ContentParent* parent = static_cast<ContentParent*>(Manager());
+  if (principal && !AssertAppPrincipal(parent, principal)) {
+    return false;
+  }
+
   StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
-  CpowIdHolder cpows(static_cast<ContentParent*>(Manager())->GetCPOWManager(), aCpows);
-  return ReceiveMessage(aMessage, false, &cloneData, &cpows, nullptr);
+  CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
+  return ReceiveMessage(aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
 }
 
 bool
 TabParent::RecvSetCursor(const uint32_t& aCursor)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (widget) {
     widget->SetCursor((nsCursor) aCursor);
@@ -1209,28 +1233,30 @@ TabParent::RecvGetWidgetNativeData(Windo
   return false;
 }
 
 bool
 TabParent::ReceiveMessage(const nsString& aMessage,
                           bool aSync,
                           const StructuredCloneData* aCloneData,
                           CpowHolder* aCpows,
+                          nsIPrincipal* aPrincipal,
                           InfallibleTArray<nsString>* aJSONRetVal)
 {
   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   if (frameLoader && frameLoader->GetFrameMessageManager()) {
     nsRefPtr<nsFrameMessageManager> manager =
       frameLoader->GetFrameMessageManager();
 
     manager->ReceiveMessage(mFrameElement,
                             aMessage,
                             aSync,
                             aCloneData,
                             aCpows,
+                            aPrincipal,
                             aJSONRetVal);
   }
   return true;
 }
 
 PIndexedDBParent*
 TabParent::AllocPIndexedDBParent(
                             const nsCString& aGroup,
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -18,16 +18,17 @@
 #include "nsISecureBrowserUI.h"
 #include "nsITabParent.h"
 #include "Units.h"
 #include "js/TypeDecls.h"
 
 struct gfxMatrix;
 class nsFrameLoader;
 class nsIContent;
+class nsIPrincipal;
 class nsIURI;
 class nsIWidget;
 class CpowHolder;
 
 namespace mozilla {
 
 namespace layers {
 struct FrameMetrics;
@@ -116,24 +117,27 @@ public:
                                             const nsString& aURL,
                                             const nsString& aName,
                                             const nsString& aFeatures,
                                             bool* aOutWindowOpened);
     virtual bool AnswerCreateWindow(PBrowserParent** retval);
     virtual bool RecvSyncMessage(const nsString& aMessage,
                                  const ClonedMessageData& aData,
                                  const InfallibleTArray<CpowEntry>& aCpows,
+                                 const IPC::Principal& aPrincipal,
                                  InfallibleTArray<nsString>* aJSONRetVal);
     virtual bool AnswerRpcMessage(const nsString& aMessage,
                                   const ClonedMessageData& aData,
                                   const InfallibleTArray<CpowEntry>& aCpows,
+                                  const IPC::Principal& aPrincipal,
                                   InfallibleTArray<nsString>* aJSONRetVal);
     virtual bool RecvAsyncMessage(const nsString& aMessage,
                                   const ClonedMessageData& aData,
-                                  const InfallibleTArray<CpowEntry>& aCpows);
+                                  const InfallibleTArray<CpowEntry>& aCpows,
+                                  const IPC::Principal& aPrincipal);
     virtual bool RecvNotifyIMEFocus(const bool& aFocus,
                                     nsIMEUpdatePreference* aPreference,
                                     uint32_t* aSeqno);
     virtual bool RecvNotifyIMETextChange(const uint32_t& aStart,
                                          const uint32_t& aEnd,
                                          const uint32_t& aNewEnd);
     virtual bool RecvNotifyIMESelection(const uint32_t& aSeqno,
                                         const uint32_t& aAnchor,
@@ -249,16 +253,17 @@ public:
      */
     bool IsDestroyed() const { return mIsDestroyed; }
 
 protected:
     bool ReceiveMessage(const nsString& aMessage,
                         bool aSync,
                         const StructuredCloneData* aCloneData,
                         CpowHolder* aCpows,
+                        nsIPrincipal* aPrincipal,
                         InfallibleTArray<nsString>* aJSONRetVal = nullptr);
 
     virtual bool Recv__delete__() MOZ_OVERRIDE;
 
     virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;
 
     virtual PIndexedDBParent* AllocPIndexedDBParent(
                                                   const nsCString& aGroup,
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -146,17 +146,17 @@ partial interface Document {
                 attribute EventHandler oncut;
                 attribute EventHandler onpaste;
                 attribute EventHandler onbeforescriptexecute;
                 attribute EventHandler onafterscriptexecute;
   /**
    * True if this document is synthetic : stand alone image, video, audio file,
    * etc.
    */
-  [ChromeOnly] readonly attribute boolean mozSyntheticDocument;
+  [Func="IsChromeOrXBL"] readonly attribute boolean mozSyntheticDocument;
   /**
    * Returns the script element whose script is currently being processed.
    *
    * @see <https://developer.mozilla.org/en/DOM/document.currentScript>
    */
   readonly attribute Element? currentScript;
   /**
    * Release the current mouse capture if it is on an element within this
--- a/editor/composer/src/Makefile.in
+++ b/editor/composer/src/Makefile.in
@@ -25,11 +25,8 @@ include $(topsrcdir)/config/rules.mk
 	$(srcdir)/res/table-remove-column.gif \
 	$(srcdir)/res/table-remove-row-active.gif \
 	$(srcdir)/res/table-remove-row-hover.gif \
 	$(srcdir)/res/table-remove-row.gif \
 	$(NULL)
 
 libs::
 	$(INSTALL) $(_FILES) $(DIST)/bin/res
-
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(_FILES) $(DESTDIR)$(mozappdir)/res
--- a/embedding/browser/webBrowser/nsWebBrowser.cpp
+++ b/embedding/browser/webBrowser/nsWebBrowser.cpp
@@ -1657,16 +1657,17 @@ NS_IMETHODIMP nsWebBrowser::EnsureDocShe
    mDocShellTreeOwner->WebBrowser(this);
    
    return NS_OK;
 }
 
 static void DrawThebesLayer(ThebesLayer* aLayer,
                             gfxContext* aContext,
                             const nsIntRegion& aRegionToDraw,
+                            DrawRegionClip aClip,
                             const nsIntRegion& aRegionToInvalidate,
                             void* aCallbackData)
 {
   nscolor* color = static_cast<nscolor*>(aCallbackData);
   aContext->NewPath();
   aContext->SetColor(gfxRGBA(*color));
   nsIntRect dirtyRect = aRegionToDraw.GetBounds();
   aContext->Rectangle(gfxRect(dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height));
--- a/extensions/spellcheck/locales/Makefile.in
+++ b/extensions/spellcheck/locales/Makefile.in
@@ -6,12 +6,9 @@ DEFINES += -DAB_CD=$(AB_CD)
 
 include $(topsrcdir)/config/rules.mk
 
 DICTIONARY_FILES = $(strip $(wildcard $(LOCALE_SRCDIR)/hunspell/*.dic) $(wildcard $(LOCALE_SRCDIR)/hunspell/*.aff))
 
 ifneq (,$(DICTIONARY_FILES))
 libs::
 	$(INSTALL)  $(DICTIONARY_FILES) $(FINAL_TARGET)/dictionaries
-
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(DICTIONARY_FILES) $(DESTDIR)$(mozappdir)/dictionaries
 endif
--- a/gfx/2d/DrawTargetRecording.cpp
+++ b/gfx/2d/DrawTargetRecording.cpp
@@ -209,38 +209,47 @@ struct RecordingFontUserData
   RefPtr<DrawEventRecorderPrivate> recorder;
 };
 
 void RecordingFontUserDataDestroyFunc(void *aUserData)
 {
   RecordingFontUserData *userData =
     static_cast<RecordingFontUserData*>(aUserData);
 
+  // TODO support font in b2g recordings
+#ifndef MOZ_WIDGET_GONK
   userData->recorder->RecordEvent(RecordedScaledFontDestruction(userData->refPtr));
+#endif
 
   delete userData;
 }
 
 void
 DrawTargetRecording::FillGlyphs(ScaledFont *aFont,
                                 const GlyphBuffer &aBuffer,
                                 const Pattern &aPattern,
                                 const DrawOptions &aOptions,
                                 const GlyphRenderingOptions *aRenderingOptions)
 {
   if (!aFont->GetUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()))) {
+  // TODO support font in b2g recordings
+#ifndef MOZ_WIDGET_GONK
     mRecorder->RecordEvent(RecordedScaledFontCreation(aFont, aFont));
+#endif
     RecordingFontUserData *userData = new RecordingFontUserData;
     userData->refPtr = aFont;
     userData->recorder = mRecorder;
     aFont->AddUserData(reinterpret_cast<UserDataKey*>(mRecorder.get()), userData, 
                        &RecordingFontUserDataDestroyFunc);
   }
 
+  // TODO support font in b2g recordings
+#ifndef MOZ_WIDGET_GONK
   mRecorder->RecordEvent(RecordedFillGlyphs(this, aFont, aPattern, aOptions, aBuffer.mGlyphs, aBuffer.mNumGlyphs));
+#endif
   mFinalDT->FillGlyphs(aFont, aBuffer, aPattern, aOptions, aRenderingOptions);
 }
 
 void
 DrawTargetRecording::Mask(const Pattern &aSource,
                           const Pattern &aMask,
                           const DrawOptions &aOptions)
 {
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -260,16 +260,17 @@ public:
    * We guarantee that buffered contents in the visible
    * region are valid once drawing is complete.
    *
    * The origin of aContext is 0,0 in the ThebesLayer.
    */
   typedef void (* DrawThebesLayerCallback)(ThebesLayer* aLayer,
                                            gfxContext* aContext,
                                            const nsIntRegion& aRegionToDraw,
+                                           DrawRegionClip aClip,
                                            const nsIntRegion& aRegionToInvalidate,
                                            void* aCallbackData);
 
   /**
    * Finish the construction phase of the transaction, perform the
    * drawing phase, and end the transaction.
    * During the drawing phase, all ThebesLayers in the tree are
    * drawn in tree order, exactly once each, except for those layers
--- a/gfx/layers/LayersTypes.h
+++ b/gfx/layers/LayersTypes.h
@@ -53,16 +53,22 @@ enum LayersBackend {
   LAYERS_LAST
 };
 
 enum BufferMode {
   BUFFER_NONE,
   BUFFER_BUFFERED
 };
 
+enum DrawRegionClip {
+  CLIP_DRAW,
+  CLIP_DRAW_SNAPPED,
+  CLIP_NONE,
+};
+
 // LayerRenderState for Composer2D
 // We currently only support Composer2D using gralloc. If we want to be backed
 // by other surfaces we will need a more generic LayerRenderState.
 enum LayerRenderStateFlags {
   LAYER_RENDER_STATE_Y_FLIPPED = 1 << 0,
   LAYER_RENDER_STATE_BUFFER_ROTATION = 1 << 1,
   // Notify Composer2D to swap the RB pixels of gralloc buffer
   LAYER_RENDER_STATE_FORMAT_RB_SWAP = 1 << 2
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -851,16 +851,17 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
                "Rotation disabled, but we have nonzero rotation?");
 
   nsIntRegion invalidate;
   invalidate.Sub(aLayer->GetValidRegion(), destBufferRect);
   result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate);
 
   nsIntPoint topLeft;
   result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
+  result.mClip = CLIP_DRAW_SNAPPED;
 
   if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
     if (IsAzureBuffer()) {
       MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
       nsIntRegionRectIterator iter(result.mRegionToDraw);
       const nsIntRect *iterRect;
       while ((iterRect = iter.Next())) {
         mDTBuffer->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
@@ -868,36 +869,33 @@ ThebesLayerBuffer::BeginPaint(ThebesLaye
         mDTBufferOnWhite->FillRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height),
                                    ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
       }
     } else {
       MOZ_ASSERT(mBuffer && mBufferOnWhite);
       FillSurface(mBuffer, result.mRegionToDraw, topLeft, gfxRGBA(0.0, 0.0, 0.0, 1.0));
       FillSurface(mBufferOnWhite, result.mRegionToDraw, topLeft, gfxRGBA(1.0, 1.0, 1.0, 1.0));
     }
-    gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
   } else if (contentType == GFX_CONTENT_COLOR_ALPHA && !isClear) {
     if (IsAzureBuffer()) {
       nsIntRegionRectIterator iter(result.mRegionToDraw);
       const nsIntRect *iterRect;
       while ((iterRect = iter.Next())) {
         result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
       }
       // Clear will do something expensive with a complex clip pushed, so clip
       // here.
-      gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
     } else {
       MOZ_ASSERT(result.mContext->IsCairo());
+      result.mContext->Save();
       gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
       result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
       result.mContext->Paint();
-      result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
+      result.mContext->Restore();
     }
-  } else {
-    gfxUtils::ClipToRegionSnapped(result.mContext, result.mRegionToDraw);
   }
 
   return result;
 }
 
 }
 }
 
--- a/gfx/layers/ThebesLayerBuffer.h
+++ b/gfx/layers/ThebesLayerBuffer.h
@@ -16,16 +16,17 @@
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsISupportsImpl.h"            // for gfxContext::AddRef, etc
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsRect.h"                     // for nsIntRect
 #include "nsRegion.h"                   // for nsIntRegion
 #include "nsTraceRefcnt.h"              // for MOZ_COUNT_CTOR, etc
+#include "LayersTypes.h"
 
 struct gfxMatrix;
 struct nsIntSize;
 
 namespace mozilla {
 namespace gfx {
 class Matrix;
 }
@@ -213,16 +214,17 @@ public:
     PaintState()
       : mDidSelfCopy(false)
     {}
 
     nsRefPtr<gfxContext> mContext;
     nsIntRegion mRegionToDraw;
     nsIntRegion mRegionToInvalidate;
     bool mDidSelfCopy;
+    DrawRegionClip mClip;
   };
 
   enum {
     PAINT_WILL_RESAMPLE = 0x01,
     PAINT_NO_ROTATION = 0x02
   };
   /**
    * Start a drawing operation. This returns a PaintState describing what
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -110,20 +110,20 @@ protected:
   }
 
   virtual void EnsureSurface() { }
 
   virtual bool Lock() MOZ_OVERRIDE
   {
     EnsureSurface();
     if (!mSurface) {
-      mSurface = mCompositor->GetDrawTarget()->CreateSourceSurfaceFromData(mThebesImage->Data(),
-                                                                           mSize,
-                                                                           mThebesImage->Stride(),
-                                                                           mFormat);
+      mSurface = Factory::CreateWrappingDataSourceSurface(mThebesImage->Data(),
+                                                          mThebesImage->Stride(),
+                                                          mSize,
+                                                          mFormat);
     }
     return true;
   }
 
   virtual already_AddRefed<gfxImageSurface> GetAsSurface() MOZ_OVERRIDE {
     if (!mThebesImage) {
       mThebesImage = mThebesSurface->GetAsImageSurface();
     }
--- a/gfx/layers/basic/BasicThebesLayer.cpp
+++ b/gfx/layers/basic/BasicThebesLayer.cpp
@@ -126,17 +126,17 @@ BasicThebesLayer::PaintThebes(gfxContext
                                             &needsClipToVisibleRegion);
         if (GetOperator() != gfxContext::OPERATOR_OVER || mixBlendMode != gfxContext::OPERATOR_OVER) {
           needsClipToVisibleRegion = true;
         }
       } else {
         groupContext = aContext;
       }
       SetAntialiasingFlags(this, groupContext);
-      aCallback(this, groupContext, toDraw, nsIntRegion(), aCallbackData);
+      aCallback(this, groupContext, toDraw, CLIP_NONE, nsIntRegion(), aCallbackData);
       if (needsGroup) {
         BasicManager()->PopGroupToSourceWithCachedSurface(aContext, groupContext);
         if (needsClipToVisibleRegion) {
           gfxUtils::ClipToRegion(aContext, toDraw);
         }
         AutoSetOperator setOptimizedOperator(aContext, mixBlendMode != gfxContext::OPERATOR_OVER ? mixBlendMode : GetOperator());
         PaintWithMask(aContext, opacity, aMaskLayer);
       }
@@ -231,16 +231,17 @@ BasicThebesLayer::Validate(LayerManager:
     nsIntRegion extendedDrawRegion = state.mRegionToDraw;
     SetAntialiasingFlags(this, state.mContext);
 
     RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
 
     PaintBuffer(state.mContext,
                 state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
                 state.mDidSelfCopy,
+                state.mClip,
                 aCallback, aCallbackData);
     MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
     Mutated();
 
     RenderTraceInvalidateEnd(this, "FFFF00");
   } else {
     // It's possible that state.mRegionToInvalidate is nonempty here,
     // if we are shrinking the valid region to nothing. So use mRegionToDraw
--- a/gfx/layers/basic/BasicThebesLayer.h
+++ b/gfx/layers/basic/BasicThebesLayer.h
@@ -98,25 +98,26 @@ public:
 
 protected:
   virtual void
   PaintBuffer(gfxContext* aContext,
               const nsIntRegion& aRegionToDraw,
               const nsIntRegion& aExtendedRegionToDraw,
               const nsIntRegion& aRegionToInvalidate,
               bool aDidSelfCopy,
+              DrawRegionClip aClip,
               LayerManager::DrawThebesLayerCallback aCallback,
               void* aCallbackData)
   {
     if (!aCallback) {
       BasicManager()->SetTransactionIncomplete();
       return;
     }
-    aCallback(this, aContext, aExtendedRegionToDraw, aRegionToInvalidate,
-              aCallbackData);
+    aCallback(this, aContext, aExtendedRegionToDraw, aClip,
+              aRegionToInvalidate, aCallbackData);
     // Everything that's visible has been validated. Do this instead of just
     // OR-ing with aRegionToDraw, since that can lead to a very complex region
     // here (OR doesn't automatically simplify to the simplest possible
     // representation of a region.)
     nsIntRegion tmp;
     tmp.Or(mVisibleRegion, aExtendedRegionToDraw);
     mValidRegion.Or(mValidRegion, tmp);
   }
--- a/gfx/layers/client/ClientThebesLayer.cpp
+++ b/gfx/layers/client/ClientThebesLayer.cpp
@@ -101,17 +101,17 @@ ClientThebesLayer::PaintThebes()
       // subpixel AA)
       state.mRegionToInvalidate.And(state.mRegionToInvalidate,
                                     GetEffectiveVisibleRegion());
       nsIntRegion extendedDrawRegion = state.mRegionToDraw;
       SetAntialiasingFlags(this, state.mContext);
 
       PaintBuffer(state.mContext,
                   state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
-                  state.mDidSelfCopy);
+                  state.mDidSelfCopy, state.mClip);
       MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
       Mutated();
     } else {
       // It's possible that state.mRegionToInvalidate is nonempty here,
       // if we are shrinking the valid region to nothing. So use mRegionToDraw
       // instead.
       NS_WARN_IF_FALSE(state.mRegionToDraw.IsEmpty(),
                        "No context when we have something to draw, resource exhaustion?");
@@ -141,32 +141,33 @@ ClientThebesLayer::RenderLayer()
   mContentClient->EndPaint();
 }
 
 void
 ClientThebesLayer::PaintBuffer(gfxContext* aContext,
                                const nsIntRegion& aRegionToDraw,
                                const nsIntRegion& aExtendedRegionToDraw,
                                const nsIntRegion& aRegionToInvalidate,
-                               bool aDidSelfCopy)
+                               bool aDidSelfCopy, DrawRegionClip aClip)
 {
   ContentClientRemote* contentClientRemote = static_cast<ContentClientRemote*>(mContentClient.get());
   MOZ_ASSERT(contentClientRemote->GetIPDLActor());
 
   // NB: this just throws away the entire valid region if there are
   // too many rects.
   mValidRegion.SimplifyInward(8);
 
   if (!ClientManager()->GetThebesLayerCallback()) {
     ClientManager()->SetTransactionIncomplete();
     return;
   }
   ClientManager()->GetThebesLayerCallback()(this, 
                                             aContext, 
-                                            aExtendedRegionToDraw, 
+                                            aExtendedRegionToDraw,
+                                            aClip,
                                             aRegionToInvalidate,
                                             ClientManager()->GetThebesLayerCallbackData());
 
   // Everything that's visible has been validated. Do this instead of just
   // OR-ing with aRegionToDraw, since that can lead to a very complex region
   // here (OR doesn't automatically simplify to the simplest possible
   // representation of a region.)
   nsIntRegion tmp;
--- a/gfx/layers/client/ClientThebesLayer.h
+++ b/gfx/layers/client/ClientThebesLayer.h
@@ -100,17 +100,18 @@ public:
   }
 
 protected:
   void
   PaintBuffer(gfxContext* aContext,
               const nsIntRegion& aRegionToDraw,
               const nsIntRegion& aExtendedRegionToDraw,
               const nsIntRegion& aRegionToInvalidate,
-              bool aDidSelfCopy);
+              bool aDidSelfCopy,
+              DrawRegionClip aClip);
   
   void PaintThebes();
   
   void DestroyBackBuffer()
   {
     mContentClient = nullptr;
   }
 
--- a/gfx/layers/client/ClientTiledThebesLayer.h
+++ b/gfx/layers/client/ClientTiledThebesLayer.h
@@ -64,28 +64,16 @@ public:
   virtual void RenderLayer();
 
 private:
   ClientLayerManager* ClientManager()
   {
     return static_cast<ClientLayerManager*>(mManager);
   }
 
-  // BasicImplData
-  virtual void
-  PaintBuffer(gfxContext* aContext,
-              const nsIntRegion& aRegionToDraw,
-              const nsIntRegion& aExtendedRegionToDraw,
-              const nsIntRegion& aRegionToInvalidate,
-              bool aDidSelfCopy,
-              LayerManager::DrawThebesLayerCallback aCallback,
-              void* aCallbackData)
-  { NS_RUNTIMEABORT("Not reached."); }
-
-
   /**
    * For the initial PaintThebes of a transaction, calculates all the data
    * needed for that paint and any repeated transactions.
    */
   void BeginPaint();
 
   /**
    * When a paint ends, updates any data necessary to persist until the next
--- a/gfx/layers/client/ContentClient.cpp
+++ b/gfx/layers/client/ContentClient.cpp
@@ -889,22 +889,24 @@ ContentClientIncremental::BeginPaintBuff
 
   // If we do partial updates, we have to clip drawing to the regionToDraw.
   // If we don't clip, background images will be fillrect'd to the region correctly,
   // while text or lines will paint outside of the regionToDraw. This becomes apparent
   // with concave regions. Right now the scrollbars invalidate a narrow strip of the bar
   // although they never cover it. This leads to two draw rects, the narow strip and the actually
   // newly exposed area. It would be wise to fix this glitch in any way to have simpler
   // clip and draw regions.
-  gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
+  result.mClip = CLIP_DRAW;
 
   if (mContentType == GFX_CONTENT_COLOR_ALPHA) {
+    result.mContext->Save();
+    gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
     result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
     result.mContext->Paint();
-    result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
+    result.mContext->Restore();
   }
 
   return result;
 }
 
 void
 ContentClientIncremental::Updated(const nsIntRegion& aRegionToDraw,
                                   const nsIntRegion& aVisibleRegion,
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -269,17 +269,17 @@ BasicTiledLayerBuffer::PaintThebes(const
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
     if (PR_IntervalNow() - start > 3) {
       printf_stderr("Slow alloc %i\n", PR_IntervalNow() - start);
     }
     start = PR_IntervalNow();
 #endif
     PROFILER_LABEL("BasicTiledLayerBuffer", "PaintThebesSingleBufferDraw");
 
-    mCallback(mThebesLayer, ctxt, aPaintRegion, nsIntRegion(), mCallbackData);
+    mCallback(mThebesLayer, ctxt, aPaintRegion, CLIP_NONE, nsIntRegion(), mCallbackData);
   }
 
 #ifdef GFX_TILEDLAYER_PREF_WARNINGS
   if (PR_IntervalNow() - start > 30) {
     const nsIntRect bounds = aPaintRegion.GetBounds();
     printf_stderr("Time to draw %i: %i, %i, %i, %i\n", PR_IntervalNow() - start, bounds.x, bounds.y, bounds.width, bounds.height);
     if (aPaintRegion.IsComplex()) {
       printf_stderr("Complex region\n");
@@ -378,16 +378,17 @@ BasicTiledLayerBuffer::ValidateTileInter
   } else {
     ctxt->NewPath();
     ctxt->Scale(mResolution, mResolution);
     ctxt->Translate(gfxPoint(-aTileOrigin.x, -aTileOrigin.y));
     nsIntPoint a = nsIntPoint(aTileOrigin.x, aTileOrigin.y);
     mCallback(mThebesLayer, ctxt,
               nsIntRegion(nsIntRect(a, nsIntSize(GetScaledTileLength(),
                                                  GetScaledTileLength()))),
+              CLIP_NONE,
               nsIntRegion(), mCallbackData);
   }
 
 #ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
   DrawDebugOverlay(writableSurface, aTileOrigin.x * mResolution,
                    aTileOrigin.y * mResolution);
 #endif
 
--- a/gfx/layers/composite/APZCTreeManager.cpp
+++ b/gfx/layers/composite/APZCTreeManager.cpp
@@ -387,17 +387,16 @@ APZCTreeManager::ProcessEvent(const Widg
   // Transform the refPoint
   nsRefPtr<AsyncPanZoomController> apzc = GetTargetAPZC(ScreenPoint(aEvent.refPoint.x, aEvent.refPoint.y));
   if (!apzc) {
     return nsEventStatus_eIgnore;
   }
   gfx3DMatrix transformToApzc;
   gfx3DMatrix transformToGecko;
   GetInputTransforms(apzc, transformToApzc, transformToGecko);
-  ApplyTransform(&(aOutEvent->refPoint), transformToApzc);
   gfx3DMatrix outTransform = transformToApzc * transformToGecko;
   ApplyTransform(&(aOutEvent->refPoint), outTransform);
   return nsEventStatus_eIgnore;
 }
 
 nsEventStatus
 APZCTreeManager::ReceiveInputEvent(const WidgetInputEvent& aEvent,
                                    WidgetInputEvent* aOutEvent)
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -153,30 +153,16 @@ public:
 
 
   DrawThebesLayerCallback GetThebesLayerCallback() const
   { return mThebesLayerCallback; }
 
   void* GetThebesLayerCallbackData() const
   { return mThebesLayerCallbackData; }
 
-  /*
-   * Helper functions for our layers
-   */
-  void CallThebesLayerDrawCallback(ThebesLayer* aLayer,
-                                   gfxContext* aContext,
-                                   const nsIntRegion& aRegionToDraw)
-  {
-    NS_ASSERTION(mThebesLayerCallback,
-                 "CallThebesLayerDrawCallback without callback!");
-    mThebesLayerCallback(aLayer, aContext,
-                         aRegionToDraw, nsIntRegion(),
-                         mThebesLayerCallbackData);
-  }
-
 #ifdef MOZ_LAYERS_HAVE_LOG
   virtual const char* Name() const MOZ_OVERRIDE { return ""; }
 #endif // MOZ_LAYERS_HAVE_LOG
 
   enum WorldTransforPolicy {
     ApplyWorldTransform,
     DontApplyWorldTransform
   };
--- a/gfx/layers/d3d10/ThebesLayerD3D10.cpp
+++ b/gfx/layers/d3d10/ThebesLayerD3D10.cpp
@@ -409,50 +409,32 @@ ThebesLayerD3D10::DrawRegion(nsIntRegion
       // only the onBlack surface will really be used, so alpha information will
       // be incorrect.
       destinationSurface->SetAllowUseAsSource(false);
     }
   } else {
     destinationSurface = mD2DSurface;
   }
 
-  nsRefPtr<gfxContext> context;
-
-  if (mDrawTarget) {
-    context = new gfxContext(mDrawTarget);
-  } else {
-    context = new gfxContext(destinationSurface);
-  }
+  MOZ_ASSERT(mDrawTarget);
+  nsRefPtr<gfxContext> context = new gfxContext(mDrawTarget);
 
-  nsIntRegionRectIterator iter(aRegion);
   context->Translate(gfxPoint(-visibleRect.x, -visibleRect.y));
-  context->NewPath();
-  const nsIntRect *iterRect;
-  while ((iterRect = iter.Next())) {
-    context->Rectangle(gfxRect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
-    if (mDrawTarget && aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
+  if (aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
+    nsIntRegionRectIterator iter(aRegion);
+    const nsIntRect *iterRect;
+    while ((iterRect = iter.Next())) {
       mDrawTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
     }
   }
-  context->Clip();
 
-  if (!mDrawTarget && aMode == SURFACE_SINGLE_CHANNEL_ALPHA) {
-    context->SetOperator(gfxContext::OPERATOR_CLEAR);
-    context->Paint();
-    context->SetOperator(gfxContext::OPERATOR_OVER);
-  }
-
-  if (mD2DSurface) {
-    mD2DSurface->SetSubpixelAntialiasingEnabled(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
-  } else if (mDrawTarget) {
-    mDrawTarget->SetPermitSubpixelAA(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
-  }
+  mDrawTarget->SetPermitSubpixelAA(!(mContentFlags & CONTENT_COMPONENT_ALPHA));
 
   LayerManagerD3D10::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
-  cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
+  cbInfo.Callback(this, context, aRegion, CLIP_DRAW, nsIntRegion(), cbInfo.CallbackData);
 }
 
 void
 ThebesLayerD3D10::CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode)
 {
   if (aSize.width == 0 || aSize.height == 0) {
     // Nothing to do.
     return;
--- a/gfx/layers/d3d9/ThebesLayerD3D9.cpp
+++ b/gfx/layers/d3d9/ThebesLayerD3D9.cpp
@@ -488,17 +488,17 @@ ThebesLayerD3D9::DrawRegion(nsIntRegion 
 
     context = new gfxContext(dt);
   } else {
     context = new gfxContext(destinationSurface);
   }
 
   context->Translate(gfxPoint(-bounds.x, -bounds.y));
   LayerManagerD3D9::CallbackInfo cbInfo = mD3DManager->GetCallbackInfo();
-  cbInfo.Callback(this, context, aRegion, nsIntRegion(), cbInfo.CallbackData);
+  cbInfo.Callback(this, context, aRegion, CLIP_NONE, nsIntRegion(), cbInfo.CallbackData);
 
   for (uint32_t i = 0; i < aReadbackUpdates.Length(); ++i) {
     NS_ASSERTION(aMode == SURFACE_OPAQUE,
                  "Transparent surfaces should not be used for readback");
     const ReadbackProcessor::Update& update = aReadbackUpdates[i];
     nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();
     nsRefPtr<gfxContext> ctx =
         update.mLayer->GetSink()->BeginUpdate(update.mUpdateRect + offset,
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -378,17 +378,17 @@ nsEventStatus AsyncPanZoomController::Re
 
       if (!mTouchListenerTimeoutTask) {
         mTouchListenerTimeoutTask =
           NewRunnableMethod(this, &AsyncPanZoomController::TimeoutTouchListeners);
 
         PostDelayedTask(mTouchListenerTimeoutTask, gTouchListenerTimeout);
       }
     }
-    return nsEventStatus_eConsumeNoDefault;
+    return nsEventStatus_eIgnore;
   }
 
   return HandleInputEvent(aEvent);
 }
 
 nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent) {
   nsEventStatus rv = nsEventStatus_eIgnore;
 
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -195,31 +195,16 @@ public:
   void* GetNSOpenGLContext() const;
 
   DrawThebesLayerCallback GetThebesLayerCallback() const
   { return mThebesLayerCallback; }
 
   void* GetThebesLayerCallbackData() const
   { return mThebesLayerCallbackData; }
 
-  /*
-   * Helper functions for our layers
-   */
-  void CallThebesLayerDrawCallback(ThebesLayer* aLayer,
-                                   gfxContext* aContext,
-                                   const nsIntRegion& aRegionToDraw)
-  {
-    NS_ASSERTION(mThebesLayerCallback,
-                 "CallThebesLayerDrawCallback without callback!");
-    mThebesLayerCallback(aLayer, aContext,
-                         aRegionToDraw, nsIntRegion(),
-                         mThebesLayerCallbackData);
-  }
-
-
   GLenum FBOTextureTarget() { return mFBOTextureTarget; }
 
   /**
    * Controls how to initialize the texture / FBO created by
    * CreateFBOWithTexture.
    *  - InitModeNone: No initialization, contents are undefined.
    *  - InitModeClear: Clears the FBO.
    *  - InitModeCopy: Copies the contents of the current glReadBuffer into the
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -823,22 +823,24 @@ BasicBufferOGL::BeginPaint(ContentType a
 
   // If we do partial updates, we have to clip drawing to the regionToDraw.
   // If we don't clip, background images will be fillrect'd to the region correctly,
   // while text or lines will paint outside of the regionToDraw. This becomes apparent
   // with concave regions. Right now the scrollbars invalidate a narrow strip of the bar
   // although they never cover it. This leads to two draw rects, the narow strip and the actually
   // newly exposed area. It would be wise to fix this glitch in any way to have simpler
   // clip and draw regions.
-  gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
+  result.mClip = CLIP_DRAW;
 
   if (mTexImage->GetContentType() == GFX_CONTENT_COLOR_ALPHA) {
+    result.mContext->Save();
+    gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
     result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
     result.mContext->Paint();
-    result.mContext->SetOperator(gfxContext::OPERATOR_OVER);
+    result.mContext->Restore();
   }
 
   return result;
 }
 
 ThebesLayerOGL::ThebesLayerOGL(LayerManagerOGL* aManager)
   : ThebesLayer(aManager, nullptr)
   , LayerOGL(aManager)
@@ -926,17 +928,17 @@ ThebesLayerOGL::RenderLayer(int aPreviou
 
     LayerManager::DrawThebesLayerCallback callback =
       mOGLManager->GetThebesLayerCallback();
     if (!callback) {
       NS_ERROR("GL should never need to update ThebesLayers in an empty transaction");
     } else {
       void* callbackData = mOGLManager->GetThebesLayerCallbackData();
       SetAntialiasingFlags(this, state.mContext);
-      callback(this, state.mContext, state.mRegionToDraw,
+      callback(this, state.mContext, state.mRegionToDraw, state.mClip,
                state.mRegionToInvalidate, callbackData);
       // Everything that's visible has been validated. Do this instead of just
       // OR-ing with aRegionToDraw, since that can lead to a very complex region
       // here (OR doesn't automatically simplify to the simplest possible
       // representation of a region.)
       nsIntRegion tmp;
       tmp.Or(mVisibleRegion, state.mRegionToDraw);
       mValidRegion.Or(mValidRegion, tmp);
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -10,17 +10,24 @@
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/CompositorParent.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 
 #include "prlog.h"
 
 #include "gfxPlatform.h"
 
+#ifdef XP_WIN
+#include <process.h>
+#define getpid _getpid
+#endif
+
 #include "nsXULAppAPI.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsDirectoryServiceDefs.h"
 
 #if defined(XP_WIN)
 #include "gfxWindowsPlatform.h"
 #include "gfxD2DSurface.h"
 #elif defined(XP_MACOSX)
 #include "gfxPlatformMac.h"
 #include "gfxQuartzSurface.h"
 #elif defined(MOZ_WIDGET_GTK)
@@ -314,20 +321,33 @@ int RecordingPrefChanged(const char *aPr
 {
   if (Preferences::GetBool("gfx.2d.recording", false)) {
     nsAutoCString fileName;
     nsAdoptingString prefFileName = Preferences::GetString("gfx.2d.recordingfile");
 
     if (prefFileName) {
       fileName.Append(NS_ConvertUTF16toUTF8(prefFileName));
     } else {
-      fileName.AssignLiteral("browserrecording.aer");
+      nsCOMPtr<nsIFile> tmpFile;
+      if (NS_FAILED(NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile)))) {
+        return 0;
+      }
+      fileName.AppendPrintf("moz2drec_%i_%i.aer", XRE_GetProcessType(), getpid());
+
+      nsresult rv = tmpFile->AppendNative(fileName);
+      if (NS_FAILED(rv))
+        return 0;
+
+      rv = tmpFile->GetNativePath(fileName);
+      if (NS_FAILED(rv))
+        return 0;
     }
 
     gPlatform->mRecorder = Factory::CreateEventRecorderForFile(fileName.BeginReading());
+    printf_stderr("Recording to %s\n", fileName.get());
     Factory::SetGlobalEventRecorder(gPlatform->mRecorder);
   } else {
     Factory::SetGlobalEventRecorder(nullptr);
   }
 
   return 0;
 }
 
--- a/intl/locale/src/Makefile.in
+++ b/intl/locale/src/Makefile.in
@@ -25,11 +25,8 @@ charsetalias.properties.h: props2arrays.
 	$(PYTHON) $^ $@
 
 GARBAGE += \
 	charsetalias.properties.h \
 	$(NULL)
 
 libs::
 	$(INSTALL) $(EXPORT_RESOURCE) $(DIST)/bin/res
-
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(EXPORT_RESOURCE) $(DESTDIR)$(mozappdir)/res
--- a/intl/locales/Makefile.in
+++ b/intl/locales/Makefile.in
@@ -6,12 +6,9 @@ DEFINES += -DAB_CD=$(AB_CD)
 
 include $(topsrcdir)/config/rules.mk
 
 PATTERN_FILES = $(strip $(wildcard $(srcdir)/*/hyphenation/*.dic))
 
 ifneq (,$(PATTERN_FILES))
 libs::
 	$(INSTALL)  $(PATTERN_FILES) $(FINAL_TARGET)/hyphenation
-
-install::
-	$(SYSINSTALL) $(IFLAGS1) $(PATTERN_FILES) $(DESTDIR)$(mozappdir)/hyphenation
 endif
--- a/intl/unicharutil/tables/Makefile.in
+++ b/intl/unicharutil/tables/Makefile.in
@@ -16,11 +16,8 @@ include $(topsrcdir)/config/rules.mk
 
 ifeq ($(MOZ_WIDGET_TOOLKIT), qt)
 CFLAGS          += $(MOZ_QT_CFLAGS)
 CXXFLAGS        += $(MOZ_QT_CFLAGS)
 endif
 
 libs:: $(_PROP_TABLES)
 	$(INSTALL) $^ $(DIST)/bin/res/entityTables
-
-install:: $(_PROP_TABLES)
-	$(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/res/entityTables
--- a/js/public/GCAPI.h
+++ b/js/public/GCAPI.h
@@ -208,23 +208,28 @@ PokeGC(JSRuntime *rt);
 
 /* Was the most recent GC run incrementally? */
 extern JS_FRIEND_API(bool)
 WasIncrementalGC(JSRuntime *rt);
 
 extern JS_FRIEND_API(size_t)
 GetGCNumber();
 
-class AutoAssertNoGC {
+class JS_PUBLIC_API(AutoAssertNoGC)
+{
 #ifdef DEBUG
     size_t gcNumber;
 
   public:
     AutoAssertNoGC();
     ~AutoAssertNoGC();
+#else
+  public:
+    /* Prevent unreferenced local warnings in opt builds. */
+    AutoAssertNoGC() {}
 #endif
 };
 
 class JS_PUBLIC_API(ObjectPtr)
 {
     Heap<JSObject *> value;
 
   public:
@@ -306,11 +311,36 @@ ExposeValueToActiveJS(const Value &v)
 }
 
 static JS_ALWAYS_INLINE void
 ExposeObjectToActiveJS(JSObject *obj)
 {
     ExposeGCThingToActiveJS(obj, JSTRACE_OBJECT);
 }
 
+/*
+ * If a GC is currently marking, mark the object black.
+ */
+static JS_ALWAYS_INLINE void
+MarkGCThingAsLive(JSRuntime *rt_, void *thing, JSGCTraceKind kind)
+{
+    shadow::Runtime *rt = shadow::Runtime::asShadowRuntime(rt_);
+#ifdef JSGC_GENERATIONAL
+    /*
+     * Any object in the nursery will not be freed during any GC running at that time.
+     */
+    if (js::gc::IsInsideNursery(rt, thing))
+        return;
+#endif
+    if (IsIncrementalBarrierNeededOnGCThing(rt, thing, kind))
+        IncrementalReferenceBarrier(thing, kind);
+}
+
+static JS_ALWAYS_INLINE void
+MarkStringAsLive(Zone *zone, JSString *string)
+{
+    JSRuntime *rt = JS::shadow::Zone::asShadowZone(zone)->runtimeFromMainThread();
+    MarkGCThingAsLive(rt, string, JSTRACE_STRING);
+}
+
 } /* namespace JS */
 
 #endif /* js_GCAPI_h */
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -1244,16 +1244,18 @@ js_InitTypedObjectClass(JSContext *cx, H
     Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
 
     RootedObject objProto(cx, global->getOrCreateObjectPrototype(cx));
     if (!objProto)
         return nullptr;
 
     RootedObject module(cx, NewObjectWithClassProto(cx, &JSObject::class_,
                                                     objProto, global));
+    if (!module)
+        return nullptr;
 
     // Define TypedObject global.
 
     RootedValue moduleValue(cx, ObjectValue(*module));
 
     // uint8, uint16, etc
 
 #define BINARYDATA_NUMERIC_DEFINE(constant_, type_, name_)                      \
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -617,18 +617,23 @@ endif
 ifneq (WINNT_,$(OS_ARCH)_$(GNU_CC))
 LIBS_DIR	= -L$(DIST)/bin -L$(DIST)/lib
 ifdef LIBXUL_SDK
 LIBS_DIR	+= -L$(LIBXUL_SDK)/bin -L$(LIBXUL_SDK)/lib
 endif
 endif
 
 # Default location of include files
+ifndef LIBXUL_SDK
 IDL_PARSER_DIR = $(topsrcdir)/xpcom/idl-parser
 IDL_PARSER_CACHE_DIR = $(DEPTH)/xpcom/idl-parser
+else
+IDL_PARSER_DIR = $(LIBXUL_SDK)/sdk/bin
+IDL_PARSER_CACHE_DIR = $(LIBXUL_SDK)/sdk/bin
+endif
 
 SDK_LIB_DIR = $(DIST)/sdk/lib
 SDK_BIN_DIR = $(DIST)/sdk/bin
 
 DEPENDENCIES	= .md
 
 MOZ_COMPONENT_LIBS=$(XPCOM_LIBS) $(MOZ_COMPONENT_NSPR_LIBS)
 
rename from js/src/config/makefiles/target_libs.mk
rename to js/src/config/makefiles/target_binaries.mk
--- a/js/src/config/recurse.mk
+++ b/js/src/config/recurse.mk
@@ -107,16 +107,17 @@ endif
 $(addsuffix /Makefile,$(CURRENT_DIRS)) $(addsuffix /backend.mk,$(CURRENT_DIRS)):
 
 # The export tier requires nsinstall, which is built from config. So every
 # subdirectory traversal needs to happen after traversing config.
 ifeq ($(CURRENT_TIER),export)
 $(addsuffix /$(CURRENT_TIER),$(filter-out config,$(CURRENT_DIRS))): config/$(CURRENT_TIER)
 endif
 
+ifdef COMPILE_ENVIRONMENT
 ifneq (,$(filter libs binaries,$(CURRENT_TIER)))
 # When doing a "libs" build, target_libs.mk ensures the interesting dependency data
 # is available in the "binaries" stamp. Once recursion is done, aggregate all that
 # dependency info so that stamps depend on relevant files and relevant other stamps.
 # When doing a "binaries" build, the aggregate dependency file and those stamps are
 # used and allow to skip recursing directories where changes are not going to require
 # rebuild. A few directories, however, are still traversed all the time, mostly, the
 # gyp managed ones and js/src.
@@ -134,16 +135,18 @@ binaries-deps: $(addsuffix /binaries,$(C
 ifeq (recurse_binaries,$(MAKECMDGOALS))
 $(call include_deps,binaries-deps.mk)
 endif
 
 endif
 
 DIST_GARBAGE += binaries-deps.mk binaries-deps
 
+endif
+
 else
 
 # Don't recurse if MAKELEVEL is NO_RECURSE_MAKELEVEL as defined above, but
 # still recurse for externally managed make files (gyp-generated ones).
 ifeq ($(EXTERNALLY_MANAGED_MAKE_FILE)_$(NO_RECURSE_MAKELEVEL),_$(MAKELEVEL))
 
 compile binaries libs export tools::
 
@@ -204,16 +207,18 @@ ifeq (.,$(DEPTH))
 recurse_targets := $(addsuffix /binaries,$(binaries_dirs))
 ifdef recurse_targets
 # only js/src has binaries_dirs, and we want to adjust paths for it.
 want_abspaths = 1
 endif
 endif
 endif
 
+ifdef COMPILE_ENVIRONMENT
+
 # Aggregate all dependency files relevant to a binaries build except in
 # the mozilla top-level directory.
 ifneq (_.,$(recurse_targets)_$(DEPTH))
 ALL_DEP_FILES := \
   $(BINARIES_PP) \
   $(addsuffix .pp,$(addprefix $(MDDEPDIR)/,$(sort \
     $(TARGETS) \
     $(filter-out $(SOBJS) $(ASOBJS) $(EXCLUDED_OBJS),$(OBJ_TARGETS)) \
@@ -222,9 +227,11 @@ ALL_DEP_FILES := \
   $(NULL)
 endif
 
 binaries libs:: $(TARGETS) $(BINARIES_PP)
 ifneq (_.,$(recurse_targets)_$(DEPTH))
 	@$(if $(or $(recurse_targets),$^),$(call py_action,link_deps,-o binaries --group-all $(if $(want_abspaths),--abspaths )--topsrcdir $(topsrcdir) --topobjdir $(DEPTH) --dist $(DIST) $(ALL_DEP_FILES)))
 endif
 
+endif
+
 endif # ifdef MOZ_PSEUDO_DERECURSE
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -117,16 +117,17 @@ CSRCS += $(GTEST_CSRCS)
 endif
 
 ifdef GTEST_CMMSRCS
 CMMSRCS += $(GTEST_CMMSRCS)
 endif
 endif
 
 ifdef CPP_UNIT_TESTS
+ifdef COMPILE_ENVIRONMENT
 
 # Compile the tests to $(DIST)/bin.  Make lots of niceties available by default
 # through TestHarness.h, by modifying the list of includes and the libs against
 # which stuff links.
 CPPSRCS += $(CPP_UNIT_TESTS)
 CPP_UNIT_TEST_BINS := $(CPP_UNIT_TESTS:.cpp=$(BIN_SUFFIX))
 SIMPLE_PROGRAMS += $(CPP_UNIT_TEST_BINS)
 INCLUDES += -I$(DIST)/include/testing
@@ -148,16 +149,17 @@ cppunittests-remote:
 			--localLib=$(DEPTH)/dist/$(MOZ_APP_NAME) \
 			--dm_trans=$(DM_TRANS) \
 			--deviceIP=${TEST_DEVICE} \
 			$(subst .cpp,$(BIN_SUFFIX),$(CPP_UNIT_TESTS)) $(EXTRA_TEST_ARGS); \
 	else \
 		echo "please prepare your host with environment variables for TEST_DEVICE"; \
 	fi
 
+endif # COMPILE_ENVIRONMENT
 endif # CPP_UNIT_TESTS
 
 .PHONY: check
 
 ifdef PYTHON_UNIT_TESTS
 
 RUN_PYTHON_UNIT_TESTS := $(addsuffix -run,$(PYTHON_UNIT_TESTS))
 
@@ -298,16 +300,17 @@ HOST_PDBFILE=$(basename $(@F)).pdb
 endif
 
 # Don't build SIMPLE_PROGRAMS during the MOZ_PROFILE_GENERATE pass
 ifdef MOZ_PROFILE_GENERATE
 EXCLUDED_OBJS := $(SIMPLE_PROGRAMS:$(BIN_SUFFIX)=.$(OBJ_SUFFIX))
 SIMPLE_PROGRAMS :=
 endif
 
+ifdef COMPILE_ENVIRONMENT
 ifndef TARGETS
 TARGETS			= $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) $(SIMPLE_PROGRAMS) $(HOST_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS)
 endif
 
 COBJS = $(notdir $(CSRCS:.c=.$(OBJ_SUFFIX)))
 SOBJS = $(notdir $(SSRCS:.S=.$(OBJ_SUFFIX)))
 # CPPSRCS can have different extensions (eg: .cpp, .cc)
 CPPOBJS = $(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(CPPSRCS))))
@@ -323,16 +326,29 @@ HOST_COBJS = $(addprefix host_,$(notdir 
 # HOST_CPPOBJS can have different extensions (eg: .cpp, .cc)
 HOST_CPPOBJS = $(addprefix host_,$(notdir $(addsuffix .$(OBJ_SUFFIX),$(basename $(HOST_CPPSRCS)))))
 HOST_CMOBJS = $(addprefix host_,$(notdir $(HOST_CMSRCS:.m=.$(OBJ_SUFFIX))))
 HOST_CMMOBJS = $(addprefix host_,$(notdir $(HOST_CMMSRCS:.mm=.$(OBJ_SUFFIX))))
 ifndef HOST_OBJS
 _HOST_OBJS = $(HOST_COBJS) $(HOST_CPPOBJS) $(HOST_CMOBJS) $(HOST_CMMOBJS)
 HOST_OBJS = $(strip $(_HOST_OBJS))
 endif
+else
+LIBRARY :=
+SHARED_LIBRARY :=
+IMPORT_LIBRARY :=
+REAL_LIBRARY :=
+PROGRAM :=
+SIMPLE_PROGRAMS :=
+HOST_LIBRARY :=
+HOST_PROGRAM :=
+HOST_SIMPLE_PROGRAMS :=
+SDK_BINARY := $(filter %.py,$(SDK_BINARY))
+SDK_LIBRARY :=
+endif
 
 ALL_TRASH = \
 	$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
 	$(filter-out $(ASFILES),$(OBJS:.$(OBJ_SUFFIX)=.s)) $(OBJS:.$(OBJ_SUFFIX)=.ii) \
 	$(OBJS:.$(OBJ_SUFFIX)=.i) $(OBJS:.$(OBJ_SUFFIX)=.i_o) \
 	$(HOST_PROGOBJS) $(HOST_OBJS) $(IMPORT_LIBRARY) $(DEF_FILE)\
 	$(EXE_DEF_FILE) so_locations _gen _stubs $(wildcard *.res) $(wildcard *.RES) \
 	$(wildcard *.pdb) $(CODFILE) $(IMPORT_LIBRARY) \
@@ -608,18 +624,20 @@ endif
 # The root makefile doesn't want to do a plain export/libs, because
 # of the tiers and because of libxul. Suppress the default rules in favor
 # of something else. Makefiles which use this var *must* provide a sensible
 # default rule before including rules.mk
 ifndef SUPPRESS_DEFAULT_RULES
 default all::
 	$(MAKE) export
 ifdef MOZ_PSEUDO_DERECURSE
+ifdef COMPILE_ENVIRONMENT
 	$(MAKE) compile
 endif
+endif
 	$(MAKE) libs
 	$(MAKE) tools
 endif # SUPPRESS_DEFAULT_RULES
 
 ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),)
 ECHO := echo
 QUIET :=
 else
@@ -637,21 +655,23 @@ ifneq (,$(filter-out %.$(LIB_SUFFIX),$(S
 endif
 
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX),$(HOST_LIBS))
 
 # Dependencies which, if modified, should cause everything to rebuild
 GLOBAL_DEPS += Makefile $(DEPTH)/config/autoconf.mk $(topsrcdir)/config/config.mk
 
 ##############################################
+ifdef COMPILE_ENVIRONMENT
 OBJ_TARGETS = $(OBJS) $(PROGOBJS) $(HOST_OBJS) $(HOST_PROGOBJS)
 
 compile:: $(OBJ_TARGETS)
 
-include $(topsrcdir)/config/makefiles/target_libs.mk
+include $(topsrcdir)/config/makefiles/target_binaries.mk
+endif
 
 ifdef IS_TOOL_DIR
 # One would think "tools:: libs" would work, but it turns out that combined with
 # bug 907365, this makes make forget to run some rules sometimes.
 tools::
 	@$(MAKE) libs
 endif
 
@@ -1348,17 +1368,17 @@ endif
 
 ifneq ($(DIST_CHROME_FILES),)
 DIST_CHROME_FILES_PATH := $(FINAL_TARGET)/chrome
 DIST_CHROME_FILES_FLAGS := $(XULAPP_DEFINES)
 PP_TARGETS += DIST_CHROME_FILES
 endif
 
 ifneq ($(XPI_PKGNAME),)
-tools realchrome::
+libs realchrome::
 ifdef STRIP_XPI
 ifndef MOZ_DEBUG
 	@echo "Stripping $(XPI_PKGNAME) package directory..."
 	@echo $(FINAL_TARGET)
 	@cd $(FINAL_TARGET) && find . ! -type d \
 			! -name "*.js" \
 			! -name "*.xpt" \
 			! -name "*.gif" \
@@ -1387,17 +1407,17 @@ endif
 	cd $(FINAL_TARGET) && $(ZIP) -qr ../$(XPI_PKGNAME).xpi *
 endif
 
 ifdef INSTALL_EXTENSION_ID
 ifndef XPI_NAME
 $(error XPI_NAME must be set for INSTALL_EXTENSION_ID)
 endif
 
-tools::
+libs::
 	$(RM) -r "$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)"
 	$(NSINSTALL) -D "$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)"
 	$(call copy_dir,$(FINAL_TARGET),$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID))
 
 endif
 
 #############################################################################
 # MDDEPDIR is the subdirectory where all the dependency files are placed.
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -119,16 +119,17 @@ AC_SUBST(TOP_DIST)
 
 MOZ_DEFAULT_COMPILER
 
 COMPILE_ENVIRONMENT=1
 MOZ_ARG_DISABLE_BOOL(compile-environment,
 [  --disable-compile-environment
                           Disable compiler/library checks.],
     COMPILE_ENVIRONMENT= )
+AC_SUBST(COMPILE_ENVIRONMENT)
 
 dnl Check for Perl first -- needed for win32 SDK checks
 MOZ_PATH_PROGS(PERL, $PERL perl5 perl )
 if test -z "$PERL" -o "$PERL" = ":"; then
     AC_MSG_ERROR([perl not found in \$PATH])
 fi
 
 MOZ_ARG_ENABLE_BOOL(shared-js,
@@ -2084,17 +2085,20 @@ if test "$ENABLE_ION"; then
 fi
 
 AC_SUBST(ENABLE_YARR_JIT)
 
 if test "$ENABLE_YARR_JIT"; then
     AC_DEFINE(ENABLE_YARR_JIT)
 fi
 
-MOZ_COMPILER_OPTS
+if test -n "$COMPILE_ENVIRONMENT"; then
+    MOZ_COMPILER_OPTS
+fi
+
 if test -z "$SKIP_COMPILER_CHECKS"; then
 dnl Checks for typedefs, structures, and compiler characteristics.
 dnl ========================================================
 AC_HEADER_STDC
 AC_C_CONST
 AC_TYPE_MODE_T
 AC_TYPE_OFF_T
 AC_TYPE_PID_T
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -33,16 +33,17 @@
 #include "vm/Debugger.h"
 
 #include "jsatominlines.h"
 #include "jsobjinlines.h"
 #include "jsscriptinlines.h"
 
 #include "frontend/ParseMaps-inl.h"
 #include "frontend/ParseNode-inl.h"
+#include "vm/ScopeObject-inl.h"
 
 using namespace js;
 using namespace js::gc;
 using namespace js::frontend;
 
 using mozilla::DebugOnly;
 using mozilla::DoubleIsInt32;
 using mozilla::PodCopy;
@@ -1160,19 +1161,19 @@ TryConvertFreeName(BytecodeEmitter *bce,
         if (funbox->isHeavyweight()) {
             hops++;
             if (funbox->function()->isNamedLambda())
                 hops++;
         }
         if (bce->script->directlyInsideEval)
             return false;
         RootedObject outerScope(bce->sc->context, bce->script->enclosingStaticScope());
-        for (StaticScopeIter ssi(bce->sc->context, outerScope); !ssi.done(); ssi++) {
-            if (ssi.type() != StaticScopeIter::FUNCTION) {
-                if (ssi.type() == StaticScopeIter::BLOCK) {
+        for (StaticScopeIter<CanGC> ssi(bce->sc->context, outerScope); !ssi.done(); ssi++) {
+            if (ssi.type() != StaticScopeIter<CanGC>::FUNCTION) {
+                if (ssi.type() == StaticScopeIter<CanGC>::BLOCK) {
                     // Use generic ops if a catch block is encountered.
                     return false;
                 }
                 if (ssi.hasDynamicScopeObject())
                     hops++;
                 continue;
             }
             RootedScript script(bce->sc->context, ssi.funScript());
@@ -6441,16 +6442,21 @@ frontend::EmitTree(ExclusiveContext *cx,
         break;
 
       case PNK_LET:
         ok = pn->isArity(PN_BINARY)
              ? EmitLet(cx, bce, pn)
              : EmitVariables(cx, bce, pn, InitializeVars);
         break;
 
+      case PNK_IMPORT:
+       // TODO: Implement emitter support for modules
+       bce->reportError(nullptr, JSMSG_MODULES_NOT_IMPLEMENTED);
+       return false;
+
       case PNK_ARRAYPUSH: {
         int slot;
 
         /*
          * The array object's stack index is in bce->arrayCompDepth. See below
          * under the array initialiser code generator for array comprehension
          * special casing. Note that the array object is a pure stack value,
          * unaliased by blocks, so we can EmitUnaliasedVarOp.
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -290,16 +290,26 @@ class FullParseHandler
 
         list->append(stmt);
     }
 
     ParseNode *newEmptyStatement(const TokenPos &pos) {
         return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, pos, (ParseNode *) nullptr);
     }
 
+    ParseNode *newImportDeclaration(ParseNode *importSpecSet,
+                                    ParseNode *moduleSpec, const TokenPos &pos)
+    {
+        ParseNode *pn = new_<BinaryNode>(PNK_IMPORT, JSOP_NOP, pos,
+                                         importSpecSet, moduleSpec);
+        if (!pn)
+            return null();
+        return pn;
+    }
+
     ParseNode *newExprStatement(ParseNode *expr, uint32_t end) {
         JS_ASSERT(expr->pn_pos.end <= end);
         return new_<UnaryNode>(PNK_SEMI, JSOP_NOP, TokenPos(expr->pn_pos.begin, end), expr);
     }
 
     ParseNode *newIfStatement(uint32_t begin, ParseNode *cond, ParseNode *thenBranch,
                               ParseNode *elseBranch)
     {
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -123,16 +123,19 @@ class UpvarCookie
     F(DEBUGGER) \
     F(YIELD) \
     F(YIELD_STAR) \
     F(GENEXP) \
     F(ARRAYCOMP) \
     F(ARRAYPUSH) \
     F(LEXICALSCOPE) \
     F(LET) \
+    F(IMPORT) \
+    F(IMPORT_SPEC_LIST) \
+    F(IMPORT_SPEC) \
     F(SEQ) \
     F(FORIN) \
     F(FOROF) \
     F(FORHEAD) \
     F(ARGSBODY) \
     F(SPREAD) \
     \
     /* Unary operators. */ \
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -3623,16 +3623,144 @@ Parser<FullParseHandler>::letStatement()
 template <>
 SyntaxParseHandler::Node
 Parser<SyntaxParseHandler>::letStatement()
 {
     JS_ALWAYS_FALSE(abortIfSyntaxParser());
     return SyntaxParseHandler::NodeFailure;
 }
 
+template<typename ParseHandler>
+typename ParseHandler::Node
+Parser<ParseHandler>::importDeclaration()
+{
+    JS_ASSERT(tokenStream.currentToken().type == TOK_IMPORT);
+
+    if (pc->sc->isFunctionBox() || !pc->atBodyLevel()) {
+        report(ParseError, false, null(), JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
+        return null();
+    }
+
+    uint32_t begin = pos().begin;
+    TokenKind tt = tokenStream.getToken();
+
+    Node importSpecSet = handler.newList(PNK_IMPORT_SPEC_LIST);
+    if (!importSpecSet)
+        return null();
+
+    if (tt == TOK_NAME || tt == TOK_LC) {
+        if (tt == TOK_NAME) {
+            // Handle the form |import a from 'b'|, by adding a single import
+            // specifier to the list, with 'default' as the import name and
+            // 'a' as the binding name. This is equivalent to
+            // |import { default as a } from 'b'|.
+            Node importName = newName(context->names().default_);
+            if (!importName)
+                return null();
+
+            Node bindingName = newName(tokenStream.currentName());
+            if (!bindingName)
+                return null();
+
+            Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
+            if (!importSpec)
+                return null();
+
+            handler.addList(importSpecSet, importSpec);
+        } else {
+            do {
+                // Handle the forms |import {} from 'a'| and
+                // |import { ..., } from 'a'| (where ... is non empty), by
+                // escaping the loop early if the next token is }.
+                tt = tokenStream.peekToken(TokenStream::KeywordIsName);
+                if (tt == TOK_ERROR)
+                    return null();
+                if (tt == TOK_RC)
+                    break;
+
+                // If the next token is a keyword, the previous call to
+                // peekToken matched it as a TOK_NAME, and put it in the
+                // lookahead buffer, so this call will match keywords as well.
+                MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME);
+                Node importName = newName(tokenStream.currentName());
+                if (!importName)
+                    return null();
+
+                if (tokenStream.getToken() == TOK_NAME &&
+                    tokenStream.currentName() == context->names().as)
+                {
+                    if (tokenStream.getToken() != TOK_NAME) {
+                        report(ParseError, false, null(), JSMSG_NO_BINDING_NAME);
+                        return null();
+                    }
+                } else {
+                    // Keywords cannot be bound to themselves, so an import name
+                    // that is a keyword is a syntax error if it is not followed
+                    // by the keyword 'as'.
+                    if (IsKeyword(importName->name())) {
+                        JSAutoByteString bytes;
+                        if (!AtomToPrintableString(context, importName->name(), &bytes))
+                            return null();
+                        report(ParseError, false, null(), JSMSG_AS_AFTER_RESERVED_WORD, bytes.ptr());
+                        return null();
+                    }
+                    tokenStream.ungetToken();
+                }
+                Node bindingName = newName(tokenStream.currentName());
+                if (!bindingName)
+                    return null();
+
+                Node importSpec = handler.newBinary(PNK_IMPORT_SPEC, importName, bindingName);
+                if (!importSpec)
+                    return null();
+
+                handler.addList(importSpecSet, importSpec);
+            } while (tokenStream.matchToken(TOK_COMMA));
+
+            MUST_MATCH_TOKEN(TOK_RC, JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
+        }
+
+        if (tokenStream.getToken() != TOK_NAME ||
+            tokenStream.currentName() != context->names().from)
+        {
+            report(ParseError, false, null(), JSMSG_FROM_AFTER_IMPORT_SPEC_SET);
+            return null();
+        }
+
+        MUST_MATCH_TOKEN(TOK_STRING, JSMSG_MODULE_SPEC_AFTER_FROM);
+    } else {
+        if (tt != TOK_STRING) {
+            report(ParseError, false, null(), JSMSG_DECLARATION_AFTER_IMPORT);
+            return null();
+        }
+
+        // Handle the form |import 'a'| by leaving the list empty. This is
+        // equivalent to |import {} from 'a'|.
+        importSpecSet->pn_pos.end = importSpecSet->pn_pos.begin;
+    }
+
+    Node moduleSpec = stringLiteral();
+    if (!moduleSpec)
+        return null();
+
+    if (!MatchOrInsertSemicolon(tokenStream))
+        return null();
+
+    return handler.newImportDeclaration(importSpecSet, moduleSpec,
+                                        TokenPos(begin, pos().end));
+}
+
+template<>
+SyntaxParseHandler::Node
+Parser<SyntaxParseHandler>::importDeclaration()
+{
+    JS_ALWAYS_FALSE(abortIfSyntaxParser());
+    return SyntaxParseHandler::NodeFailure;
+}
+
 template <typename ParseHandler>
 typename ParseHandler::Node
 Parser<ParseHandler>::expressionStatement()
 {
     tokenStream.ungetToken();
     Node pnexpr = expr();
     if (!pnexpr)
         return null();
@@ -4902,16 +5030,18 @@ Parser<ParseHandler>::statement(bool can
 
         if (!MatchOrInsertSemicolon(tokenStream))
             return null();
         return pn;
       }
 
       case TOK_LET:
         return letStatement();
+      case TOK_IMPORT:
+        return importDeclaration();
       case TOK_SEMI:
         return handler.newEmptyStatement(pos());
       case TOK_IF:
         return ifStatement();
       case TOK_DO:
         return doWhileStatement();
       case TOK_WHILE:
         return whileStatement();
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -507,16 +507,17 @@ class Parser : private AutoGCRooter, pub
     Node returnStatement();
     Node withStatement();
     Node labeledStatement();
     Node throwStatement();
     Node tryStatement();
     Node debuggerStatement();
 
     Node letStatement();
+    Node importDeclaration();
     Node expressionStatement();
     Node variables(ParseNodeKind kind, bool *psimple = nullptr,
                    StaticBlockObject *blockObj = nullptr,
                    VarContext varContext = HoistVars);
     Node expr();
     Node assignExpr();
     Node assignExprWithoutYield(unsigned err);
     Node yieldExpression();
--- a/js/src/gc/Memory.cpp
+++ b/js/src/gc/Memory.cpp
@@ -292,17 +292,17 @@ gc::MarkPagesInUse(JSRuntime *rt, void *
 }
 
 size_t
 gc::GetPageFaultCount()
 {
     return 0;
 }
 
-#elif defined(XP_UNIX) || defined(XP_MACOSX) || defined(DARWIN)
+#elif defined(XP_UNIX)
 
 #include <sys/mman.h>
 #include <sys/resource.h>
 #include <unistd.h>
 
 void
 gc::InitMemorySubsystem(JSRuntime *rt)
 {
--- a/js/src/gc/Zone.cpp
+++ b/js/src/gc/Zone.cpp
@@ -34,16 +34,17 @@ JS::Zone::Zone(JSRuntime *rt)