Merge m-c to fx-team. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 03 Sep 2014 16:42:41 -0400
changeset 203444 d76eb4c469dcf342c4ddbb39dd3842e9c16d995e
parent 203443 ec6952a71088b6b978c93cb26aa9476f57f05b94 (current diff)
parent 203417 acbdce59da2fda8c1dce44802cfae8dd4147aabf (diff)
child 203445 65e611823b0fec328d56244143eae71fe019315c
push id27427
push userryanvm@gmail.com
push dateThu, 04 Sep 2014 02:32:42 +0000
treeherdermozilla-central@776fa9cf70cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone35.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge m-c to fx-team. a=merge
build/mozconfig.vs2010-common
dom/mobileconnection/interfaces/nsIMobileConnectionProvider.idl
ipc/chromium/src/base/base_paths.cc
ipc/chromium/src/base/base_paths.h
ipc/chromium/src/base/base_paths_linux.cc
ipc/chromium/src/base/base_paths_linux.h
ipc/chromium/src/base/base_paths_mac.h
ipc/chromium/src/base/base_paths_mac.mm
ipc/chromium/src/base/base_paths_win.cc
ipc/chromium/src/base/base_paths_win.h
ipc/chromium/src/base/hmac.h
ipc/chromium/src/base/hmac_mac.cc
ipc/chromium/src/base/path_service.cc
ipc/chromium/src/base/path_service.h
ipc/chromium/src/base/stats_counters.h
ipc/chromium/src/base/stats_table.cc
ipc/chromium/src/base/stats_table.h
ipc/chromium/src/base/system_monitor.cc
ipc/chromium/src/base/system_monitor.h
ipc/chromium/src/base/system_monitor_posix.cc
ipc/chromium/src/base/system_monitor_win.cc
ipc/chromium/src/base/trace_event.cc
ipc/chromium/src/base/trace_event.h
ipc/chromium/src/base/worker_pool.h
ipc/chromium/src/base/worker_pool_linux.h
ipc/chromium/src/base/worker_pool_mac.mm
js/src/jit/IonSpewer.cpp
js/src/jit/IonSpewer.h
layout/reftests/w3c-css/submitted/flexbox/flexbox-abspos-child-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-abspos-child-1a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-abspos-child-1b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-horiz-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-content-vert-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-5-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-baseline-horiz-5.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-1-block.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-1-table.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-5-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-horiz-5.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-stretch-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-stretch-vert-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-stretch-vert-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-stretch-vert-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-align-self-vert-rtl-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-anonymous-items-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-anonymous-items-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-align-self-baseline-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-align-self-baseline-horiz-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-align-self-baseline-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-align-self-baseline-vert-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-empty-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-empty-1a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-empty-1b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-item-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-item-horiz-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-item-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-item-vert-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-3-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-3.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-4-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-horiz-4.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-vert-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-vert-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-multi-line-vert-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-single-item-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-single-item-1a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-baseline-single-item-1b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-block-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-canvas-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-fieldset-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-iframe-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-img-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-img-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-img-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-img-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-textarea-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-textarea-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-textarea-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-textarea-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-video-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-video-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-video-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-basic-video-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-horiz-1a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-horiz-1b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-horiz-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-horiz-2a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-horiz-2b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-vert-1a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-vert-1b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-vert-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-vert-2a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-break-request-vert-2b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-baseline-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-baseline-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-horiz-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-horiz-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-horiz-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-horiz-3-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-collapsed-item-horiz-3.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-flow-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-flow-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-flow-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-flow-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-horiz-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-horiz-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-horiz-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-vert-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-vert-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-flex-wrap-vert-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-items-as-stacking-contexts-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-items-as-stacking-contexts-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-items-as-stacking-contexts-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-items-as-stacking-contexts-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-items-as-stacking-contexts-3-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-items-as-stacking-contexts-3.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-5-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-horiz-5.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-5-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-justify-content-vert-5.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-margin-auto-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-margin-auto-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-margin-auto-horiz-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-margin-auto-horiz-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-1-reverse-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-1-reverse.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-1-rtl-reverse.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-1-rtl.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-2a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-2b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-3-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-3-reverse-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-3-reverse.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-3.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-4-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-mbp-horiz-4.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-3-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-3.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-4-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-4.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-5-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-horiz-5.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-3-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-3.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-4-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-4.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-5-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-overflow-vert-5.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-paint-ordering-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-paint-ordering-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-paint-ordering-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-paint-ordering-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-root-node-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-root-node-1a.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-root-node-1b.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-horiz-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-horiz-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-horiz-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-horiz-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-vert-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-vert-1.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-vert-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-sizing-vert-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-table-fixup-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-table-fixup-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-table-fixup-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-whitespace-handling-1-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-whitespace-handling-1a.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-whitespace-handling-1b.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-whitespace-handling-2-ref.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-whitespace-handling-2.xhtml
layout/reftests/w3c-css/submitted/flexbox/flexbox-with-pseudo-elements-1-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-with-pseudo-elements-1.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-with-pseudo-elements-2-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-with-pseudo-elements-2.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-with-pseudo-elements-3-ref.html
layout/reftests/w3c-css/submitted/flexbox/flexbox-with-pseudo-elements-3.html
media/libvpx/vpx_rtcd.h
media/libvpx/vpx_rtcd_armv7-android-gcc.h
media/libvpx/vpx_rtcd_generic-gnu.h
media/libvpx/vpx_rtcd_x86-darwin9-gcc.h
media/libvpx/vpx_rtcd_x86-linux-gcc.h
media/libvpx/vpx_rtcd_x86-win32-vs8.h
media/libvpx/vpx_rtcd_x86_64-darwin9-gcc.h
media/libvpx/vpx_rtcd_x86_64-linux-gcc.h
media/libvpx/vpx_rtcd_x86_64-win64-vs8.h
--- a/.gdbinit
+++ b/.gdbinit
@@ -172,10 +172,10 @@ document ptarray
         ptarray a 1 2 - Prints elements in range [idx1..idx2] from tarray
 end
 
 def js
   call DumpJSStack()
 end
 
 def ft
-  call nsFrame::DumpFrameTree($arg0)
+  call $arg0->DumpFrameTree()
 end
--- a/accessible/xpcom/xpcAccessibleTable.h
+++ b/accessible/xpcom/xpcAccessibleTable.h
@@ -16,17 +16,20 @@ class nsIArray;
 namespace mozilla {
 namespace a11y {
 
 class TableAccessible;
 
 class xpcAccessibleTable
 {
 public:
-  explicit xpcAccessibleTable(mozilla::a11y::TableAccessible* aTable) : mTable(aTable) { }
+  explicit xpcAccessibleTable(TableAccessible* aTable) :
+    mTable(aTable)
+  {
+  }
 
   nsresult GetCaption(nsIAccessible** aCaption);
   nsresult GetSummary(nsAString& aSummary);
   nsresult GetColumnCount(int32_t* aColumnCount);
   nsresult GetRowCount(int32_t* aRowCount);
   nsresult GetCellAt(int32_t aRowIndex, int32_t aColumnIndex,
                      nsIAccessible** aCell);
   nsresult GetCellIndexAt(int32_t aRowIndex, int32_t aColumnIndex,
--- a/accessible/xpcom/xpcAccessibleTableCell.h
+++ b/accessible/xpcom/xpcAccessibleTableCell.h
@@ -20,18 +20,20 @@ class TableCellAccessible;
 
 /**
  * This class provides an implementation of the nsIAccessibleTableCell
  * interface's methods.
  */
 class xpcAccessibleTableCell
 {
 public:
-  explicit xpcAccessibleTableCell(mozilla::a11y::TableCellAccessible* aTableCell) :
-    mTableCell(aTableCell) { }
+  explicit xpcAccessibleTableCell(TableCellAccessible* aTableCell) :
+    mTableCell(aTableCell)
+  {
+  }
 
   nsresult GetTable(nsIAccessibleTable** aTable);
   nsresult GetColumnIndex(int32_t* aColIdx);
   nsresult GetRowIndex(int32_t* aRowIdx);
   nsresult GetColumnExtent(int32_t* aExtent);
   nsresult GetRowExtent(int32_t* aExtent);
   nsresult GetColumnHeaderCells(nsIArray** aHeaderCells);
   nsresult GetRowHeaderCells(nsIArray** aHeaderCells);
--- a/addon-sdk/test/browser.ini
+++ b/addon-sdk/test/browser.ini
@@ -2,14 +2,13 @@
 support-files =
   head.js
   Math.jsm
   math.js
   data.json
   invalid.json
 [browser_sdk_loader_sdk_modules.js]
 [browser_sdk_loader_sdk_gui_modules.js]
-skip-if = e10s # Bug ?????? - test times out.
 [browser_sdk_loader_jsm_modules.js]
 [browser_sdk_loader_js_modules.js]
 [browser_sdk_loader_json.js]
 [browser_sdk_loader_chrome.js]
 [browser_sdk_loader_chrome_in_sdk.js]
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -189,16 +189,34 @@ SettingsListener.observe('devtools.overl
     developerHUD.init();
   } else {
     if (developerHUD) {
       developerHUD.uninit();
     }
   }
 });
 
+#ifdef MOZ_WIDGET_GONK
+let LogShake;
+SettingsListener.observe('devtools.logshake', false, (value) => {
+  if (value) {
+    if (!LogShake) {
+      let scope = {};
+      Cu.import('resource://gre/modules/LogShake.jsm', scope);
+      LogShake = scope.LogShake;
+    }
+    LogShake.init();
+  } else {
+    if (LogShake) {
+      LogShake.uninit();
+    }
+  }
+});
+#endif
+
 // =================== Device Storage ====================
 SettingsListener.observe('device.storage.writable.name', 'sdcard', function(value) {
   if (Services.prefs.getPrefType('device.storage.writable.name') != Ci.nsIPrefBranch.PREF_STRING) {
     // We clear the pref because it used to be erroneously written as a bool
     // and we need to clear it before we can change it to have the correct type.
     Services.prefs.clearUserPref('device.storage.writable.name');
   }
   Services.prefs.setCharPref('device.storage.writable.name', value);
new file mode 100644
--- /dev/null
+++ b/b2g/components/LogCapture.jsm
@@ -0,0 +1,91 @@
+/* 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/. */
+/* jshint moz: true */
+/* global Uint8Array, Components, dump */
+
+'use strict';
+
+this.EXPORTED_SYMBOLS = ['LogCapture'];
+
+/**
+ * readLogFile
+ * Read in /dev/log/{{log}} in nonblocking mode, which will return -1 if
+ * reading would block the thread.
+ *
+ * @param log {String} The log from which to read. Must be present in /dev/log
+ * @return {Uint8Array} Raw log data
+ */
+let readLogFile = function(logLocation) {
+  if (!this.ctypes) {
+    // load in everything on first use
+    Components.utils.import('resource://gre/modules/ctypes.jsm', this);
+
+    this.lib = this.ctypes.open(this.ctypes.libraryName('c'));
+
+    this.read = this.lib.declare('read',
+      this.ctypes.default_abi,
+      this.ctypes.int,       // bytes read (out)
+      this.ctypes.int,       // file descriptor (in)
+      this.ctypes.voidptr_t, // buffer to read into (in)
+      this.ctypes.size_t     // size_t size of buffer (in)
+    );
+
+    this.open = this.lib.declare('open',
+      this.ctypes.default_abi,
+      this.ctypes.int,      // file descriptor (returned)
+      this.ctypes.char.ptr, // path
+      this.ctypes.int       // flags
+    );
+
+    this.close = this.lib.declare('close',
+      this.ctypes.default_abi,
+      this.ctypes.int, // error code (returned)
+      this.ctypes.int  // file descriptor
+    );
+  }
+
+  const O_READONLY = 0;
+  const O_NONBLOCK = 1 << 11;
+
+  const BUF_SIZE = 2048;
+
+  let BufType = this.ctypes.ArrayType(this.ctypes.char);
+  let buf = new BufType(BUF_SIZE);
+  let logArray = [];
+
+  let logFd = this.open(logLocation, O_READONLY | O_NONBLOCK);
+  if (logFd === -1) {
+    return null;
+  }
+
+  let readStart = Date.now();
+  let readCount = 0;
+  while (true) {
+    let count = this.read(logFd, buf, BUF_SIZE);
+    readCount += 1;
+
+    if (count <= 0) {
+      // log has return due to being nonblocking or running out of things
+      break;
+    }
+    for(let i = 0; i < count; i++) {
+      logArray.push(buf[i]);
+    }
+  }
+
+  let logTypedArray = new Uint8Array(logArray);
+
+  this.close(logFd);
+
+  return logTypedArray;
+};
+
+let cleanup = function() {
+  this.lib.close();
+  this.read = this.open = this.close = null;
+  this.lib = null;
+  this.ctypes = null;
+};
+
+this.LogCapture = { readLogFile: readLogFile, cleanup: cleanup };
new file mode 100644
--- /dev/null
+++ b/b2g/components/LogParser.jsm
@@ -0,0 +1,301 @@
+/* jshint esnext: true */
+/* global DataView */
+
+"use strict";
+
+this.EXPORTED_SYMBOLS = ["LogParser"];
+
+/**
+ * Parse an array read from a /dev/log/ file. Format taken from
+ * kernel/drivers/staging/android/logger.h and system/core/logcat/logcat.cpp
+ *
+ * @param array {Uint8Array} Array read from /dev/log/ file
+ * @return {Array} List of log messages
+ */
+function parseLogArray(array) {
+  let data = new DataView(array.buffer);
+  let byteString = String.fromCharCode.apply(null, array);
+
+  let logMessages = [];
+  let pos = 0;
+
+  while (pos < byteString.length) {
+    // Parse a single log entry
+
+    // Track current offset from global position
+    let offset = 0;
+
+    // Length of the entry, discarded
+    let length = data.getUint32(pos + offset, true);
+    offset += 4;
+    // Id of the process which generated the message
+    let processId = data.getUint32(pos + offset, true);
+    offset += 4;
+    // Id of the thread which generated the message
+    let threadId = data.getUint32(pos + offset, true);
+    offset += 4;
+    // Seconds since epoch when this message was logged
+    let seconds = data.getUint32(pos + offset, true);
+    offset += 4;
+    // Nanoseconds since the last second
+    let nanoseconds = data.getUint32(pos + offset, true);
+    offset += 4;
+
+    // Priority in terms of the ANDROID_LOG_* constants (see below)
+    // This is where the length field begins counting
+    let priority = data.getUint8(pos + offset);
+
+    // Reset pos and offset to count from here
+    pos += offset;
+    offset = 0;
+    offset += 1;
+
+    // Read the tag and message, represented as null-terminated c-style strings
+    let tag = "";
+    while (byteString[pos + offset] != "\0") {
+      tag += byteString[pos + offset];
+      offset ++;
+    }
+    offset ++;
+
+    let message = "";
+    // The kernel log driver may have cut off the null byte (logprint.c)
+    while (byteString[pos + offset] != "\0" && offset < length) {
+      message += byteString[pos + offset];
+      offset ++;
+    }
+
+    // Un-skip the missing null terminator
+    if (offset === length) {
+      offset --;
+    }
+
+    offset ++;
+
+    pos += offset;
+
+    // Log messages are occasionally delimited by newlines, but are also
+    // sometimes followed by newlines as well
+    if (message.charAt(message.length - 1) === "\n") {
+      message = message.substring(0, message.length - 1);
+    }
+
+    // Add an aditional time property to mimic the milliseconds since UTC
+    // expected by Date
+    let time = seconds * 1000.0 + nanoseconds/1000000.0;
+
+    // Log messages with interleaved newlines are considered to be separate log
+    // messages by logcat
+    for (let lineMessage of message.split("\n")) {
+      logMessages.push({
+        processId: processId,
+        threadId: threadId,
+        seconds: seconds,
+        nanoseconds: nanoseconds,
+        time: time,
+        priority: priority,
+        tag: tag,
+        message: lineMessage + "\n"
+      });
+    }
+  }
+
+  return logMessages;
+}
+
+/**
+ * Get a thread-time style formatted string from time
+ * @param time {Number} Milliseconds since epoch
+ * @return {String} Formatted time string
+ */
+function getTimeString(time) {
+  let date = new Date(time);
+  function pad(number) {
+    if ( number < 10 ) {
+      return "0" + number;
+    }
+    return number;
+  }
+  return pad( date.getMonth() + 1 ) +
+         "-" + pad( date.getDate() ) +
+         " " + pad( date.getHours() ) +
+         ":" + pad( date.getMinutes() ) +
+         ":" + pad( date.getSeconds() ) +
+         "." + (date.getMilliseconds() / 1000).toFixed(3).slice(2, 5);
+}
+
+/**
+ * Pad a string using spaces on the left
+ * @param str   {String} String to pad
+ * @param width {Number} Desired string length
+ */
+function padLeft(str, width) {
+  while (str.length < width) {
+    str = " " + str;
+  }
+  return str;
+}
+
+/**
+ * Pad a string using spaces on the right
+ * @param str   {String} String to pad
+ * @param width {Number} Desired string length
+ */
+function padRight(str, width) {
+  while (str.length < width) {
+    str = str + " ";
+  }
+  return str;
+}
+
+/** Constant values taken from system/core/liblog */
+const ANDROID_LOG_UNKNOWN = 0;
+const ANDROID_LOG_DEFAULT = 1;
+const ANDROID_LOG_VERBOSE = 2;
+const ANDROID_LOG_DEBUG   = 3;
+const ANDROID_LOG_INFO    = 4;
+const ANDROID_LOG_WARN    = 5;
+const ANDROID_LOG_ERROR   = 6;
+const ANDROID_LOG_FATAL   = 7;
+const ANDROID_LOG_SILENT  = 8;
+
+/**
+ * Map a priority number to its abbreviated string equivalent
+ * @param priorityNumber {Number} Log-provided priority number
+ * @return {String} Priority number's abbreviation
+ */
+function getPriorityString(priorityNumber) {
+  switch (priorityNumber) {
+  case ANDROID_LOG_VERBOSE:
+    return "V";
+  case ANDROID_LOG_DEBUG:
+    return "D";
+  case ANDROID_LOG_INFO:
+    return "I";
+  case ANDROID_LOG_WARN:
+    return "W";
+  case ANDROID_LOG_ERROR:
+    return "E";
+  case ANDROID_LOG_FATAL:
+    return "F";
+  case ANDROID_LOG_SILENT:
+    return "S";
+  default:
+    return "?";
+  }
+}
+
+
+/**
+ * Mimic the logcat "threadtime" format, generating a formatted string from a
+ * log message object.
+ * @param logMessage {Object} A log message from the list returned by parseLogArray
+ * @return {String} threadtime formatted summary of the message
+ */
+function formatLogMessage(logMessage) {
+  // MM-DD HH:MM:SS.ms pid tid priority tag: message
+  // from system/core/liblog/logprint.c:
+  return getTimeString(logMessage.time) +
+         " " + padLeft(""+logMessage.processId, 5) +
+         " " + padLeft(""+logMessage.threadId, 5) +
+         " " + getPriorityString(logMessage.priority) +
+         " " + padRight(logMessage.tag, 8) +
+         ": " + logMessage.message;
+}
+
+/**
+ * Pretty-print an array of bytes read from a log file by parsing then
+ * threadtime formatting its entries.
+ * @param array {Uint8Array} Array of a log file's bytes
+ * @return {String} Pretty-printed log
+ */
+function prettyPrintLogArray(array) {
+  let logMessages = parseLogArray(array);
+  return logMessages.map(formatLogMessage).join("");
+}
+
+/**
+ * Parse an array of bytes as a properties file. The structure of the
+ * properties file is derived from bionic/libc/bionic/system_properties.c
+ * @param array {Uint8Array} Array containing property data
+ * @return {Object} Map from property name to property value, both strings
+ */
+function parsePropertiesArray(array) {
+  let data = new DataView(array.buffer);
+  let byteString = String.fromCharCode.apply(null, array);
+
+  let properties = {};
+
+  let propIndex = 0;
+  let propCount = data.getUint32(0, true);
+
+  // first TOC entry is at 32
+  let tocOffset = 32;
+
+  const PROP_NAME_MAX = 32;
+  const PROP_VALUE_MAX = 92;
+
+  while (propIndex < propCount) {
+    // Retrieve offset from file start
+    let infoOffset = data.getUint32(tocOffset, true) & 0xffffff;
+
+    // Now read the name, integer serial, and value
+    let propName = "";
+    let nameOffset = infoOffset;
+    while (byteString[nameOffset] != "\0" &&
+           (nameOffset - infoOffset) < PROP_NAME_MAX) {
+      propName += byteString[nameOffset];
+      nameOffset ++;
+    }
+
+    infoOffset += PROP_NAME_MAX;
+    // Skip serial number
+    infoOffset += 4;
+
+    let propValue = "";
+    nameOffset = infoOffset;
+    while (byteString[nameOffset] != "\0" &&
+           (nameOffset - infoOffset) < PROP_VALUE_MAX) {
+      propValue += byteString[nameOffset];
+      nameOffset ++;
+    }
+
+    // Move to next table of contents entry
+    tocOffset += 4;
+
+    properties[propName] = propValue;
+    propIndex += 1;
+  }
+
+  return properties;
+}
+
+/**
+ * Pretty-print an array read from the /dev/__properties__ file.
+ * @param array {Uint8Array} File data array
+ * @return {String} Human-readable string of property name: property value
+ */
+function prettyPrintPropertiesArray(array) {
+  let properties = parsePropertiesArray(array);
+  let propertiesString = "";
+  for(let propName in properties) {
+    propertiesString += propName + ": " + properties[propName] + "\n";
+  }
+  return propertiesString;
+}
+
+/**
+ * Pretty-print a normal array. Does nothing.
+ * @param array {Uint8Array} Input array
+ */
+function prettyPrintArray(array) {
+  return array;
+}
+
+this.LogParser = {
+  parseLogArray: parseLogArray,
+  parsePropertiesArray: parsePropertiesArray,
+  prettyPrintArray: prettyPrintArray,
+  prettyPrintLogArray: prettyPrintLogArray,
+  prettyPrintPropertiesArray: prettyPrintPropertiesArray
+};
new file mode 100644
--- /dev/null
+++ b/b2g/components/LogShake.jsm
@@ -0,0 +1,301 @@
+/* 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/. */
+
+/**
+ * LogShake is a module which listens for log requests sent by Gaia. In
+ * response to a sufficiently large acceleration (a shake), it will save log
+ * files to an arbitrary directory which it will then return on a
+ * 'capture-logs-success' event with detail.logFilenames representing each log
+ * file's filename in the directory. If an error occurs it will instead produce
+ * a 'capture-logs-error' event.
+ */
+
+/* enable Mozilla javascript extensions and global strictness declaration,
+ * disable valid this checking */
+/* jshint moz: true */
+/* jshint -W097 */
+/* jshint -W040 */
+/* global Services, Components, dump, LogCapture, LogParser,
+   OS, Promise, volumeService, XPCOMUtils, SystemAppProxy */
+
+'use strict';
+
+const Cu = Components.utils;
+const Ci = Components.interfaces;
+
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+
+XPCOMUtils.defineLazyModuleGetter(this, 'LogCapture', 'resource://gre/modules/LogCapture.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'LogParser', 'resource://gre/modules/LogParser.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'OS', 'resource://gre/modules/osfile.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'Promise', 'resource://gre/modules/Promise.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'Services', 'resource://gre/modules/Services.jsm');
+XPCOMUtils.defineLazyModuleGetter(this, 'SystemAppProxy', 'resource://gre/modules/SystemAppProxy.jsm');
+
+XPCOMUtils.defineLazyServiceGetter(this, 'powerManagerService',
+                                   '@mozilla.org/power/powermanagerservice;1',
+                                   'nsIPowerManagerService');
+
+XPCOMUtils.defineLazyServiceGetter(this, 'volumeService',
+                                   '@mozilla.org/telephony/volume-service;1',
+                                   'nsIVolumeService');
+
+this.EXPORTED_SYMBOLS = ['LogShake'];
+
+function debug(msg) {
+  dump('LogShake.jsm: '+msg+'\n');
+}
+
+/**
+ * An empirically determined amount of acceleration corresponding to a
+ * shake
+ */
+const EXCITEMENT_THRESHOLD = 500;
+const DEVICE_MOTION_EVENT = 'devicemotion';
+const SCREEN_CHANGE_EVENT = 'screenchange';
+const CAPTURE_LOGS_ERROR_EVENT = 'capture-logs-error';
+const CAPTURE_LOGS_SUCCESS_EVENT = 'capture-logs-success';
+
+// Map of files which have log-type information to their parsers
+const LOGS_WITH_PARSERS = {
+  '/dev/__properties__': LogParser.prettyPrintPropertiesArray,
+  '/dev/log/main': LogParser.prettyPrintLogArray,
+  '/dev/log/system': LogParser.prettyPrintLogArray,
+  '/dev/log/radio': LogParser.prettyPrintLogArray,
+  '/dev/log/events': LogParser.prettyPrintLogArray,
+  '/proc/cmdline': LogParser.prettyPrintArray,
+  '/proc/kmsg': LogParser.prettyPrintArray,
+  '/proc/meminfo': LogParser.prettyPrintArray,
+  '/proc/uptime': LogParser.prettyPrintArray,
+  '/proc/version': LogParser.prettyPrintArray,
+  '/proc/vmallocinfo': LogParser.prettyPrintArray,
+  '/proc/vmstat': LogParser.prettyPrintArray
+};
+
+let LogShake = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+  /**
+   * If LogShake is listening for device motion events. Required due to lag
+   * between HAL layer of device motion events and listening for device motion
+   * events.
+   */
+  deviceMotionEnabled: false,
+
+  /**
+   * If a capture has been requested and is waiting for reads/parsing. Used for
+   * debouncing.
+   */
+  captureRequested: false,
+
+  /**
+   * Start existing, observing motion events if the screen is turned on.
+   */
+  init: function() {
+    // TODO: no way of querying screen state from power manager
+    // this.handleScreenChangeEvent({ detail: {
+    //   screenEnabled: powerManagerService.screenEnabled
+    // }});
+
+    // However, the screen is always on when we are being enabled because it is
+    // either due to the phone starting up or a user enabling us directly.
+    this.handleScreenChangeEvent({ detail: {
+      screenEnabled: true
+    }});
+
+    SystemAppProxy.addEventListener(SCREEN_CHANGE_EVENT, this, false);
+
+    Services.obs.addObserver(this, 'xpcom-shutdown', false);
+  },
+
+  /**
+   * Handle an arbitrary event, passing it along to the proper function
+   */
+  handleEvent: function(event) {
+    switch (event.type) {
+    case DEVICE_MOTION_EVENT:
+      if (!this.deviceMotionEnabled) {
+        return;
+      }
+      this.handleDeviceMotionEvent(event);
+      break;
+
+    case SCREEN_CHANGE_EVENT:
+      this.handleScreenChangeEvent(event);
+      break;
+    }
+  },
+
+  /**
+   * Handle an observation from Services.obs
+   */
+  observe: function(subject, topic) {
+    if (topic === 'xpcom-shutdown') {
+      this.uninit();
+    }
+  },
+
+  startDeviceMotionListener: function() {
+    if (!this.deviceMotionEnabled) {
+      SystemAppProxy.addEventListener(DEVICE_MOTION_EVENT, this, false);
+      this.deviceMotionEnabled = true;
+    }
+  },
+
+  stopDeviceMotionListener: function() {
+    SystemAppProxy.removeEventListener(DEVICE_MOTION_EVENT, this, false);
+    this.deviceMotionEnabled = false;
+  },
+
+  /**
+   * Handle a motion event, keeping track of 'excitement', the magnitude
+   * of the device's acceleration.
+   */
+  handleDeviceMotionEvent: function(event) {
+    // There is a lag between disabling the event listener and event arrival
+    // ceasing.
+    if (!this.deviceMotionEnabled) {
+      return;
+    }
+
+    var acc = event.accelerationIncludingGravity;
+
+    var excitement = acc.x * acc.x + acc.y * acc.y + acc.z * acc.z;
+
+    if (excitement > EXCITEMENT_THRESHOLD) {
+      if (!this.captureRequested) {
+        this.captureRequested = true;
+        captureLogs().then(logResults => {
+          // On resolution send the success event to the requester
+          SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_SUCCESS_EVENT, {
+            logFilenames: logResults.logFilenames,
+            logPrefix: logResults.logPrefix
+          });
+          this.captureRequested = false;
+        },
+        error => {
+          // On an error send the error event
+          SystemAppProxy._sendCustomEvent(CAPTURE_LOGS_ERROR_EVENT, {error: error});
+          this.captureRequested = false;
+        });
+      }
+    }
+  },
+
+  handleScreenChangeEvent: function(event) {
+    if (event.detail.screenEnabled) {
+      this.startDeviceMotionListener();
+    } else {
+      this.stopDeviceMotionListener();
+    }
+  },
+
+  /**
+   * Stop logshake, removing all listeners
+   */
+  uninit: function() {
+    this.stopDeviceMotionListener();
+    SystemAppProxy.removeEventListener(SCREEN_CHANGE_EVENT, this, false);
+    Services.obs.removeObserver(this, 'xpcom-shutdown');
+  }
+};
+
+function getLogFilename(logLocation) {
+  // sanitize the log location
+  let logName = logLocation.replace(/\//g, '-');
+  if (logName[0] === '-') {
+    logName = logName.substring(1);
+  }
+  return logName + '.log';
+}
+
+function getSdcardPrefix() {
+  return volumeService.getVolumeByName('sdcard').mountPoint;
+}
+
+function getLogDirectory() {
+  let d = new Date();
+  d = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
+  let timestamp = d.toISOString().slice(0, -5).replace(/[:T]/g, '-');
+  // return directory name of format 'logs/timestamp/'
+  return OS.Path.join('logs', timestamp, '');
+}
+
+/**
+ * Captures and saves the current device logs, returning a promise that will
+ * resolve to an array of log filenames.
+ */
+function captureLogs() {
+  let logArrays = readLogs();
+  return saveLogs(logArrays);
+}
+
+/**
+ * Read in all log files, returning their formatted contents
+ */
+function readLogs() {
+  let logArrays = {};
+  for (let loc in LOGS_WITH_PARSERS) {
+    let logArray = LogCapture.readLogFile(loc);
+    if (!logArray) {
+      continue;
+    }
+    let prettyLogArray = LOGS_WITH_PARSERS[loc](logArray);
+
+    logArrays[loc] = prettyLogArray;
+  }
+  return logArrays;
+}
+
+/**
+ * Save the formatted arrays of log files to an sdcard if available
+ */
+function saveLogs(logArrays) {
+  if (!logArrays || Object.keys(logArrays).length === 0) {
+    return Promise.resolve({
+      logFilenames: [],
+      logPrefix: ''
+    });
+  }
+
+  let sdcardPrefix, dirName;
+  try {
+    sdcardPrefix = getSdcardPrefix();
+    dirName = getLogDirectory();
+  } catch(e) {
+    // Return promise failed with exception e
+    // Handles missing sdcard
+    return Promise.reject(e);
+  }
+
+  debug('making a directory all the way from '+sdcardPrefix+' to '+(sdcardPrefix + '/' + dirName));
+  return OS.File.makeDir(OS.Path.join(sdcardPrefix, dirName), {from: sdcardPrefix})
+    .then(function() {
+    // Now the directory is guaranteed to exist, save the logs
+    let logFilenames = [];
+    let saveRequests = [];
+
+    for (let logLocation in logArrays) {
+      debug('requesting save of ' + logLocation);
+      let logArray = logArrays[logLocation];
+      // The filename represents the relative path within the SD card, not the
+      // absolute path because Gaia will refer to it using the DeviceStorage
+      // API
+      let filename = dirName + getLogFilename(logLocation);
+      logFilenames.push(filename);
+      let saveRequest = OS.File.writeAtomic(OS.Path.join(sdcardPrefix, filename), logArray);
+      saveRequests.push(saveRequest);
+    }
+
+    return Promise.all(saveRequests).then(function() {
+      debug('returning logfilenames: '+logFilenames.toSource());
+      return {
+        logFilenames: logFilenames,
+        logPrefix: dirName
+      };
+    });
+  });
+}
+
+LogShake.init();
+this.LogShake = LogShake;
--- a/b2g/components/moz.build
+++ b/b2g/components/moz.build
@@ -47,16 +47,19 @@ if CONFIG['MOZ_UPDATER']:
     ]
 
 EXTRA_JS_MODULES += [
     'AlertsHelper.jsm',
     'AppFrames.jsm',
     'ContentRequestHelper.jsm',
     'ErrorPage.jsm',
     'FxAccountsMgmtService.jsm',
+    'LogCapture.jsm',
+    'LogParser.jsm',
+    'LogShake.jsm',
     'SignInToWebsite.jsm',
     'SystemAppProxy.jsm',
     'TelURIParser.jsm',
     'WebappsUpdater.jsm',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
     EXTRA_JS_MODULES += [
new file mode 100644
index 0000000000000000000000000000000000000000..b1ed7f10ae86e16e9e6f1b14006182ceb278f5e3
GIT binary patch
literal 4037
zc%1E*zi!h|6o+p_(;=#aSn0rNg%k(kI!QqlAPNzsfKV$Sf`tLy`ko|Koa@McB47(M
z8xN3~M_}kwsiHz+gEwGd?gQW($Hhr)a$}MK(IJlFocrDLJB~jqc|yqfOz>K|utYM>
z@#TdVmdS`XKxM5AirYl6v5UNc1*jXg!5iRp$b*=r=fb648v$RtXme_U<5CwvZ&Kb6
zYgM25h#Rg!P2;V9q5$e9lt9_F)E#67Es*<@&<@k7&87!$55d(Coc~mi07n^uDfVF|
zs?T}b^0<racgrEUxBv8t1o<>c@GGD^LC!>k)8L=)u1bI-h=h)p$7j)7E@lVdEw5u5
zy1)fcrCi9JmH(UNy{#YWS^0lfULBS{6Al&S2S=H}>KenYwr5&;OY8cdwerS|o9iXm
zL*WeF;*P=4Mh11uhHlg^xf6Frp{WhG4$8eI>aBs|F2<09bhVbz=?F^Q@ri!DlOrz^
z!);;L&=KM@7Qv-<16|M@*Rp8?wV>Y;4Eut+ptZTHIjDQK|E)_!|Kv`(*wKI@@HJ3&
zLi0v1&$o8Jw!m*)l0Zfff_NR2;Y<fZyd8ml7tmEQe3Fj`*48Lzwq>waK~!)&9UZ6c
zndTet!plU|WME`W)PI)+eEg7)@96IVCySye@-PM<G3e3BCOkfO)3M`khYe6_P3qrx
zNjvOY{o0pOc12=`I95W2>evpCkH4<Y)Dt0e_MQmIa-J9sH+N4=5nI+1pMB(^+z&wB
z6GuLDdu4{67z0l42?03VEGnrzF##~y6Cq$8o|uB2(i4k%zm}~~nZF(>Jt1~je1A}!
ZsV73{>^%{Z<vcMOZtk9#BKDs=@eBW@U8n#6
new file mode 100644
index 0000000000000000000000000000000000000000..a8254853738e2083fbea3c659e4346c141214f2f
GIT binary patch
literal 65536
zc%1EB+j`r^wMHb_a$-BNb84D{qo!`!rX)yEltj6w?bvQ(*S1{AahjgcAut4C;Uo+|
zitfJPx1Vf3!oJ$?u<!Q+^dFEE0T56eiv#syetjSe%mDu!*Q_<O2L3-qQT~5TQJ(DY
zJsIrXxu@iDNqK90Nx7!HuDm^dUAdyXp<El|P%bN%$2f53^7x8!6@Qn<IFvV)H^*-x
z_FKyP<F|14n)31Zn)04<9oN@!^)}x3w(`F64&uLq-**xIE`HxremH(l`2ZnT$L}Nd
z4{*kTJ6Fdzlplf@hw>qw{}ACH;rb)I?PKMg@yCe$iSpt26U4rO`!^8&DbAnby&KBA
z;|<*Zk#c2>L-`Ep_zX||7`!-?n>gRZ(?3x@8RJks$N6)l;-|>(PjUS-r0Zvh_jBdF
z@y~Jp3+1En7dZa{;lBWH4f(AheRbu7aUG?jB0VbD8+cCx&o%M>CayJHYbc!-o^K(y
zn@Ha#a@9usHqyC;^A@hRamJzSAl?q%-$A?%p5Ik&jCXOqh45R*-!F0gCBlD&eE$m1
z{Tk`{HTZsm=YE6xzeT!#i}?S6bmLHND?b?DMmc<`yfOX~*LRSfJK(vC=kB6Z@8Lc7
z5dU|G|2v$2k82#tSE#42kgxl=zK`c0pgbSo{vUAt2c+X6>gOS9`w`yr2<OL${}|zW
z;M+qvJ;51=@<)^p4rL$beOw>lJ`Uxn^6B^~&R^p_U*r4?>3)Xt_(r)t{s!gxC%pGh
zNawexzi&}~e@47NgZD28{|mzZitxXpUjK&o{SEEo@3{Uu!gbV(j(q$B<@XOfPf+g!
z<<!M>7w<6;jzck#9}{PaGevk0;XRx!@ZeDT$Y&qdHqvF|{m&8p9M^}4e~9vSP+m9`
z7xnDoJs$FpL-CPbANdGSPXXHL5z=>rbBJ?@^f5fg5I;gbB9vQ<c8x<B;5<P15bqx%
z{xPnP@tzUljllB)>Bgb_6Yu{gdgp&4jS><P60d;JSG&F+sfO<{-=RfO)}v_j)xpE2
zQ2ss%%^?Yk60mk;_^uH06hHrQd}7jYA<C79+S5C&W>eFezh8PG%=oG68YNNIqA)J3
zm}T-a8rsD1{DLT#I$FDDP_iYGze^bH63;A%vg$Hn)zA4)$$Ek+^6&a)X%(->-l69Y
zJrVQ?e|ga-5MBPKbiD+k``;;|CxK}B6VidrY`?UAUlSvFPxyPpi2QIAQ5KyGKchxm
zUi#wsiR1V~)%A@-)$t7y<*VW~O)S4jyRl`FZt>_Vm_MK)vl-<7h^Z_JZ6nhCK&M_R
zITw1wVWI}0H2<(~N7S+N&2XcEz=*mH8X1j~I64UeKVa&y>nw{uW?ila^=xY%zM?2w
zrcJEcWR%dEYtH@&wWt=l9*y)aaceGNOlRmw#G*A~c3+a;_H2+33^k?$>P1CDcs-0g
z&-Sc>ptA$*&j?3Bgl-s-sIZnV#~$^PNVIf}cx4QH$5aC!_1R;(Ng|?~zL!mg=>FG@
zZKT02&D+HX2M5~L1Ht^J%>svv3evILbBIgp)U!6)>gL8IH5<58pZEQ)?WwJ%)^2V$
zcT`QoFuA?KC3*djj@b9%AMlRgd#a79rY@Qynf0p=%c+)_{~13s4|7pgw9eUiUYg&4
zCg!2M=TTPo?>(%JKco&N8F9OcS{Ki6mh^r_`S^fD8xLY{V`FDS({8nzx3ry&CwHH2
z@W!xIel?B?jG#Br<XYPHR!iGCE88jj(I_a%|0)$Edo%noE7N~3PWql;{=Q$L{wZ&D
zeHS)D6thG>I@54l&L0u0L|(oAedO6I@CTu9#zv%a8>}dE7ZUj^fIG+E4U3I1(e}rT
z-z&*wRrxnz2N?xCm6g8_L$Dyq`lEwKoo!9n{MU@%2x66V?S&|pN$64p)CW7H0{&J$
z%KDUl>D)Pfmv}L^MPUqPB;jh*5<34d<4=SeRUP74F_id|C@WNu>@DUGsg<=rSH3<F
z%0IMwwrcc==TS$5i2W}9q~EDfexsfr7S!~*%UqHDZ!-Q&YoQ>DX!$eMe<(9TJ6M=~
zs7n9u!NR0r5ZYe84DRyrr;#LL@_P%(XiSpPC{M;M1U0@hDJT4BfFU|ROlua|Mmqkw
zNqZ!AO0<(RBIMkT-3>_8FNt!a0n6O<!v>=91CP{?jQWvl*EN-uP8)weeiD|cKgyN5
zxzWJj*kG=?^iD9F|47o|+0hF<a9n}%?z{ON-?MbzW4g#`zn9?`IqmQ={0jqd#r)!o
z&QtkW-w&h88o+7%RWyLp_^W6Dr}0<O0KluVxO+18C3bjL60SdfR@?vj{v#p$ckeyB
zf9Ib5WPk73{e$~^kMG@Gh*HV?dq_;%S6yaBG1tTRY-~6k@hX{rpYTHk8=7fu;rtl?
zBkItg?|UP4I?(GLjfQ?Wn+JSN$inLs$>NL3dTOt$6K6<9OwTJ|LhFCR4+SgmnSIg$
zGEr8|k+=bQ!f%Cq5zK%I7U(Dlm%4s9nne-1{x;$74-FN$eA*8w#E+A;!dEp_TnjLX
zGq4ZUfvff@37GvN*U(oKWv#WfEzAIgUZ(~w&%Dlv8#vIy!`w`)==G1j>Dp>$#V-q?
z{wGs$XHuio1ELCk5<~nAY?JznNf9dloPeB~`6~EhM(dFI7VU+$)nBl)gqFWcO`E7G
z_GwG3^Tn{qJka^@_oFD7L^&URLS{=L=fi(w1n0`%b4kk#&X1oNWIF1K<#&TAqq=Do
zEBqDYAB|1l(sVzLf;gIbf1C`$g7ZJiKA&aM0}?K*gI(C%Y43^}10nN`i3g7A&_Ut)
zPbK>QOan85Njg%tm+0{y;(y|K0kzw;7MDPT*8eR3k&TvEtc8g7fAs_ESq^2hCHQ=l
zi`wq?c2kfK!rb_ABD&|@F<o*uw+>cG`|I&mz)YiH2~2eP9~s=~W1@noj4iB!i?%;A
z{5>b8o<Y+_*qWF3NLnsGcRlM3)vm=|+L-RxuAR}rR$2lLFrNRIIFP-rYM}EKM5(0x
znS}LWejckK4RA2uiDye8m$X)=`NfWyQYhr--q1taoURD0x0?w>&}aF{fQ>vu9onAB
zJyID>RKQhD5I0BK{(<-{GDJl8zn-f`A@LZReN^NFBbMKt<^9;8$qeMeGK^69cSuK8
z%-26XUk~X~Y=;oTc4oRkwERWiSJB`@-%h-+Nazzc?QU8zKjo{yBqaggc=V`ln)MMN
zh@ZRssv+_m6-oN*`v}nwMqbp{n{Cy%mgx;P=lA@`?%5OnbDjC|i7(LAz&^IA8AD1e
zmwU=TS=~ejh^WW)ADypplKK4K2f6jnBctvI(V161C&<me@tNoRB-~0zocl+P-wOR<
z)X$B;tGnW+|8o4uzC|O9e2)F%WFx{_Q{53Z0h;AUzwd=KKLsk#{U*;(jtlrj)<4?6
z>%UNa_gL)@xdNci2mUG6xc*Tcf1l<i;Z_ByJ~Mvk{Gnaue5#1we>RnW#37-p6NiSm
z8OZCmlaM<OVazs`ECX}vZ?O~E7=AO`K-NrV3iFGa)<5@s^ny5gPK><!yKwuT^Lsr*
z%}x89K=k;}`S~(%Q=P8+>De{l*DdDOh6XHSvHV&I|EeW+|Kp6Gx)jpiGe&xMq^EqI
zsw#gkb`8g-UX*L>uZi?SNb#rL0CaS~DD)F^RA~PF&{Dgw`Cm-kk9p6}t-)S^d?W%?
z&jiT-Aq^7~Y^nkqeQF#&_vY@lLi<0OyxJ}I{pMJ|JxQ4`e(rl}mC*k$^j{vw^w=yK
z)WgJQ6~^n?`RDovbWh{34olRa^`4!Yg?zWct)d3;!bTFx)aZC=&WJhx3$v>`zLj!8
zSQEVdp5Fh+=U`tfT0qxsLomTGX*{Mw{oA=;#!~qw`KK_yv*XZOrT#A_q>i4<hqF1q
zX!*-}s$-at_^`gB0y(qVY75o>CW;r|g<l*+X!#Ev;;Ck64``^CxZnzH|7rgG-rp%c
zoAiIzW=4a{oyIqJ9v>X&$$FL1vsBwV!`6tSWcDMOf#O?%i=tfO-a!s6+n#qep#Hh;
z7x;Otdyduntve#96L8rc8G+i3dp+J2A=~rr-al?PceiVuoy|_OrfJPqvr|j%Xxp2e
z_Vms&`6pw`6f25S+iJC2oldRQ+}+W(TD7*e+um%pYpv~;)^5*2wPw4swe!7q#1`;7
zxth)~oTNh(f9z&8Kwkds3d_IGf{dpBlQe&;)!fb{U~+4j{Bb4$)$^O@%pZ^-6{Tu^
zYG#$eAAxL>w|4MvZZ+G@G<$O66}e0Jtsu;_|4%{JLjJdT^WW}F>F3vHU@y-9z|2go
zru*Nt&!-Ata_5!#C!f~PC!e86W?$p52PL=XB>RDQ6rtnq$@ec94Y~d05|3Ef$ta=U
zzc}F^<lRmy=I4q)-GJR2(mI>#K^TA5S>y+SfNyVP_$SJb&TZics^BaImGLL}k6AaJ
z`6~I@kOaYEEmy`5L2$0^Z}Jr)ns@(LOYw_H!U;d$Rc8|F=KOCiR+j&wt)~g9;ZGd#
z7Q@#n%YQd6ndGj9-}W&4I7KqJ8h*Y>HS&wTLsktxtgv(K|Ca9^GNWH0=BnZEwh9UU
zC(SQX{!GVTm)PF9jK9gQVs~LCp)!6uWQNXHp3jM&m@Ei`qCOzB{Uskiu)T;TT5n;L
z3w(}9ln$KP|7Jh{>f8@yvJe?eCZUDSzh&D$TbO{WQ2!$?4G9}8EJRl$e};y~Sbb`R
zRL7t8zdX^sRh0KUiqQGzwEkc60cfH5FZ=Fd3e|jnG1>ZB7)5CNk6JEFk22Tu1XsQk
z`2E}Y_~S;i;>$&;$o_TX<C5~Pgnw>-<d<8|q5t=LmG}RW%^%A7<eycZe~66p(7$K$
zuk`Dyg5_Uv`3K$946yM1AB+6GsH*xe=J!a2{Bv5CnRl<A-;9e!AmRIO7R%o~pYn&;
z<s)$}iqP*5Wbz-WeZ$t1%@C;t*;Vv;q5MX=2}TPZh!+z7C_((D?{r7Ay<fI>2wSX|
zUj0bykARZHQyf&!0`7QrWZ+j1LYgdt=#Fn3>U}zyin=KN`}2wK+rWvac3c=mbpM<1
zo2BmjV)?n_qhTz5^?i!}Qj{CJnpV@aR;}4=)|wr@;#}L^-Nl*zdv|I4g>H8LEtub8
z?)=lwP(f`s$jrbzP?T$boC=7I{re9$G<B)Xao+Q7cCWwz_-2LvKU@bYn1o*Om+Enr
z#oYc6h|c05aBPF5K7r^|p#O2#D}CnVlN0qf1^a(y=YRNz`0E)@um^(eU$bunYBIsb
zcYQ8?<?&%v_0JPxn0kJ$FA`k;sr&~;F1Eb?!S>%gqnLRa{*V&3Fa?3~zqo(z%e}p)
z!ud^)Ew=Q>DF2R{{8hle=;{8s5Y{sO#V_tv%fIMHQYF977he|n-?w7QJ(PRC#`g-?
zjziR?eGxsyZwJIQA%rp`5cscZO|`Y9shiuXw!3UyFvV|?hz|1`4ZweS#@|wxKN6()
zUBVUxEzf^zYfDXzc4xWDN0vYNe=oQXdXE2s*6aw|0iWXMbN>rgMz;Ky{~u7K_$Rw;
z?`Q2F(fyD6pPeFp`S>GL{$}_KHX3pMrkeZ-=C_7L;Wq{Mzv<qV(ic}z{;9n+Mf@vg
zwQ(dQBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsx
zBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsx
jBqSsxBqSsxBqSsxBqSsxBqSsxBqSsxBqSsx{$24ea`HxF
new file mode 100644
--- /dev/null
+++ b/b2g/components/test/unit/test_logcapture.js
@@ -0,0 +1,25 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+
+/**
+ * Test that LogCapture successfully reads from the /dev/log devices, returning
+ * a Uint8Array of some length, including zero. This tests a few standard
+ * log devices
+ */
+function run_test() {
+  Components.utils.import('resource:///modules/LogCapture.jsm');
+
+  function verifyLog(log) {
+    // log exists
+    notEqual(log, null);
+    // log has a length and it is non-negative (is probably array-like)
+    ok(log.length >= 0);
+  }
+
+  let mainLog = LogCapture.readLogFile('/dev/log/main');
+  verifyLog(mainLog);
+
+  let meminfoLog = LogCapture.readLogFile('/proc/meminfo');
+  verifyLog(meminfoLog);
+}
new file mode 100644
--- /dev/null
+++ b/b2g/components/test/unit/test_logparser.js
@@ -0,0 +1,49 @@
+/* jshint moz: true */
+
+const {utils: Cu, classes: Cc, interfaces: Ci} = Components;
+
+function run_test() {
+  Cu.import('resource:///modules/LogParser.jsm');
+
+  let propertiesFile = do_get_file('data/test_properties');
+  let loggerFile = do_get_file('data/test_logger_file');
+
+  let propertiesStream = makeStream(propertiesFile);
+  let loggerStream = makeStream(loggerFile);
+
+  // Initialize arrays to hold the file contents (lengths are hardcoded)
+  let propertiesArray = new Uint8Array(propertiesStream.readByteArray(65536));
+  let loggerArray = new Uint8Array(loggerStream.readByteArray(4037));
+
+  propertiesStream.close();
+  loggerStream.close();
+
+  let properties = LogParser.parsePropertiesArray(propertiesArray);
+  let logMessages = LogParser.parseLogArray(loggerArray);
+
+  // Test arbitrary property entries for correctness
+  equal(properties['ro.boot.console'], 'ttyHSL0');
+  equal(properties['net.tcp.buffersize.lte'],
+        '524288,1048576,2097152,262144,524288,1048576');
+
+  ok(logMessages.length === 58, 'There should be 58 messages in the log');
+
+  let expectedLogEntry = {
+    processId: 271, threadId: 271,
+    seconds: 790796, nanoseconds: 620000001, time: 790796620.000001,
+    priority: 4, tag: 'Vold',
+    message: 'Vold 2.1 (the revenge) firing up\n'
+  };
+
+  deepEqual(expectedLogEntry, logMessages[0]);
+}
+
+function makeStream(file) {
+  var fileStream = Cc['@mozilla.org/network/file-input-stream;1']
+                .createInstance(Ci.nsIFileInputStream);
+  fileStream.init(file, -1, -1, 0);
+  var bis = Cc['@mozilla.org/binaryinputstream;1']
+                .createInstance(Ci.nsIBinaryInputStream);
+  bis.setInputStream(fileStream);
+  return bis;
+}
new file mode 100644
--- /dev/null
+++ b/b2g/components/test/unit/test_logshake.js
@@ -0,0 +1,141 @@
+/**
+ * Test the log capturing capabilities of LogShake.jsm
+ */
+
+/* jshint moz: true */
+/* global Components, LogCapture, LogShake, ok, add_test, run_next_test, dump */
+/* exported run_test */
+
+/* disable use strict warning */
+/* jshint -W097 */
+'use strict';
+
+const Cu = Components.utils;
+
+Cu.import('resource://gre/modules/LogCapture.jsm');
+Cu.import('resource://gre/modules/LogShake.jsm');
+
+// Force logshake to handle a device motion event with given components
+// Does not use SystemAppProxy because event needs special
+// accelerationIncludingGravity property
+function sendDeviceMotionEvent(x, y, z) {
+  let event = {
+    type: 'devicemotion',
+    accelerationIncludingGravity: {
+      x: x,
+      y: y,
+      z: z
+    }
+  };
+  LogShake.handleEvent(event);
+}
+
+// Send a screen change event directly, does not use SystemAppProxy due to race
+// conditions.
+function sendScreenChangeEvent(screenEnabled) {
+  let event = {
+    type: 'screenchange',
+    detail: {
+      screenEnabled: screenEnabled
+    }
+  };
+  LogShake.handleEvent(event);
+}
+
+function debug(msg) {
+  var timestamp = Date.now();
+  dump('LogShake: ' + timestamp + ': ' + msg);
+}
+
+add_test(function test_do_log_capture_after_shaking() {
+  // Enable LogShake
+  LogShake.init();
+
+  let readLocations = [];
+  LogCapture.readLogFile = function(loc) {
+    readLocations.push(loc);
+    return null; // we don't want to provide invalid data to a parser
+  };
+
+  // Fire a devicemotion event that is of shake magnitude
+  sendDeviceMotionEvent(9001, 9001, 9001);
+
+  ok(readLocations.length > 0,
+      'LogShake should attempt to read at least one log');
+
+  LogShake.uninit();
+  run_next_test();
+});
+
+add_test(function test_do_nothing_when_resting() {
+  // Enable LogShake
+  LogShake.init();
+
+  let readLocations = [];
+  LogCapture.readLogFile = function(loc) {
+    readLocations.push(loc);
+    return null; // we don't want to provide invalid data to a parser
+  };
+
+  // Fire a devicemotion event that is relatively tiny
+  sendDeviceMotionEvent(0, 9.8, 9.8);
+
+  ok(readLocations.length === 0,
+      'LogShake should not read any logs');
+
+  debug('test_do_nothing_when_resting: stop');
+  LogShake.uninit();
+  run_next_test();
+});
+
+add_test(function test_do_nothing_when_disabled() {
+  debug('test_do_nothing_when_disabled: start');
+  // Disable LogShake
+  LogShake.uninit();
+
+  let readLocations = [];
+  LogCapture.readLogFile = function(loc) {
+    readLocations.push(loc);
+    return null; // we don't want to provide invalid data to a parser
+  };
+
+  // Fire a devicemotion event that would normally be a shake
+  sendDeviceMotionEvent(0, 9001, 9001);
+
+  ok(readLocations.length === 0,
+      'LogShake should not read any logs');
+
+  run_next_test();
+});
+
+add_test(function test_do_nothing_when_screen_off() {
+  // Enable LogShake
+  LogShake.init();
+
+
+  // Send an event as if the screen has been turned off
+  sendScreenChangeEvent(false);
+
+  let readLocations = [];
+  LogCapture.readLogFile = function(loc) {
+    readLocations.push(loc);
+    return null; // we don't want to provide invalid data to a parser
+  };
+
+  // Fire a devicemotion event that would normally be a shake
+  sendDeviceMotionEvent(0, 9001, 9001);
+
+  ok(readLocations.length === 0,
+      'LogShake should not read any logs');
+
+  // Restore the screen
+  sendScreenChangeEvent(true);
+
+  LogShake.uninit();
+  run_next_test();
+});
+
+function run_test() {
+  debug('Starting');
+  run_next_test();
+}
--- a/b2g/components/test/unit/xpcshell.ini
+++ b/b2g/components/test/unit/xpcshell.ini
@@ -1,14 +1,24 @@
 [DEFAULT]
 head =
 tail =
 
+support-files =
+  data/test_logger_file
+  data/test_properties
+
 [test_bug793310.js]
 
 [test_bug832946.js]
 
 [test_fxaccounts.js]
 [test_signintowebsite.js]
 head = head_identity.js
 tail =
 
+[test_logcapture.js]
+# only run on b2g builds due to requiring b2g-specific log files to exist
+skip-if = toolkit != "gonk"
 
+[test_logparser.js]
+
+[test_logshake.js]
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4b4336c73c081b39776d399835ce4853aee5cc1c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="83760d213fb3bec7b4117d266fcfbf6fe2ba14ab"/>
   <project name="device/common" path="device/common" revision="6a2995683de147791e516aae2ccb31fdfbe2ad30"/>
@@ -122,17 +122,17 @@
   <project name="platform/system/security" path="system/security" revision="ee8068b9e7bfb2770635062fc9c2035be2142bd8"/>
   <project name="platform/system/vold" path="system/vold" revision="118dec582647895a863dbbce8ec26bc7af457bbe"/>
   <!--original fetch url was http://sprdsource.spreadtrum.com:8085/b2g/android-->
   <remote fetch="https://git.mozilla.org/external/sprd-aosp" name="sprd-aosp"/>
   <default remote="sprd-aosp" revision="sprdb2g_gonk4.4" sync-j="4"/>
   <!-- Stock Android things -->
   <project name="platform/external/icu4c" path="external/icu4c" revision="2bb01561780583cc37bc667f0ea79f48a122d8a2"/>
   <!-- dolphin specific things -->
-  <project name="device/sprd" path="device/sprd" revision="4eac1e31bf69596bf229a6877c9aa3493ecd9fce"/>
+  <project name="device/sprd" path="device/sprd" revision="3ba0b8b4e3f55d68f84603218e522d054a723532"/>
   <project name="platform/external/wpa_supplicant_8" path="external/wpa_supplicant_8" revision="4e58336019b5cbcfd134caf55b142236cf986618"/>
   <project name="platform/frameworks/av" path="frameworks/av" revision="facca8d3e35431b66f85a4eb42bc6c5b24bd04da"/>
   <project name="platform/hardware/akm" path="hardware/akm" revision="6d3be412647b0eab0adff8a2768736cf4eb68039"/>
   <project groups="invensense" name="platform/hardware/invensense" path="hardware/invensense" revision="e6d9ab28b4f4e7684f6c07874ee819c9ea0002a2"/>
   <project name="platform/hardware/ril" path="hardware/ril" revision="865ce3b4a2ba0b3a31421ca671f4d6c5595f8690"/>
   <project name="kernel/common" path="kernel" revision="03effd4db31881b2dd8d57575694515327f9ea2e"/>
   <project name="platform/system/core" path="system/core" revision="53d584d4a4b4316e4de9ee5f210d662f89b44e7e"/>
   <project name="u-boot" path="u-boot" revision="df509ae75495aa409969973b97ee781037dee1fe"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="74465af039d2809454afdfef285285bb63146e1b">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4b4336c73c081b39776d399835ce4853aee5cc1c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="1950e4760fa14688b83cdbb5acaa1af9f82ef434"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="ac6eb97a37035c09fb5ede0852f0881e9aadf9ad"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="737f591c5f95477148d26602c7be56cbea0cdeb9"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="51da9b1981be481b92a59a826d4d78dc73d0989a"/>
   <project name="device/common" path="device/common" revision="798a3664597e6041985feab9aef42e98d458bc3d"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,23 +14,23 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="c058843242068d0df7c107e09da31b53d2e08fa6"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
   <project name="platform/bionic" path="bionic" revision="c72b8f6359de7ed17c11ddc9dfdde3f615d188a9"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="425f8b5fadf5889834c5acd27d23c9e0b2129c28"/>
   <project name="device/common" path="device/common" revision="42b808b7e93d0619286ae8e59110b176b7732389"/>
   <project name="device/sample" path="device/sample" revision="237bd668d0f114d801a8d6455ef5e02cc3577587"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
   <project name="platform/external/bluetooth/bluez" path="external/bluetooth/bluez" revision="52a1a862a8bac319652b8f82d9541ba40bfa45ce"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,25 +10,25 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4b4336c73c081b39776d399835ce4853aee5cc1c">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7" revision="a1e239a0bb5cd1d69680bf1075883aa9a7bf2429"/>
   <project groups="linux,x86" name="platform/prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" path="prebuilts/gcc/linux-x86/x86/i686-linux-android-4.7" revision="c7931763d41be602407ed9d71e2c0292c6597e00"/>
   <project groups="linux,x86" name="platform/prebuilts/python/linux-x86/2.7.5" path="prebuilts/python/linux-x86/2.7.5" revision="a32003194f707f66a2d8cdb913ed1869f1926c5d"/>
   <project name="device/common" path="device/common" revision="96d4d2006c4fcb2f19a3fa47ab10cb409faa017b"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="74465af039d2809454afdfef285285bb63146e1b">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="8b880805d454664b3eed11d0f053cdeafa1ff06e"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
         "git_revision": "", 
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "a0fe2fdc571f1a5eb5474e08773fac80f9bb9fbd", 
+    "revision": "dc9488c3826ae1dbd0051ac19c83c5da1f4915a7", 
     "repo_path": "/integration/gaia-central"
 }
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="746bc48f34f5060f90801925dcdd964030c1ab6d"/>
   <project name="platform/development" path="development" revision="2460485184bc8535440bb63876d4e63ec1b4770c"/>
   <project name="device/common" path="device/common" revision="0dcc1e03659db33b77392529466f9eb685cdd3c7"/>
   <project name="device/sample" path="device/sample" revision="68b1cb978a20806176123b959cb05d4fa8adaea4"/>
   <project name="platform_external_apriori" path="external/apriori" remote="b2g" revision="11816ad0406744f963537b23d68ed9c2afb412bd"/>
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <default remote="caf" revision="b2g/ics_strawberry" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="d2eb6c7b6e1bc7643c17df2d9d9bcb1704d0b9ab"/>
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,20 +12,20 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="74465af039d2809454afdfef285285bb63146e1b">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="9025e50b9d29b3cabbbb21e1dd94d0d13121a17e"/>
   <project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="b89fda71fcd0fa0cf969310e75be3ea33e048b44"/>
   <project groups="linux,arm" name="platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" path="prebuilts/gcc/linux-x86/arm/arm-eabi-4.7" revision="2e7d5348f35575870b3c7e567a9a9f6d66f8d6c5"/>
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -12,22 +12,22 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="ics_chocolate_rb4.2" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="0d616942c300d9fb142483210f1dda9096c9a9fc">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="52670853c17fc0d3d33065c667c0ce124c93b98f"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="af04d8bc2111d4ea146239a89ff602206b85eaf5"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="6969df171e5295f855f12d12db0382048e6892e7"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
-  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="7ddb07033043613303061416882c9b02ac3d76b6"/>
+  <project name="apitrace" path="external/apitrace" remote="apitrace" revision="2aa3a0d353812bb8732a122965ffdbf5f889ca12"/>
   <project name="gonk-patches" path="patches" remote="b2g" revision="223a2421006e8f5da33f516f6891c87cae86b0f6"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="6426040f1be4a844082c9769171ce7f5341a5528"/>
   <project name="platform/bionic" path="bionic" revision="cd5dfce80bc3f0139a56b58aca633202ccaee7f8"/>
   <project name="platform/bootable/recovery" path="bootable/recovery" revision="e0a9ac010df3afaa47ba107192c05ac8b5516435"/>
   <project name="platform/development" path="development" revision="a384622f5fcb1d2bebb9102591ff7ae91fe8ed2d"/>
   <project name="device/common" path="device/common" revision="7c65ea240157763b8ded6154a17d3c033167afb7"/>
   <project name="device/sample" path="device/sample" revision="c328f3d4409db801628861baa8d279fb8855892f"/>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -288,16 +288,17 @@
 #ifdef MOZ_CAPTIVEDETECT
 @BINPATH@/components/captivedetect.xpt
 #endif
 @BINPATH@/components/shellservice.xpt
 @BINPATH@/components/shistory.xpt
 @BINPATH@/components/spellchecker.xpt
 @BINPATH@/components/storage.xpt
 @BINPATH@/components/telemetry.xpt
+@BINPATH@/components/toolkit_filewatcher.xpt
 @BINPATH@/components/toolkit_finalizationwitness.xpt
 @BINPATH@/components/toolkit_formautofill.xpt
 @BINPATH@/components/toolkit_osfile.xpt
 @BINPATH@/components/toolkit_xulstore.xpt
 @BINPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @BINPATH@/components/toolkitremote.xpt
 #endif
@@ -436,16 +437,18 @@
 @BINPATH@/components/MmsService.manifest
 @BINPATH@/components/MobileMessageDatabaseService.js
 @BINPATH@/components/MobileMessageDatabaseService.manifest
 @BINPATH@/components/RadioInterfaceLayer.js
 @BINPATH@/components/RadioInterfaceLayer.manifest
 @BINPATH@/components/RILContentHelper.js
 @BINPATH@/components/TelephonyService.js
 @BINPATH@/components/TelephonyService.manifest
+@BINPATH@/components/MobileConnectionGonkService.js
+@BINPATH@/components/MobileConnectionGonkService.manifest
 #endif // MOZ_WIDGET_GONK && MOZ_B2G_RIL
 
 #ifndef MOZ_WIDGET_GONK
 @BINPATH@/components/extensions.manifest
 @BINPATH@/components/addonManager.js
 @BINPATH@/components/amContentHandler.js
 @BINPATH@/components/amInstallTrigger.js
 @BINPATH@/components/amWebInstallListener.js
--- a/browser/base/content/test/chat/browser.ini
+++ b/browser/base/content/test/chat/browser.ini
@@ -1,9 +1,9 @@
 [DEFAULT]
-skip-if = buildapp == 'mulet'
+skip-if = buildapp == 'mulet' || e10s
 support-files =
   head.js
   chat.html
 
 [browser_chatwindow.js]
 [browser_focus.js]
 [browser_tearoff.js]
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -97,37 +97,41 @@ support-files =
   content_aboutAccounts.js
 [browser_aboutSupport_newtab_security_state.js]
 [browser_aboutHealthReport.js]
 skip-if = os == "linux" # Bug 924307
 [browser_aboutHome.js]
 skip-if = e10s # Bug ?????? - no about:home support yet
 [browser_aboutSyncProgress.js]
 [browser_addKeywordSearch.js]
+skip-if = e10s
 [browser_alltabslistener.js]
 skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 951680; e10s: Bug ?????? - notifications don't work correctly.
 [browser_backButtonFitts.js]
 skip-if = os != "win" || e10s # The Fitts Law back button is only supported on Windows (bug 571454) / e10s - Bug ?????? test touches content (attempts to add an event listener directly to the contentWindow)
 [browser_blob-channelname.js]
 [browser_bookmark_titles.js]
 skip-if = buildapp == 'mulet' || toolkit == "windows" || e10s # Disabled on Windows due to frequent failures (bugs 825739, 841341) / e10s - Bug ?????? test checks event.target on load event, which our e10s utils don't support
 [browser_bug304198.js]
+skip-if = e10s
 [browser_bug321000.js]
 skip-if = true # browser_bug321000.js is disabled because newline handling is shaky (bug 592528)
 [browser_bug329212.js]
+skip-if = e10s
 [browser_bug331772_xul_tooltiptext_in_html.js]
+skip-if = e10s
 [browser_bug356571.js]
 [browser_bug380960.js]
 [browser_bug386835.js]
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug405137.js]
 [browser_bug406216.js]
 [browser_bug409481.js]
-skip-if = e10s # Bug 921952 - Content:Click event issues (test simulated middle-click on a link and checks the value pastes - it doesn't)
 [browser_bug409624.js]
+skip-if = e10s
 [browser_bug413915.js]
 [browser_bug416661.js]
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug417483.js]
 skip-if = e10s # Bug ?????? - no about:home support yet
 [browser_bug419612.js]
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug422590.js]
@@ -141,29 +145,31 @@ skip-if = e10s # Bug ?????? - "content w
 skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
 [browser_bug432599.js]
 [browser_bug435035.js]
 [browser_bug435325.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content
 [browser_bug441778.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug455852.js]
+skip-if = e10s
 [browser_bug460146.js]
 skip-if = e10s # Bug 866413 - PageInfo doesn't work in e10s
 [browser_bug462289.js]
 skip-if = toolkit == "cocoa" || e10s # Bug ?????? - not sure why this is timing out and crashing!!
 [browser_bug462673.js]
 skip-if = e10s # Bug 924260 - "Window is closed"
 [browser_bug477014.js]
 skip-if = e10s # Bug 918634 - swapFrameLoaders not implemented for e10s
 [browser_bug479408.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome
 [browser_bug481560.js]
 skip-if = e10s # Bug ????? - This bug attached an event listener directly to the content
 [browser_bug484315.js]
+skip-if = e10s
 [browser_bug491431.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 918634 - swapFrameLoaders (and thus replaceTabWithWindow) not implemented for e10s
 [browser_bug495058.js]
 skip-if = e10s # Bug 918634 - swapFrameLoaders (and thus replaceTabWithWindow) not implemented for e10s
 [browser_bug517902.js]
 skip-if = e10s # Bug 866413 - PageInfo doesn't work in e10s
 [browser_bug519216.js]
 skip-if = e10s # Bug ?????? - some weird timing issue with progress listeners that fails intermittently
@@ -183,40 +189,44 @@ skip-if = buildapp == 'mulet' || e10s # 
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug555767.js]
 skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
 [browser_bug556061.js]
 skip-if = e10s # Bug 932651 - getClipboardData in specialpowersAPI.js not e10s friendly
 [browser_bug559991.js]
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug561623.js]
+skip-if = e10s
 [browser_bug561636.js]
 skip-if = e10s # Bug 691601 - no form submit observers
 [browser_bug562649.js]
 skip-if = e10s # Bug 940195 - XULBrowserWindow.isBusy is false as a remote tab starts loading
 [browser_bug563588.js]
 [browser_bug565575.js]
+skip-if = e10s
 [browser_bug565667.js]
 run-if = toolkit == "cocoa"
 [browser_bug567306.js]
+skip-if = e10s
 [browser_bug575561.js]
 [browser_bug575830.js]
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug577121.js]
 [browser_bug578534.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
 [browser_bug579872.js]
 [browser_bug580638.js]
 [browser_bug580956.js]
 skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
 [browser_bug581242.js]
 skip-if = e10s # Bug 930863 - pageshow issues ("TypeError: charset is undefined" in pageshow listener, as document is null)
 [browser_bug581253.js]
 skip-if = e10s # Bug 930863 - pageshow issues ("TypeError: charset is undefined" in pageshow listener, as document is null)
 [browser_bug581947.js]
+skip-if = e10s
 [browser_bug585558.js]
 [browser_bug585785.js]
 [browser_bug585830.js]
 [browser_bug590206.js]
 [browser_bug592338.js]
 skip-if = e10s # Bug 653065 - Make the lightweight theme web installer ready for e10s
 [browser_bug594131.js]
 [browser_bug595507.js]
@@ -230,78 +240,85 @@ skip-if = e10s # Bug ?????? - URLBar iss
 [browser_bug623893.js]
 skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
 [browser_bug624734.js]
 [browser_bug633691.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (eg, var expertDiv = gBrowser.contentDocument.getElementById("expertContent");)
 [browser_bug647886.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 916974 - Session history doesn't work in e10s
 [browser_bug655584.js]
+skip-if = e10s
 [browser_bug664672.js]
 [browser_bug676619.js]
 skip-if = buildapp == 'mulet' || os == "mac" || e10s # mac: Intermittent failures, bug 925225; e10s: Bug ?????? - test directly manipulates content (event.target.location)
 [browser_bug678392.js]
 skip-if = e10s # Bug ?????? - Obscure non-windows failures ("Snapshot array has correct length of 1 after loading one page. - Got 0, expected 1" and more)
 [browser_bug710878.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (doc.querySelector)
 [browser_bug719271.js]
 skip-if = e10s # Bug 691614 - no e10s zoom support yet
 [browser_bug724239.js]
 [browser_bug734076.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
 [browser_bug735471.js]
 [browser_bug749738.js]
 skip-if = e10s # Bug 921935 - focusmanager issues with e10s
 [browser_bug763468_perwindowpb.js]
+skip-if = e10s
 [browser_bug767836_perwindowpb.js]
 skip-if = e10s # Bug ?????? - test reports a leaked nsGlobalWindow with e10s enabled.
 [browser_bug771331.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
 [browser_bug783614.js]
 [browser_bug816527.js]
 skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
 [browser_bug817947.js]
 skip-if = e10s # Bug 916974 - Session history doesn't work in e10s
 [browser_bug822367.js]
 [browser_bug832435.js]
 [browser_bug839103.js]
 [browser_bug880101.js]
 [browser_bug882977.js]
 [browser_bug902156.js]
+skip-if = e10s
 [browser_bug906190.js]
 skip-if = buildapp == "mulet" || e10s # Bug ?????? - test directly manipulates content (strange - gets an element from a child which it tries to treat as a string, but that fails)
 [browser_bug970746.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (directly gets elements from the content)
 [browser_bug1015721.js]
 skip-if = os == 'win' || e10s # Bug 1056146 - FullZoomHelper uses promiseTabLoadEvent() which isn't e10s friendly
 [browser_canonizeURL.js]
 skip-if = e10s # Bug ?????? - [JavaScript Error: "Error in AboutHome.sendAboutHomeData TypeError: target.messageManager is undefined" {file: "resource:///modules/AboutHome.jsm" line: 208}]
 [browser_contentAreaClick.js]
+skip-if = e10s
 [browser_contextSearchTabPosition.js]
-skip-if = os == "mac" # bug 967013, bug 926729
+skip-if = os == "mac" || e10s # bug 967013, bug 926729
 [browser_ctrlTab.js]
 skip-if = e10s # Bug ????? - thumbnail captures need e10s love (tabPreviews_capture fails with Argument 1 of CanvasRenderingContext2D.drawWindow does not implement interface Window.)
 [browser_customize_popupNotification.js]
+skip-if = e10s
 [browser_datareporting_notification.js]
 run-if = datareporting
 [browser_devices_get_user_media.js]
 skip-if = buildapp == 'mulet' || (os == "linux" && debug) || e10s # linux: bug 976544; e10s: Bug 973001 - appears user media notifications only happen in the child and don't make their way to the parent?
 [browser_devices_get_user_media_about_urls.js]
 skip-if = e10s # Bug 973001 - appears user media notifications only happen in the child and don't make their way to the parent?
 [browser_discovery.js]
 skip-if = e10s # Bug 918663 - DOMLinkAdded events don't make their way to chrome
 [browser_duplicateIDs.js]
 [browser_drag.js]
 skip-if = true # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638.
 [browser_favicon_change.js]
+skip-if = e10s
 [browser_findbarClose.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (tries to grab an iframe directly from content)
 [browser_fullscreen-window-open.js]
 skip-if = buildapp == 'mulet' || e10s || os == "linux" # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly. Linux: Intermittent failures - bug 941575.
 [browser_fxa_oauth.js]
+skip-if = e10s
 [browser_gestureSupport.js]
 skip-if = e10s # Bug 863514 - no gesture support.
 [browser_getshortcutoruri.js]
 [browser_hide_removing.js]
 [browser_homeDrop.js]
 skip-if = buildapp == 'mulet'
 [browser_identity_UI.js]
 skip-if = e10s # Bug ?????? - this test fails for obscure reasons on non-windows builds only.
@@ -311,16 +328,17 @@ skip-if = e10s # Bug ?????? - this test 
 skip-if = e10s # Bug 921957 - remote webprogress doesn't supply originalURI attribute on the request object
 [browser_keywordSearch_postData.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (gBrowser.contentDocument.body.textContent)
 [browser_lastAccessedTab.js]
 skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bug 969405)
 [browser_locationBarCommand.js]
 skip-if = os == "linux" || e10s # Linux: Intermittent failures, bug 917535; e10s: Bug ?????? - Focus issues (There should be no focused element - Got [object XULElement], expected null)
 [browser_locationBarExternalLoad.js]
+skip-if = e10s
 [browser_menuButtonFitts.js]
 skip-if = os != "win" || e10s # The Fitts Law menu button is only supported on Windows (bug 969376); # Bug ?????? - URL bar issues ("There should be no focused element - Got [object XULElement], expected null")
 [browser_middleMouse_noJSPaste.js]
 skip-if = e10s # Bug 921952 - Content:Click event issues
 [browser_minimize.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (TypeError: gBrowser.docShell is null)
 [browser_mixedcontent_securityflags.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content ("cannot ipc non-cpow object")
@@ -330,16 +348,17 @@ skip-if = buildapp == 'mulet' || e10s # 
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (gBrowser.selectedBrowser.contentWindow.applicationCache.oncached = function() {...})
 [browser_overflowScroll.js]
 [browser_pageInfo.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 866413 - PageInfo doesn't work in e10s
 [browser_page_style_menu.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
 
 [browser_parsable_css.js]
+skip-if = e10s
 [browser_parsable_script.js]
 skip-if = debug || asan # Times out on debug/asan, and we are less picky about our JS there
 
 [browser_pinnedTabs.js]
 [browser_plainTextLinks.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (creates and fetches elements directly from content document)
 [browser_popupUI.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (tries to get a popup element directly from content)
@@ -347,16 +366,17 @@ skip-if = buildapp == 'mulet' || e10s # 
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
 [browser_private_browsing_window.js]
 skip-if = buildapp == 'mulet'
 [browser_private_no_prompt.js]
 skip-if = buildapp == 'mulet'
 [browser_relatedTabs.js]
 [browser_removeTabsToTheEnd.js]
 [browser_removeUnsafeProtocolsFromURLBarPaste.js]
+skip-if = e10s
 [browser_sanitize-download-history.js]
 skip-if = true # bug 432425
 [browser_sanitize-passwordDisabledHosts.js]
 [browser_sanitize-sitepermissions.js]
 [browser_sanitize-timespans.js]
 skip-if = buildapp == 'mulet'
 [browser_sanitizeDialog.js]
 skip-if = buildapp == 'mulet'
@@ -367,65 +387,72 @@ skip-if = true  # disabled until the tre
 [browser_save_link-perwindowpb.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (event.target)
 [browser_save_private_link_perwindowpb.js]
 skip-if = buildapp == 'mulet' || e10s # e10s: Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly
 [browser_save_video.js]
 skip-if = buildapp == 'mulet' || e10s # Bug ?????? - test directly manipulates content (event.target)
 [browser_scope.js]
 [browser_searchSuggestionUI.js]
+skip-if = e10s
 support-files =
   searchSuggestionUI.html
   searchSuggestionUI.js
 [browser_selectTabAtIndex.js]
 skip-if = e10s # Bug ?????? - no idea! "Accel+9 selects expected tab - Got 0, expected 9"
 [browser_star_hsts.js]
 skip-if = e10s # Bug ?????? - timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
 [browser_subframe_favicons_not_used.js]
 [browser_tabDrop.js]
-skip-if = buildapp == 'mulet'
+skip-if = buildapp == 'mulet' || e10s
 [browser_tabMatchesInAwesomebar_perwindowpb.js]
 skip-if = e10s # Bug 918634 - swapFrameLoaders not implemented for e10s (test uses gBrowser.swapBrowsersAndCloseOther)
 [browser_tab_drag_drop_perwindow.js]
 skip-if = buildapp == 'mulet'
 [browser_tab_dragdrop.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 918634 - swapFrameLoaders not implemented for e10s (test uses gBrowser.swapBrowsersAndCloseOther)
 [browser_tab_dragdrop2.js]
-skip-if = buildapp == 'mulet'
+skip-if = buildapp == 'mulet' || e10s
 [browser_tabbar_big_widgets.js]
 skip-if = os == "linux" || os == "mac" # No tabs in titlebar on linux
                                        # Disabled on OS X because of bug 967917
 [browser_tabfocus.js]
 skip-if = e10s # Bug 921935 - focusmanager issues with e10s (test calls getFocusedElementForWindow with a content window)
 [browser_tabkeynavigation.js]
+skip-if = e10s
 [browser_tabopen_reflows.js]
 skip-if = e10s # Bug ?????? - test needs to be updated for e10s (captures a stack that isn't correct in e10s)
 [browser_tabs_isActive.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (tries to get/set attributes directly on content docshell)
 [browser_tabs_owner.js]
 [browser_trackingUI.js]
+skip-if = e10s
 support-files =
   trackingPage.html
   benignPage.html
 [browser_typeAheadFind.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 921935 - focusmanager issues with e10s (test calls waitForFocus)
 [browser_unloaddialogs.js]
 skip-if = e10s # Bug ?????? - test uses chrome windowMediator to try and see alert() from content
 [browser_urlHighlight.js]
+skip-if = e10s
 [browser_urlbarAutoFillTrimURLs.js]
+skip-if = e10s
 [browser_urlbarCopying.js]
 skip-if = e10s # Bug 932651 - getClipboardData in specialpowersAPI.js not e10s friendly
 [browser_urlbarEnter.js]
 skip-if = e10s # Bug ?????? - obscure non-windows child process crashes on try
 [browser_urlbarRevert.js]
 skip-if = e10s # Bug ?????? - ESC reverted the location bar value - Got foobar, expected example.com
 [browser_urlbarSearchSingleWordNotification.js]
+skip-if = e10s
 [browser_urlbarStop.js]
 skip-if = e10s # Bug ????? - test calls gBrowser.contentWindow.stop
 [browser_urlbarTrimURLs.js]
+skip-if = e10s
 [browser_urlbar_search_healthreport.js]
 skip-if = e10s # Bug ?????? - FHR tests failing (either with "no data for today" or "2 records for today")
 [browser_utilityOverlay.js]
 [browser_visibleFindSelection.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content
 [browser_visibleLabel.js]
 [browser_visibleTabs.js]
 [browser_visibleTabs_bookmarkAllPages.js]
@@ -441,13 +468,16 @@ skip-if = buildapp == 'mulet'
 skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
 [browser_zbug569342.js]
 skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
 [browser_registerProtocolHandler_notification.js]
 skip-if = e10s # Bug 940206 - nsIWebContentHandlerRegistrar::registerProtocolHandler doesn't work in e10s
 [browser_no_mcb_on_http_site.js]
 skip-if = e10s # Bug 516755 - SessionStore disabled for e10s
 [browser_bug1003461-switchtab-override.js]
+skip-if = e10s
 [browser_bug1024133-switchtab-override-keynav.js]
+skip-if = e10s
 [browser_bug1025195_switchToTabHavingURI_ignoreFragment.js]
 [browser_addCertException.js]
 skip-if = e10s # Bug ?????? - test directly manipulates content (content.document.getElementById)
 [browser_bug1045809.js]
+skip-if = e10s
--- a/browser/components/customizableui/test/browser.ini
+++ b/browser/components/customizableui/test/browser.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = buildapp == "mulet"
+skip-if = buildapp == "mulet" || e10s
 support-files =
   head.js
   support/test_967000_charEncoding_page.html
   support/feeds_test_page.html
   support/test-feed.xml
 
 [browser_873501_handle_specials.js]
 [browser_876926_customize_mode_wrapping.js]
--- a/browser/components/downloads/test/browser/browser.ini
+++ b/browser/components/downloads/test/browser/browser.ini
@@ -1,9 +1,9 @@
 [DEFAULT]
 support-files = head.js
 
 [browser_basic_functionality.js]
-skip-if = buildapp == "mulet"
+skip-if = buildapp == "mulet" || e10s
 [browser_first_download_panel.js]
 skip-if = os == "linux" # Bug 949434
 [browser_overflow_anchor.js]
 skip-if = os == "linux" # Bug 952422
--- a/browser/components/loop/test/mochitest/browser.ini
+++ b/browser/components/loop/test/mochitest/browser.ini
@@ -1,17 +1,17 @@
 [DEFAULT]
 support-files =
     head.js
     loop_fxa.sjs
     ../../../../base/content/test/general/browser_fxa_oauth.html
 
 [browser_CardDavImporter.js]
 [browser_fxa_login.js]
-skip-if = !debug
+skip-if = !debug || e10s
 [browser_loop_fxa_server.js]
 [browser_LoopContacts.js]
 [browser_mozLoop_appVersionInfo.js]
 [browser_mozLoop_prefs.js]
 [browser_mozLoop_doNotDisturb.js]
 [browser_mozLoop_softStart.js]
 skip-if = buildapp == 'mulet'
 [browser_toolbarbutton.js]
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -10,25 +10,27 @@ support-files =
   frameLeft.html
   frameRight.html
   sidebarpanels_click_test_page.html
 
 [browser_0_library_left_pane_migration.js]
 [browser_library_left_pane_fixnames.js]
 [browser_425884.js]
 [browser_475045.js]
+skip-if = e10s
 [browser_423515.js]
 [browser_410196_paste_into_tags.js]
 skip-if = e10s # Bug ?????? - clipboard operations don't seem to work in this test?
 [browser_sort_in_library.js]
 [browser_library_open_leak.js]
 [browser_library_panel_leak.js]
 [browser_library_search.js]
 [browser_history_sidebar_search.js]
 [browser_bookmarksProperties.js]
+skip-if = e10s
 
 [browser_forgetthissite_single.js]
 # disabled for very frequent oranges - bug 551540
 skip-if = true
 
 [browser_library_left_pane_commands.js]
 [browser_drag_bookmarks_on_toolbar.js]
 skip-if = e10s # Bug ?????? - test fails - "Number of dragged items should be the same. - Got 0, expected 1"
@@ -41,15 +43,18 @@ skip-if = e10s # Bug ?????? - test fails
 skip-if = true
 
 [browser_library_infoBox.js]
 [browser_markPageAsFollowedLink.js]
 skip-if = e10s # Bug 933103 - mochitest's EventUtils.synthesizeMouse functions not e10s friendly (test does EventUtils.sendMouseEvent...)
 [browser_toolbar_migration.js]
 [browser_library_batch_delete.js]
 [browser_555547.js]
+skip-if = e10s
 [browser_416459_cut.js]
 skip-if = e10s # Bug ?????? - clipboard operations don't seem to work in this test?
 [browser_library_downloads.js]
 [browser_library_left_pane_select_hierarchy.js]
 [browser_435851_copy_query.js]
+skip-if = e10s
 [browser_toolbarbutton_menu_context.js]
+skip-if = e10s
 [browser_library_openFlatContainer.js]
--- a/browser/components/preferences/in-content/advanced.js
+++ b/browser/components/preferences/in-content/advanced.js
@@ -57,29 +57,29 @@ var gAdvancedPane = {
     setEventListener("connectionSettings", "command",
                      gAdvancedPane.showConnections);
     setEventListener("clearCacheButton", "command",
                      gAdvancedPane.clearCache);
     setEventListener("clearOfflineAppCacheButton", "command",
                      gAdvancedPane.clearOfflineAppCache);
     setEventListener("offlineNotifyExceptions", "command",
                      gAdvancedPane.showOfflineExceptions);
-    setEventListener("offlineNotifyExceptions", "command", function (event) {
-      gAdvancedPane.offlineAppSelected(event); })
+    setEventListener("offlineAppsList", "select",
+                     gAdvancedPane.offlineAppSelected);
     let bundlePrefs = document.getElementById("bundlePreferences");
     document.getElementById("offlineAppsList")
             .style.height = bundlePrefs.getString("offlineAppsList.height");
     setEventListener("offlineAppsListRemove", "command",
                      gAdvancedPane.removeOfflineApp);
 #ifdef MOZ_UPDATER
     setEventListener("updateRadioGroup", "command",
                      gAdvancedPane.updateWritePrefs);
-#endif
     setEventListener("showUpdateHistory", "command",
                      gAdvancedPane.showUpdates);
+#endif
     setEventListener("viewCertificatesButton", "command",
                      gAdvancedPane.showCertificates);
     setEventListener("viewSecurityDevicesButton", "command",
                      gAdvancedPane.showSecurityDevices);
   },
 
   /**
    * Stores the identity of the current tab in preferences so that the selected
--- a/browser/components/preferences/tests/browser.ini
+++ b/browser/components/preferences/tests/browser.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = buildapp == "mulet"
+skip-if = buildapp == "mulet" || e10s
 support-files =
   head.js
   privacypane_tests_perwindow.js
 
 [browser_advanced_update.js]
 [browser_bug410900.js]
 [browser_bug705422.js]
 skip-if = e10s # Bug 941459 - pushPrefEnv, popPrefEnv in specialPowersAPI.js not e10s friendly
@@ -12,10 +12,12 @@ skip-if = e10s # Bug 941459 - pushPrefEn
 [browser_connection_bug388287.js]
 [browser_cookies_exceptions.js]
 [browser_healthreport.js]
 skip-if = !healthreport || (os == 'linux' && debug)
 [browser_permissions.js]
 [browser_privacypane_1.js]
 [browser_privacypane_3.js]
 [browser_privacypane_4.js]
+skip-if = e10s # leaks windows
 [browser_privacypane_5.js]
+skip-if = e10s # leaks windows
 [browser_privacypane_8.js]
--- a/browser/components/privatebrowsing/test/browser/browser.ini
+++ b/browser/components/privatebrowsing/test/browser/browser.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-skip-if = buildapp == "mulet"
+skip-if = buildapp == "mulet" || e10s
 support-files =
   browser_privatebrowsing_concurrent_page.html
   browser_privatebrowsing_cookieacceptdialog.html
   browser_privatebrowsing_geoprompt_page.html
   browser_privatebrowsing_localStorage_before_after_page.html
   browser_privatebrowsing_localStorage_before_after_page2.html
   browser_privatebrowsing_localStorage_page1.html
   browser_privatebrowsing_localStorage_page2.html
@@ -12,29 +12,24 @@ support-files =
   browser_privatebrowsing_protocolhandler_page.html
   browser_privatebrowsing_windowtitle_page.html
   head.js
   popup.html
   title.sjs
 
 [browser_privatebrowsing_DownloadLastDirWithCPS.js]
 [browser_privatebrowsing_aboutHomeButtonAfterWindowClose.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content (win.getComputedStyle(win.gBrowser.contentDocument.getElementById("restorePreviousSession")))
 [browser_privatebrowsing_aboutSessionRestore.js]
-skip-if = e10s # Bug ?????? -  "leaked until shutdown [nsGlobalWindow...]"
 [browser_privatebrowsing_cache.js]
 [browser_privatebrowsing_certexceptionsui.js]
 [browser_privatebrowsing_concurrent.js]
-skip-if = e10s # Bug ?????? - test directly manipulates content (private_tab.docShell.QueryInterface...)
 [browser_privatebrowsing_cookieacceptdialog.js]
 [browser_privatebrowsing_crh.js]
 [browser_privatebrowsing_downloadLastDir.js]
-skip-if = e10s # Bug ?????? MockFilePicker cleanup failing ( nsresult: "0x80040154 (NS_ERROR_FACTORY_NOT_REGISTERED)" location: "JS frame :: resource://specialpowers/MockFilePicker.jsm :: this.MockFilePicker.cleanup :: line 84")
 [browser_privatebrowsing_downloadLastDir_c.js]
-skip-if = e10s # Bug ?????? MockFilePicker cleanup failing ( nsresult: "0x80040154 (NS_ERROR_FACTORY_NOT_REGISTERED)" location: "JS frame :: resource://specialpowers/MockFilePicker.jsm :: this.MockFilePicker.cleanup :: line 84")
 [browser_privatebrowsing_downloadLastDir_toggle.js]
 [browser_privatebrowsing_geoprompt.js]
 [browser_privatebrowsing_lastpbcontextexited.js]
 [browser_privatebrowsing_localStorage.js]
 [browser_privatebrowsing_localStorage_before_after.js]
 [browser_privatebrowsing_noSessionRestoreMenuOption.js]
 [browser_privatebrowsing_nonbrowser.js]
 [browser_privatebrowsing_opendir.js]
@@ -42,13 +37,10 @@ skip-if = e10s # Bug ?????? MockFilePick
 [browser_privatebrowsing_placestitle.js]
 [browser_privatebrowsing_popupblocker.js]
 [browser_privatebrowsing_protocolhandler.js]
 [browser_privatebrowsing_sidebar.js]
 [browser_privatebrowsing_theming.js]
 [browser_privatebrowsing_ui.js]
 [browser_privatebrowsing_urlbarfocus.js]
 [browser_privatebrowsing_windowtitle.js]
-skip-if = e10s # Bug 918634 - swapFrameLoaders
 [browser_privatebrowsing_zoom.js]
-skip-if = e10s # Bug 691614 - e10s support for content zooming
 [browser_privatebrowsing_zoomrestore.js]
-skip-if = e10s # Bug 691614 - e10s support for content zooming
--- a/browser/components/safebrowsing/content/test/browser.ini
+++ b/browser/components/safebrowsing/content/test/browser.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 support-files = head.js
 
 [browser_bug400731.js]
+skip-if = e10s
 [browser_bug415846.js]
 skip-if = true
 # Disabled because it seems to now touch network resources
 # skip-if = os == "mac"
 # Disabled on Mac because of its bizarre special-and-unique
 # snowflake of a help menu.
--- a/browser/components/translation/test/browser.ini
+++ b/browser/components/translation/test/browser.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 support-files =
   bing.sjs
   fixtures/bug1022725-fr.html
   fixtures/result-da39a3ee5e.txt
 
 [browser_translation_bing.js]
 [browser_translation_fhr.js]
+skip-if = e10s
 [browser_translation_infobar.js]
 [browser_translation_exceptions.js]
--- a/browser/config/mozconfigs/win64/beta
+++ b/browser/config/mozconfigs/win64/beta
@@ -1,8 +1,9 @@
+. "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-opt"
 
 mk_add_options MOZ_PGO=1
 
 ac_add_options --enable-official-branding
 . $topsrcdir/build/win64/mozconfig.vs2010
 
--- a/browser/config/mozconfigs/win64/release
+++ b/browser/config/mozconfigs/win64/release
@@ -1,10 +1,11 @@
 # This make file should be identical to the beta mozconfig, apart from the
 # safeguard below
+. "$topsrcdir/build/mozconfig.win-common"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-win64"
 . "$topsrcdir/browser/config/mozconfigs/win64/common-opt"
 
 mk_add_options MOZ_PGO=1
 
 ac_add_options --enable-official-branding
 
 # safeguard against someone forgetting to re-set EARLY_BETA_OR_EARLIER in
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -295,16 +295,17 @@
 @BINPATH@/components/services-crypto-component.xpt
 #ifdef MOZ_CAPTIVEDETECT
 @BINPATH@/components/captivedetect.xpt
 #endif
 @BINPATH@/browser/components/shellservice.xpt
 @BINPATH@/components/shistory.xpt
 @BINPATH@/components/spellchecker.xpt
 @BINPATH@/components/storage.xpt
+@BINPATH@/components/toolkit_filewatcher.xpt
 @BINPATH@/components/toolkit_finalizationwitness.xpt
 @BINPATH@/components/toolkit_formautofill.xpt
 @BINPATH@/components/toolkit_osfile.xpt
 @BINPATH@/components/toolkit_xulstore.xpt
 @BINPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @BINPATH@/components/toolkitremote.xpt
 #endif
--- a/browser/modules/test/browser.ini
+++ b/browser/modules/test/browser.ini
@@ -1,16 +1,17 @@
 [DEFAULT]
 support-files =
   head.js
   image.png
   uitour.*
 
 [browser_BrowserUITelemetry_buckets.js]
 [browser_ContentSearch.js]
+skip-if = e10s
 support-files =
   contentSearch.js
   contentSearchBadImage.xml
   contentSearchSuggestions.sjs
   contentSearchSuggestions.xml
 [browser_NetworkPrioritizer.js]
 skip-if = e10s # Bug 666804 - Support NetworkPrioritizer in e10s
 [browser_SignInToWebsite.js]
rename from build/mozconfig.vs2010-common
rename to build/mozconfig.vs-common
--- a/build/win32/mozconfig.vs2010
+++ b/build/win32/mozconfig.vs2010
@@ -1,13 +1,13 @@
 export INCLUDE=/d/msvs10/vc/include:/d/msvs10/vc/atlmfc/include:/d/sdks/v7.0/include:/d/sdks/v7.0/include/atl:/d/msvs8/VC/PlatformSDK/include:/d/sdks/dx10/include
 export LIBPATH=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727
 export LIB=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/d/sdks/v7.0/lib:/d/msvs8/VC/PlatformSDK/lib:/d/msvs8/SDK/v2.0/lib:/d/mozilla-build/atlthunk_compat:/d/sdks/dx10/lib/x86
 export PATH="/d/msvs10/VSTSDB/Deploy:/d/msvs10/Common7/IDE/:/d/msvs10/VC/BIN:/d/msvs10/Common7/Tools:/d/msvs10/VC/VCPackages:${PATH}"
 export WIN32_REDIST_DIR=/d/msvs10/VC/redist/x86/Microsoft.VC100.CRT
 
-. $topsrcdir/build/mozconfig.vs2010-common
+. $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style LIB
 mk_export_correct_style LIBPATH
 mk_export_correct_style PATH
 mk_export_correct_style INCLUDE
 mk_export_correct_style WIN32_REDIST_DIR
--- a/build/win32/mozconfig.vs2010-win64
+++ b/build/win32/mozconfig.vs2010-win64
@@ -20,17 +20,17 @@ export LIBPATH=/c/Program\ Files\ \(x86\
 export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
 
 ## paths: win8 sdk x86 (32-bit) tools, msvc 10 (32-bit) build toolchain, moz tools  ##
 export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
 
 ## WindowsSDKDir ##
 export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
 
-. $topsrcdir/build/mozconfig.vs2010-common
+. $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style LIB
 mk_export_correct_style LIBPATH
 mk_export_correct_style PATH
 mk_export_correct_style INCLUDE
 mk_export_correct_style WIN32_REDIST_DIR
 
 mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"
copy from build/win32/mozconfig.vs2010-win64
copy to build/win32/mozconfig.vs2013-win64
--- a/build/win32/mozconfig.vs2010-win64
+++ b/build/win32/mozconfig.vs2013-win64
@@ -1,36 +1,28 @@
-
-if [ -d "/c/PROGRA~2/MICROS~2.0" ]; then
-  # /c/Program Files (x86)/Microsoft Visual Studio 10.0
-  _VSPATH="/c/PROGRA~2/MICROS~2.0"
-else
-  _VSPATH="/c/tools/msvs10"
-fi
-
-## SDK redist ##
-export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC100.CRT
+_VSPATH="/c/tools/vs2013"
+export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x86/Microsoft.VC120.CRT
 
 ## moz tools location for 64-bit builders ##
 export MOZ_TOOLS=C:/mozilla-build/moztools
 
-## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ##
+## includes: win8 sdk includes, winrt headers for metro, msvc std library, directx sdk for d3d9 ##
 export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
 
-## libs: win8 sdk x86 (32-bit) libs, msvc 10 (32-bit) std library, msvc 10 atl libs, directx sdk (32-bit) for d3d9  ##
+## libs: win8 sdk x86 (32-bit) libs, msvc (32-bit) std library, msvc atl libs, directx sdk (32-bit) for d3d9  ##
 export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
 export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x86:${_VSPATH}/vc/lib:${_VSPATH}/vc/atlmfc/lib:/c/tools/sdks/dx10/lib
 
-## paths: win8 sdk x86 (32-bit) tools, msvc 10 (32-bit) build toolchain, moz tools  ##
-export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
+## paths: win8 sdk x86 (32-bit) tools, msvc (64-bit compiling 32-bit) build toolchain, moz tools  ##
+export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x86:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64_x86:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:/c/mozilla-build/moztools:${PATH}"
 
 ## WindowsSDKDir ##
 export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
 
-. $topsrcdir/build/mozconfig.vs2010-common
+. $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style LIB
 mk_export_correct_style LIBPATH
 mk_export_correct_style PATH
 mk_export_correct_style INCLUDE
 mk_export_correct_style WIN32_REDIST_DIR
 
 mk_add_options "export MOZ_TOOLS=$MOZ_TOOLS"
--- a/build/win64/mozconfig.vs2010
+++ b/build/win64/mozconfig.vs2010
@@ -26,15 +26,15 @@ export WINDOWSSDKDIR="/c/Program Files (
 # https://connect.microsoft.com/VisualStudio/feedback/details/686117/
 if [ -f /c/PROGRA~2/MICROS~2.0/VC/BIN/x86_amd64/link.exe ]; then
   # /c/Program Files (x86)/Microsoft Visual Studio 10.0
   export LD=c:/PROGRA~2/MICROS~2.0/VC/BIN/x86_amd64/link.exe
 else
   export LD=c:/tools/msvs10/VC/BIN/x86_amd64/link.exe
 fi
 
-. $topsrcdir/build/mozconfig.vs2010-common
+. $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style LIB
 mk_export_correct_style LIBPATH
 mk_export_correct_style PATH
 mk_export_correct_style INCLUDE
 mk_export_correct_style WIN32_REDIST_DIR
copy from build/win64/mozconfig.vs2010
copy to build/win64/mozconfig.vs2013
--- a/build/win64/mozconfig.vs2010
+++ b/build/win64/mozconfig.vs2013
@@ -1,40 +1,23 @@
-
-if [ -d "/c/PROGRA~2/MICROS~2.0" ]; then
-  # /c/Program Files (x86)/Microsoft Visual Studio 10.0
-  _VSPATH="/c/PROGRA~2/MICROS~2.0"
-else
-  _VSPATH="/c/tools/msvs10"
-fi
-
-## SDK redist ##
-export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC100.CRT
+_VSPATH="/c/tools/vs2013"
+export WIN32_REDIST_DIR=${_VSPATH}/VC/redist/x64/Microsoft.VC120.CRT
 
 ## includes: win8 sdk includes, winrt headers for metro, msvc 10 std library, directx sdk for d3d9 ##
 export INCLUDE=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/shared:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/um:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl:/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/include/winrt/wrl/wrappers:${_VSPATH}/vc/include:${_VSPATH}/vc/atlmfc/include:/c/tools/sdks/dx10/include
 
 ## libs: win8 sdk x64 (64-bit) libs, msvc 10 (64-bit) std library, msvc 10 atl libs, directx sdk (64-bit) for d3d9  ##
 export LIBPATH=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
 export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/8.0/Lib/win8/um/x64:${_VSPATH}/vc/lib/amd64:${_VSPATH}/vc/atlmfc/lib/amd64:/c/tools/sdks/dx10/lib/x64
 
 ## paths: win8 sdk x64 (64-bit) tools, msvc 10 (64-bit) build toolchain, moz tools  ##
 export PATH="/c/Program Files (x86)/Windows Kits/8.0/bin/x64:${_VSPATH}/Common7/IDE:${_VSPATH}/VC/BIN/amd64:${_VSPATH}/VC/BIN/x86_amd64:${_VSPATH}/VC/BIN:${_VSPATH}/Common7/Tools:${_VSPATH}/VC/VCPackages:${PATH}"
 
 ## WindowsSDKDir ##
 export WINDOWSSDKDIR="/c/Program Files (x86)/Windows Kits/8.0/"
 
-# Use 32bit linker for PGO crash bug.
-# https://connect.microsoft.com/VisualStudio/feedback/details/686117/
-if [ -f /c/PROGRA~2/MICROS~2.0/VC/BIN/x86_amd64/link.exe ]; then
-  # /c/Program Files (x86)/Microsoft Visual Studio 10.0
-  export LD=c:/PROGRA~2/MICROS~2.0/VC/BIN/x86_amd64/link.exe
-else
-  export LD=c:/tools/msvs10/VC/BIN/x86_amd64/link.exe
-fi
-
-. $topsrcdir/build/mozconfig.vs2010-common
+. $topsrcdir/build/mozconfig.vs-common
 
 mk_export_correct_style LIB
 mk_export_correct_style LIBPATH
 mk_export_correct_style PATH
 mk_export_correct_style INCLUDE
 mk_export_correct_style WIN32_REDIST_DIR
--- a/caps/nsNullPrincipalURI.h
+++ b/caps/nsNullPrincipalURI.h
@@ -29,17 +29,17 @@ class nsNullPrincipalURI MOZ_FINAL : pub
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIURI
 
   // nsISizeOf
   virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
 
-  nsNullPrincipalURI(const nsCString &aSpec);
+  explicit nsNullPrincipalURI(const nsCString &aSpec);
 
 private:
   ~nsNullPrincipalURI() {}
 
   nsCString mScheme;
   nsCString mPath;
 };
 
--- a/caps/nsPrincipal.h
+++ b/caps/nsPrincipal.h
@@ -118,17 +118,17 @@ protected:
    * Returns the app status of the principal based on mAppId and mInMozBrowser.
    */
   uint16_t GetAppStatus();
 };
 
 class nsExpandedPrincipal : public nsIExpandedPrincipal, public nsBasePrincipal
 {
 public:
-  nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
+  explicit nsExpandedPrincipal(nsTArray< nsCOMPtr<nsIPrincipal> > &aWhiteList);
 
 protected:
   virtual ~nsExpandedPrincipal();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIEXPANDEDPRINCIPAL
   NS_DECL_NSISERIALIZABLE
--- a/chrome/nsChromeRegistryChrome.h
+++ b/chrome/nsChromeRegistryChrome.h
@@ -122,17 +122,17 @@ class nsChromeRegistryChrome : public ns
   };
 
   class OverlayListEntry : public nsURIHashKey
   {
    public:
     typedef nsURIHashKey::KeyType        KeyType;
     typedef nsURIHashKey::KeyTypePointer KeyTypePointer;
 
-    OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
+    explicit OverlayListEntry(KeyTypePointer aKey) : nsURIHashKey(aKey) { }
     OverlayListEntry(OverlayListEntry&& toMove) : nsURIHashKey(mozilla::Move(toMove)),
                                                   mArray(mozilla::Move(toMove.mArray)) { }
     ~OverlayListEntry() { }
 
     void AddURI(nsIURI* aURI);
 
     nsCOMArray<nsIURI> mArray;
   };
--- a/config/config.mk
+++ b/config/config.mk
@@ -354,29 +354,35 @@ MY_RULES	:= $(DEPTH)/config/myrules.mk
 #
 CCC = $(CXX)
 
 # Java macros
 JAVA_GEN_DIR  = _javagen
 JAVA_DIST_DIR = $(DEPTH)/$(JAVA_GEN_DIR)
 JAVA_IFACES_PKG_NAME = org/mozilla/interfaces
 
-OS_INCLUDES += $(MOZ_JPEG_CFLAGS) $(MOZ_PNG_CFLAGS) $(MOZ_ZLIB_CFLAGS) $(MOZ_PIXMAN_CFLAGS)
-
-# NSPR_CFLAGS and NSS_CFLAGS must appear ahead of OS_INCLUDES to avoid Linux
-# builds wrongly picking up system NSPR/NSS header files.
 INCLUDES = \
   -I$(srcdir) \
   -I. \
   $(LOCAL_INCLUDES) \
   -I$(DIST)/include \
+  $(NULL)
+
+ifndef IS_GYP_DIR
+# NSPR_CFLAGS and NSS_CFLAGS must appear ahead of the other flags to avoid Linux
+# builds wrongly picking up system NSPR/NSS header files.
+OS_INCLUDES := \
   $(if $(LIBXUL_SDK),-I$(LIBXUL_SDK)/include) \
   $(NSPR_CFLAGS) $(NSS_CFLAGS) \
-  $(OS_INCLUDES) \
+  $(MOZ_JPEG_CFLAGS) \
+  $(MOZ_PNG_CFLAGS) \
+  $(MOZ_ZLIB_CFLAGS) \
+  $(MOZ_PIXMAN_CFLAGS) \
   $(NULL)
+endif
 
 include $(topsrcdir)/config/static-checking-config.mk
 
 CFLAGS		= $(OS_CPPFLAGS) $(OS_CFLAGS)
 CXXFLAGS	= $(OS_CPPFLAGS) $(OS_CXXFLAGS)
 LDFLAGS		= $(OS_LDFLAGS) $(MOZBUILD_LDFLAGS) $(MOZ_FIX_LINK_PATHS)
 
 # Allow each module to override the *default* optimization settings
@@ -478,18 +484,18 @@ HOST_CMMFLAGS += -fobjc-exceptions
 OS_COMPILE_CMFLAGS += -fobjc-exceptions
 OS_COMPILE_CMMFLAGS += -fobjc-exceptions
 ifeq ($(MOZ_WIDGET_TOOLKIT),uikit)
 OS_COMPILE_CMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
 OS_COMPILE_CMMFLAGS += -fobjc-abi-version=2 -fobjc-legacy-dispatch
 endif
 endif
 
-COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(EXTRA_COMPILE_FLAGS)
-COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(EXTRA_COMPILE_FLAGS)
+COMPILE_CFLAGS	= $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CFLAGS) $(CFLAGS) $(MOZBUILD_CFLAGS) $(EXTRA_COMPILE_FLAGS)
+COMPILE_CXXFLAGS = $(if $(DISABLE_STL_WRAPPING),,$(STL_FLAGS)) $(VISIBILITY_FLAGS) $(DEFINES) $(INCLUDES) $(OS_INCLUDES) $(DSO_CFLAGS) $(DSO_PIC_CFLAGS) $(RTL_FLAGS) $(OS_CPPFLAGS) $(OS_COMPILE_CXXFLAGS) $(CXXFLAGS) $(MOZBUILD_CXXFLAGS) $(EXTRA_COMPILE_FLAGS)
 COMPILE_CMFLAGS = $(OS_COMPILE_CMFLAGS) $(MOZBUILD_CMFLAGS) $(EXTRA_COMPILE_FLAGS)
 COMPILE_CMMFLAGS = $(OS_COMPILE_CMMFLAGS) $(MOZBUILD_CMMFLAGS) $(EXTRA_COMPILE_FLAGS)
 ASFLAGS += $(EXTRA_ASSEMBLER_FLAGS)
 
 ifndef CROSS_COMPILE
 HOST_CFLAGS += $(RTL_FLAGS)
 endif
 
@@ -745,27 +751,10 @@ PLY_INCLUDE = -I$(topsrcdir)/other-licen
 export CL_INCLUDES_PREFIX
 # Make sure that the build system can handle non-ASCII characters
 # in environment variables to prevent it from breking silently on
 # non-English systems.
 export NONASCII
 
 DEFINES += -DNO_NSPR_10_SUPPORT
 
-ifdef IS_GYP_DIR
-LOCAL_INCLUDES += \
-  -I$(topsrcdir)/ipc/chromium/src \
-  -I$(topsrcdir)/ipc/glue \
-  -I$(DEPTH)/ipc/ipdl/_ipdlheaders \
-  $(NULL)
-
-ifeq (WINNT,$(OS_TARGET))
-# These get set via VC project file settings for normal GYP builds.
-DEFINES += -DUNICODE -D_UNICODE
-endif
-
-DISABLE_STL_WRAPPING := 1
-# Skip most Mozilla-specific include locations.
-INCLUDES = -I. $(LOCAL_INCLUDES) -I$(DEPTH)/dist/include
-endif
-
 # Freeze the values specified by moz.build to catch them if they fail.
 $(foreach var,$(_MOZBUILD_EXTERNAL_VARIABLES) $(_DEPRECATED_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
--- a/content/base/src/DOMRect.h
+++ b/content/base/src/DOMRect.h
@@ -137,16 +137,19 @@ public:
   }
   void SetHeight(double aHeight)
   {
     mHeight = aHeight;
   }
 
 protected:
   double mX, mY, mWidth, mHeight;
+
+private:
+  ~DOMRect() {};
 };
 
 class DOMRectList MOZ_FINAL : public nsIDOMClientRectList,
                               public nsWrapperCache
 {
   ~DOMRectList() {}
 
 public:
@@ -205,17 +208,11 @@ public:
 
 protected:
   nsTArray<nsRefPtr<DOMRect> > mArray;
   nsCOMPtr<nsISupports> mParent;
 };
 
 }
 
-template<>
-struct HasDangerousPublicDestructor<dom::DOMRect>
-{
-  static const bool value = true;
-};
-
 }
 
 #endif /*MOZILLA_DOMRECT_H_*/
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -1596,16 +1596,22 @@ nsDocument::~nsDocument()
 #ifdef PR_LOGGING
   if (gDocumentLeakPRLog)
     PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG,
            ("DOCUMENT %p destroyed", this));
 #endif
 
   NS_ASSERTION(!mIsShowing, "Destroying a currently-showing document");
 
+  // Note: This assert is only non-fatal because mochitest-bc triggers
+  // it... as well as the preceding assert about !mIsShowing.
+  NS_ASSERTION(!mObservingAppThemeChanged,
+               "Document leaked to shutdown, then the observer service dropped "
+               "its ref to us so we were able to go away.");
+
   if (IsTopLevelContentDocument()) {
     //don't report for about: pages
     nsCOMPtr<nsIPrincipal> principal = GetPrincipal();
     nsCOMPtr<nsIURI> uri;
     principal->GetURI(getter_AddRefs(uri));
     bool isAboutScheme = true;
     if (uri) {
       uri->SchemeIs("about", &isAboutScheme);
@@ -8868,17 +8874,20 @@ nsDocument::OnPageShow(bool aPersisted,
   // Dispatch observer notification to notify observers page is shown.
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   nsIPrincipal *principal = GetPrincipal();
   os->NotifyObservers(static_cast<nsIDocument*>(this),
                       nsContentUtils::IsSystemPrincipal(principal) ?
                         "chrome-page-shown" :
                         "content-page-shown",
                       nullptr);
-  os->AddObserver(this, "app-theme-changed", /* ownsWeak */ false);
+  if (!mObservingAppThemeChanged) {
+    os->AddObserver(this, "app-theme-changed", /* ownsWeak */ false);
+    mObservingAppThemeChanged = true;
+  }
 
   DispatchPageTransition(target, NS_LITERAL_STRING("pageshow"), aPersisted);
 }
 
 static bool
 NotifyPageHide(nsIDocument* aDocument, void* aData)
 {
   const bool* aPersistedPtr = static_cast<const bool*>(aData);
@@ -8944,16 +8953,17 @@ nsDocument::OnPageHide(bool aPersisted,
     nsIPrincipal* principal = GetPrincipal();
     os->NotifyObservers(static_cast<nsIDocument*>(this),
                         nsContentUtils::IsSystemPrincipal(principal) ?
                           "chrome-page-hidden" :
                           "content-page-hidden",
                         nullptr);
 
     os->RemoveObserver(this, "app-theme-changed");
+    mObservingAppThemeChanged = false;
   }
 
   DispatchPageTransition(target, NS_LITERAL_STRING("pagehide"), aPersisted);
 
   mVisible = false;
 
   UpdateVisibilityState();
 
--- a/content/base/src/nsDocument.h
+++ b/content/base/src/nsDocument.h
@@ -1593,16 +1593,22 @@ public:
   friend class nsPointerLockPermissionRequest;
   friend class nsCallRequestFullScreen;
   // When set, trying to lock the pointer doesn't require permission from the
   // user.
   bool mAllowRelocking:1;
 
   bool mAsyncFullscreenPending:1;
 
+  // Whether we're observing the "app-theme-changed" observer service
+  // notification.  We need to keep track of this because we might get multiple
+  // OnPageShow notifications in a row without an OnPageHide in between, if
+  // we're getting document.open()/close() called on us.
+  bool mObservingAppThemeChanged:1;
+
   // Keeps track of whether we have a pending
   // 'style-sheet-applicable-state-changed' notification.
   bool mSSApplicableStateNotificationPending:1;
 
   uint32_t mCancelledPointerLockRequests;
 
   uint8_t mXMLDeclarationBits;
 
--- a/content/base/src/nsFormData.h
+++ b/content/base/src/nsFormData.h
@@ -21,20 +21,20 @@ namespace mozilla {
 class ErrorResult;
 
 namespace dom {
 class HTMLFormElement;
 class GlobalObject;
 } // namespace dom
 } // namespace mozilla
 
-class nsFormData : public nsIDOMFormData,
-                   public nsIXHRSendable,
-                   public nsFormSubmission,
-                   public nsWrapperCache
+class nsFormData MOZ_FINAL : public nsIDOMFormData,
+                             public nsIXHRSendable,
+                             public nsFormSubmission,
+                             public nsWrapperCache
 {
   ~nsFormData() {}
 
 public:
   explicit nsFormData(nsISupports* aOwner = nullptr);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsFormData,
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1030,16 +1030,26 @@ nsObjectLoadingContent::BuildParametersA
   bool isJava = nsPluginHost::IsJavaMIMEType(mContentType.get());
 
   nsCString codebase;
   if (isJava) {
       mBaseURI->GetSpec(codebase);
   }
 
   nsAdoptingCString wmodeOverride = Preferences::GetCString("plugins.force.wmode");
+#if defined(XP_WIN) || defined(XP_LINUX)
+  // Bug 923745 (/Bug 1061995) - Until we support windowed mode plugins in
+  // content processes, force flash to use a windowless rendering mode. This
+  // hack should go away when bug 923746 lands. (OS X plugins always use some
+  // native widgets, so unfortunately this does not help there)
+  if (wmodeOverride.IsEmpty() &&
+      XRE_GetProcessType() == GeckoProcessType_Content) {
+    wmodeOverride.AssignLiteral("transparent");
+  }
+#endif
 
   for (uint32_t i = 0; i < mCachedAttributes.Length(); i++) {
     if (!wmodeOverride.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("wmode")) {
       CopyASCIItoUTF16(wmodeOverride, mCachedAttributes[i].mValue);
       wmodeOverride.Truncate();
     } else if (!codebase.IsEmpty() && mCachedAttributes[i].mName.EqualsIgnoreCase("codebase")) {
       CopyASCIItoUTF16(codebase, mCachedAttributes[i].mValue);
       codebase.Truncate();
--- a/content/base/src/nsScriptLoader.h
+++ b/content/base/src/nsScriptLoader.h
@@ -30,17 +30,17 @@ namespace dom {
 class AutoJSAPI;
 }
 }
 
 //////////////////////////////////////////////////////////////
 // Script loader implementation
 //////////////////////////////////////////////////////////////
 
-class nsScriptLoader : public nsIStreamLoaderObserver
+class nsScriptLoader MOZ_FINAL : public nsIStreamLoaderObserver
 {
   class MOZ_STACK_CLASS AutoCurrentScriptUpdater
   {
   public:
     AutoCurrentScriptUpdater(nsScriptLoader* aScriptLoader,
                              nsIScriptElement* aCurrentScript)
       : mOldScript(aScriptLoader->mCurrentScript)
       , mScriptLoader(aScriptLoader)
--- a/content/html/content/src/HTMLPropertiesCollection.h
+++ b/content/html/content/src/HTMLPropertiesCollection.h
@@ -43,19 +43,19 @@ public:
 protected:
   virtual ~PropertyStringList();
 
   virtual void EnsureFresh() MOZ_OVERRIDE;
 
   nsRefPtr<HTMLPropertiesCollection> mCollection;
 };
 
-class HTMLPropertiesCollection : public nsIHTMLCollection,
-                                 public nsStubMutationObserver,
-                                 public nsWrapperCache
+class HTMLPropertiesCollection MOZ_FINAL : public nsIHTMLCollection,
+                                           public nsStubMutationObserver,
+                                           public nsWrapperCache
 {
   friend class PropertyNodeList;
   friend class PropertyStringList;
 public:
   explicit HTMLPropertiesCollection(nsGenericHTMLElement* aRoot);
 
   // nsWrapperCache
   using nsWrapperCache::GetWrapperPreserveColor;
--- a/content/media/AbstractMediaDecoder.h
+++ b/content/media/AbstractMediaDecoder.h
@@ -60,21 +60,16 @@ public:
   // Called by the decode thread to keep track of the number of bytes read
   // from the resource.
   virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) = 0;
 
   // Increments the parsed and decoded frame counters by the passed in counts.
   // Can be called on any thread.
   virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) = 0;
 
-  // Returns the end time of the last sample in the media. Note that a media
-  // can have a non-zero start time, so the end time may not necessarily be
-  // the same as the duration (i.e. duration is (end_time - start_time)).
-  virtual int64_t GetEndMediaTime() const = 0;
-
   // Return the duration of the media in microseconds.
   virtual int64_t GetMediaDuration() = 0;
 
   // Set the duration of the media in microseconds.
   virtual void SetMediaDuration(int64_t aDuration) = 0;
 
   // Sets the duration of the media in microseconds. The MediaDecoder
   // fires a durationchange event to its owner (e.g., an HTML audio
--- a/content/media/GraphDriver.cpp
+++ b/content/media/GraphDriver.cpp
@@ -12,16 +12,30 @@
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gMediaStreamGraphLog;
 #define STREAM_LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
 #else
 #define STREAM_LOG(type, msg)
 #endif
 
+// We don't use NSPR log here because we want this interleaved with adb logcat
+// on Android/B2G
+// #define ENABLE_LIFECYCLE_LOG
+#ifdef ENABLE_LIFECYCLE_LOG
+#ifdef ANDROID
+#include "android/log.h"
+#define LIFECYCLE_LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG" , ## __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
+#else
+#define LIFECYCLE_LOG(...) printf(__VA_ARGS__);printf("\n");
+#endif
+#else
+#define LIFECYCLE_LOG(...)
+#endif
+
 namespace mozilla {
 
 struct AutoProfilerUnregisterThread
 {
   // The empty ctor is used to silence a pre-4.8.0 GCC unused variable warning.
   AutoProfilerUnregisterThread()
   {
   }
@@ -63,20 +77,22 @@ void GraphDriver::SetGraphTime(GraphDriv
   STREAM_LOG(PR_LOG_DEBUG, ("Setting previous driver: %p (%s)", aPreviousDriver, aPreviousDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
   MOZ_ASSERT(!mPreviousDriver);
   mPreviousDriver = aPreviousDriver;
 }
 
 void GraphDriver::SwitchAtNextIteration(GraphDriver* aNextDriver)
 {
 
-  STREAM_LOG(PR_LOG_DEBUG, ("Switching to new driver: %p (%s)", aNextDriver, aNextDriver->AsAudioCallbackDriver() ? "AudioCallbackDriver" : "SystemClockDriver"));
+  LIFECYCLE_LOG("Switching to new driver: %p (%s)",
+      aNextDriver, aNextDriver->AsAudioCallbackDriver() ?
+      "AudioCallbackDriver" : "SystemClockDriver");
   // Sometimes we switch twice to a new driver per iteration, this is probably a
   // bug.
-  MOZ_ASSERT(!mNextDriver || !mNextDriver->AsAudioCallbackDriver());
+  MOZ_ASSERT(!mNextDriver || mNextDriver->AsAudioCallbackDriver());
   mNextDriver = aNextDriver;
 }
 
 void GraphDriver::EnsureImmediateWakeUpLocked()
 {
   mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
   mWaitState = WAITSTATE_WAKING_UP;
   mGraphImpl->GetMonitor().Notify();
@@ -110,65 +126,85 @@ void GraphDriver::EnsureNextIterationLoc
   }
 
   if (mNeedAnotherIteration) {
     return;
   }
   mNeedAnotherIteration = true;
 }
 
+class MediaStreamGraphShutdownThreadRunnable : public nsRunnable {
+public:
+  explicit MediaStreamGraphShutdownThreadRunnable(GraphDriver* aDriver)
+    : mDriver(aDriver)
+  {
+  }
+  NS_IMETHOD Run()
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    LIFECYCLE_LOG("MediaStreamGraphShutdownThreadRunnable for graph %p",
+        mDriver->GraphImpl());
+    // We can't release an audio driver on the main thread, because it can be
+    // blocking.
+    if (mDriver->AsAudioCallbackDriver()) {
+      LIFECYCLE_LOG("Releasing audio driver off main thread.");
+      nsRefPtr<AsyncCubebTask> releaseEvent =
+        new AsyncCubebTask(mDriver->AsAudioCallbackDriver(),
+                           AsyncCubebTask::SHUTDOWN);
+      mDriver = nullptr;
+      releaseEvent->Dispatch();
+    } else {
+      LIFECYCLE_LOG("Dropping driver reference for SystemClockDriver.");
+      mDriver = nullptr;
+    }
+    return NS_OK;
+  }
+private:
+  nsRefPtr<GraphDriver> mDriver;
+};
+
+void GraphDriver::Shutdown()
+{
+  if (AsAudioCallbackDriver()) {
+    LIFECYCLE_LOG("Releasing audio driver off main thread (GraphDriver::Shutdown).\n");
+    nsRefPtr<AsyncCubebTask> releaseEvent =
+      new AsyncCubebTask(AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
+    releaseEvent->Dispatch();
+  }
+}
+
 ThreadedDriver::ThreadedDriver(MediaStreamGraphImpl* aGraphImpl)
   : GraphDriver(aGraphImpl)
 { }
 
 ThreadedDriver::~ThreadedDriver()
 {
   if (mThread) {
     mThread->Shutdown();
   }
 }
-
-class MediaStreamGraphShutdownThreadRunnable : public nsRunnable {
-public:
-  explicit MediaStreamGraphShutdownThreadRunnable(GraphDriver* aDriver)
-    : mDriver(aDriver)
-  {
-  }
-  NS_IMETHOD Run()
-  {
-    MOZ_ASSERT(NS_IsMainThread());
-    // We can't release an audio driver on the main thread, because it can be
-    // blocking.
-    if (mDriver->AsAudioCallbackDriver()) {
-      STREAM_LOG(PR_LOG_DEBUG, ("Releasing audio driver off main thread.\n"));
-      nsRefPtr<AsyncCubebTask> releaseEvent =
-        new AsyncCubebTask(mDriver->AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
-      mDriver = nullptr;
-      releaseEvent->Dispatch();
-    } else {
-      mDriver = nullptr;
-    }
-    return NS_OK;
-  }
-private:
-  nsRefPtr<GraphDriver> mDriver;
-};
-
 class MediaStreamGraphInitThreadRunnable : public nsRunnable {
 public:
   explicit MediaStreamGraphInitThreadRunnable(ThreadedDriver* aDriver)
     : mDriver(aDriver)
   {
   }
   NS_IMETHOD Run()
   {
     char aLocal;
     STREAM_LOG(PR_LOG_DEBUG, ("Starting system thread"));
     profiler_register_thread("MediaStreamGraph", &aLocal);
+    LIFECYCLE_LOG("Starting a new system driver for graph %p\n",
+                  mDriver->mGraphImpl);
     if (mDriver->mPreviousDriver) {
+      LIFECYCLE_LOG("%p releasing an AudioCallbackDriver(%p), for graph %p\n",
+                    mDriver,
+                    mDriver->mPreviousDriver.get(),
+                    mDriver->GraphImpl());
       MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
       // Stop and release the previous driver off-main-thread.
       nsRefPtr<AsyncCubebTask> releaseEvent =
         new AsyncCubebTask(mDriver->mPreviousDriver->AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
       mDriver->mPreviousDriver = nullptr;
       releaseEvent->Dispatch();
     } else {
       MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
@@ -180,16 +216,17 @@ public:
   }
 private:
   ThreadedDriver* mDriver;
 };
 
 void
 ThreadedDriver::Start()
 {
+  LIFECYCLE_LOG("Starting thread for a SystemClockDriver  %p\n", mGraphImpl);
   nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
   NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread), event);
 }
 
 void
 ThreadedDriver::Resume()
 {
   Start();
@@ -408,16 +445,27 @@ OfflineClockDriver::WaitForNextIteration
 }
 
 void
 OfflineClockDriver::WakeUp()
 {
   MOZ_ASSERT(false, "An offline graph should not have to wake up.");
 }
 
+AsyncCubebTask::AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation)
+  : mDriver(aDriver),
+    mOperation(aOperation),
+    mShutdownGrip(aDriver->GraphImpl())
+{
+  MOZ_ASSERT(mDriver->mAudioStream || aOperation == INIT, "No audio stream !");
+}
+
+AsyncCubebTask::~AsyncCubebTask()
+{
+}
 
 NS_IMETHODIMP
 AsyncCubebTask::Run()
 {
   MOZ_ASSERT(mThread);
   if (NS_IsMainThread()) {
     mThread->Shutdown(); // can't shutdown from the thread itself, darn
     // don't null out mThread!
@@ -427,24 +475,28 @@ AsyncCubebTask::Run()
     // assumes the caller does.
     return NS_OK;
   }
 
   MOZ_ASSERT(mDriver);
 
   switch(mOperation) {
     case AsyncCubebOperation::INIT:
+      LIFECYCLE_LOG("AsyncCubebOperation::INIT\n");
       mDriver->Init();
       break;
     case AsyncCubebOperation::SHUTDOWN:
+      LIFECYCLE_LOG("AsyncCubebOperation::SHUTDOWN\n");
       mDriver->Stop();
       mDriver = nullptr;
+      mShutdownGrip = nullptr;
       break;
     case AsyncCubebOperation::SLEEP: {
       {
+        LIFECYCLE_LOG("AsyncCubebOperation::SLEEP\n");
         MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
         // We might just have been awoken
         if (mDriver->mNeedAnotherIteration) {
           mDriver->mPauseRequested = false;
           mDriver->mWaitState = AudioCallbackDriver::WAITSTATE_RUNNING;
           break;
         }
         mDriver->Stop();
@@ -792,17 +844,17 @@ AudioCallbackDriver::DataCallback(AudioD
     mGraphImpl->SetCurrentDriver(mNextDriver);
     mNextDriver->Start();
     // Returning less than aFrames starts the draining and eventually stops the
     // audio thread. This function will never get called again.
     return aFrames - 1;
   }
 
   if (!stillProcessing) {
-    STREAM_LOG(PR_LOG_DEBUG, ("Stopping audio thread for MediaStreamGraph %p", this));
+    LIFECYCLE_LOG("Stopping audio thread for MediaStreamGraph %p", this);
     return aFrames - 1;
   }
   return aFrames;
 }
 
 void
 AudioCallbackDriver::StateCallback(cubeb_state aState)
 {
--- a/content/media/GraphDriver.h
+++ b/content/media/GraphDriver.h
@@ -91,16 +91,17 @@ public:
   /* Start the graph, init the driver, start the thread. */
   virtual void Start() = 0;
   /* Stop the graph, shutting down the thread. */
   virtual void Stop() = 0;
   /* Resume after a stop */
   virtual void Resume() = 0;
   /* Revive this driver, as more messages just arrived. */
   virtual void Revive() = 0;
+  void Shutdown();
   /* Rate at which the GraphDriver runs, in ms. This can either be user
    * controlled (because we are using a {System,Offline}ClockDriver, and decide
    * how often we want to wakeup/how much we want to process per iteration), or
    * it can be indirectly set by the latency of the audio backend, and the
    * number of buffers of this audio backend: say we have four buffers, and 40ms
    * latency, we will get a callback approximately every 10ms. */
   virtual uint32_t IterationDuration() = 0;
 
@@ -182,16 +183,20 @@ public:
    */
   void EnsureNextIteration();
 
   /**
    * Same thing, but not locked.
    */
   void EnsureNextIterationLocked();
 
+  MediaStreamGraphImpl* GraphImpl() {
+    return mGraphImpl;
+  }
+
 protected:
   // Time of the start of this graph iteration.
   GraphTime mIterationStart;
   // Time of the end of this graph iteration.
   GraphTime mIterationEnd;
   // Time, in the future, for which blocking has been computed.
   GraphTime mStateComputedTime;
   GraphTime mNextStateComputedTime;
@@ -455,39 +460,35 @@ class AsyncCubebTask : public nsRunnable
 public:
   enum AsyncCubebOperation {
     INIT,
     SHUTDOWN,
     SLEEP
   };
 
 
-  AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation)
-    : mDriver(aDriver),
-      mOperation(aOperation)
-  {
-    MOZ_ASSERT(mDriver->mAudioStream || aOperation == INIT, "No audio stream !");
-  }
+  AsyncCubebTask(AudioCallbackDriver* aDriver, AsyncCubebOperation aOperation);
 
   nsresult Dispatch()
   {
     // Can't add 'this' as the event to run, since mThread may not be set yet
     nsresult rv = NS_NewNamedThread("CubebOperation", getter_AddRefs(mThread));
     if (NS_SUCCEEDED(rv)) {
       // Note: event must not null out mThread!
       rv = mThread->Dispatch(this, NS_DISPATCH_NORMAL);
     }
     return rv;
   }
 
 protected:
-  virtual ~AsyncCubebTask() {};
+  virtual ~AsyncCubebTask();
 
 private:
   NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL;
   nsCOMPtr<nsIThread> mThread;
   nsRefPtr<AudioCallbackDriver> mDriver;
   AsyncCubebOperation mOperation;
+  nsRefPtr<MediaStreamGraphImpl> mShutdownGrip;
 };
 
 }
 
 #endif // GRAPHDRIVER_H_
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -125,57 +125,52 @@ NS_IMPL_ISUPPORTS(MediaMemoryTracker, ns
 
 NS_IMPL_ISUPPORTS(MediaDecoder, nsIObserver)
 
 void MediaDecoder::SetDormantIfNecessary(bool aDormant)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
-  if (!mDecoderStateMachine || !mDecoderStateMachine->IsDormantNeeded() || (mPlayState == PLAY_STATE_SHUTDOWN)) {
-    return;
-  }
-
-  if (mIsDormant == aDormant) {
-    // no change to dormant state
+  if (!mDecoderStateMachine ||
+      !mDecoderStateMachine->IsDormantNeeded() ||
+      mPlayState == PLAY_STATE_SHUTDOWN ||
+      mIsDormant == aDormant) {
     return;
   }
 
   if(aDormant) {
     // enter dormant state
     StopProgress();
     DestroyDecodedStream();
     mDecoderStateMachine->SetDormant(true);
 
     int64_t timeUsecs = 0;
     SecondsToUsecs(mCurrentTime, timeUsecs);
     mRequestedSeekTarget = SeekTarget(timeUsecs, SeekTarget::Accurate);
 
-    if (mPlayState == PLAY_STATE_PLAYING){
-      mNextState = PLAY_STATE_PLAYING;
-    } else {
-      mNextState = PLAY_STATE_PAUSED;
-    }
     mNextState = mPlayState;
     mIsDormant = true;
     mIsExitingDormant = false;
     ChangeState(PLAY_STATE_LOADING);
-  } else if ((aDormant != true) && (mPlayState == PLAY_STATE_LOADING)) {
+  } else if (!aDormant && mPlayState == PLAY_STATE_LOADING) {
     // exit dormant state
     // trigger to state machine.
     mDecoderStateMachine->SetDormant(false);
     mIsExitingDormant = true;
   }
 }
 
 void MediaDecoder::Pause()
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
-  if ((mPlayState == PLAY_STATE_LOADING && mIsDormant)  || mPlayState == PLAY_STATE_SEEKING || mPlayState == PLAY_STATE_ENDED) {
+  if ((mPlayState == PLAY_STATE_LOADING && mIsDormant) ||
+      mPlayState == PLAY_STATE_SEEKING ||
+      mPlayState == PLAY_STATE_ENDED) {
     mNextState = PLAY_STATE_PAUSED;
     return;
   }
 
   ChangeState(PLAY_STATE_PAUSED);
 }
 
 void MediaDecoder::SetVolume(double aVolume)
@@ -864,18 +859,21 @@ bool MediaDecoder::IsEnded() const
   MOZ_ASSERT(NS_IsMainThread());
   return mPlayState == PLAY_STATE_ENDED || mPlayState == PLAY_STATE_SHUTDOWN;
 }
 
 void MediaDecoder::PlaybackEnded()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mShuttingDown || mPlayState == MediaDecoder::PLAY_STATE_SEEKING)
+  if (mShuttingDown ||
+      mPlayState == PLAY_STATE_SEEKING ||
+      (mPlayState == PLAY_STATE_LOADING && mIsDormant)) {
     return;
+  }
 
   {
     ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
     for (int32_t i = mOutputStreams.Length() - 1; i >= 0; --i) {
       OutputStreamData& os = mOutputStreams[i];
       if (os.mStream->IsDestroyed()) {
         // Probably the DOM MediaStream was GCed. Clean up.
@@ -1549,21 +1547,16 @@ MediaDecoder::NotifyWaitingForResourcesS
   }
 }
 
 bool MediaDecoder::IsShutdown() const {
   NS_ENSURE_TRUE(GetStateMachine(), true);
   return GetStateMachine()->IsShutdown();
 }
 
-int64_t MediaDecoder::GetEndMediaTime() const {
-  NS_ENSURE_TRUE(GetStateMachine(), -1);
-  return GetStateMachine()->GetEndMediaTime();
-}
-
 // Drop reference to state machine.  Only called during shutdown dance.
 void MediaDecoder::BreakCycles() {
   mDecoderStateMachine = nullptr;
 }
 
 MediaDecoderOwner* MediaDecoder::GetMediaOwner() const
 {
   return mOwner;
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -576,18 +576,16 @@ public:
   // changed. Called on main thread only.
   virtual void NotifyPrincipalChanged();
 
   // Called by the MediaResource to keep track of the number of bytes read
   // from the resource. Called on the main by an event runner dispatched
   // by the MediaResource read functions.
   void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
 
-  int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;
-
   // Return true if we are currently seeking in the media resource.
   // Call on the main thread only.
   virtual bool IsSeeking() const;
 
   // Return true if the decoder has reached the end of playback.
   // Call on the main thread only.
   virtual bool IsEnded() const;
 
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -1445,16 +1445,17 @@ void MediaDecoderStateMachine::Play()
   // Once we start playing, we don't want to minimize our prerolling, as we
   // assume the user is likely to want to keep playing in future.
   mMinimizePreroll = false;
   ScheduleStateMachine();
 }
 
 void MediaDecoderStateMachine::ResetPlayback()
 {
+  AssertCurrentThreadInMonitor();
   MOZ_ASSERT(mState == DECODER_STATE_SEEKING ||
              mState == DECODER_STATE_SHUTDOWN ||
              mState == DECODER_STATE_DORMANT);
   mVideoFrameEndTime = -1;
   mAudioStartTime = -1;
   mAudioEndTime = -1;
   mAudioCompleted = false;
   AudioQueue().Reset();
@@ -2480,17 +2481,17 @@ nsresult MediaDecoderStateMachine::RunSt
   return NS_OK;
 }
 
 void
 MediaDecoderStateMachine::FlushDecoding()
 {
   NS_ASSERTION(OnStateMachineThread() || OnDecodeThread(),
                "Should be on state machine or decode thread.");
-  mDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn();
+  AssertCurrentThreadInMonitor();
 
   {
     // Put a task in the decode queue to abort any decoding operations.
     // The reader is not supposed to put any tasks to deliver samples into
     // the queue after this runs (unless we request another sample from it).
     RefPtr<nsIRunnable> task;
     task = NS_NewRunnableMethod(mReader, &MediaDecoderReader::ResetDecode);
 
--- a/content/media/MediaDecoderStateMachine.h
+++ b/content/media/MediaDecoderStateMachine.h
@@ -270,21 +270,16 @@ public:
     if (mReader) {
       return mReader->SizeOfAudioQueueInBytes();
     }
     return 0;
   }
 
   void NotifyDataArrived(const char* aBuffer, uint32_t aLength, int64_t aOffset);
 
-  int64_t GetEndMediaTime() const {
-    AssertCurrentThreadInMonitor();
-    return mEndTime;
-  }
-
   // Returns the shared state machine thread.
   nsIEventTarget* GetStateMachineThread() const;
 
   // Calls ScheduleStateMachine() after taking the decoder lock. Also
   // notifies the decoder thread in case it's waiting on the decoder lock.
   void ScheduleStateMachineWithLockAndWakeDecoder();
 
   // Schedules the shared state machine thread to run the state machine
--- a/content/media/MediaResource.cpp
+++ b/content/media/MediaResource.cpp
@@ -931,16 +931,17 @@ ChannelMediaResource::RecreateChannel()
   NS_ENSURE_TRUE(loadGroup, NS_ERROR_NULL_POINTER);
 
   nsresult rv = NS_NewChannel(getter_AddRefs(mChannel),
                               mURI,
                               nullptr,
                               loadGroup,
                               nullptr,
                               loadFlags);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   // We have cached the Content-Type, which should not change. Give a hint to
   // the channel to avoid a sniffing failure, which would be expected because we
   // are probably seeking in the middle of the bitstream, and sniffing relies
   // on the presence of a magic number at the beginning of the stream.
   NS_ASSERTION(!GetContentType().IsEmpty(),
       "When recreating a channel, we should know the Content-Type.");
   mChannel->SetContentType(GetContentType());
@@ -1029,18 +1030,17 @@ ChannelMediaResource::CacheClientSeek(in
     if (mChannel) {
       mIgnoreClose = true;
       CloseChannel();
     }
     return NS_OK;
   }
 
   nsresult rv = RecreateChannel();
-  if (NS_FAILED(rv))
-    return rv;
+  NS_ENSURE_SUCCESS(rv, rv);
 
   return OpenChannel(nullptr);
 }
 
 void
 ChannelMediaResource::FlushCache()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on main thread.");
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -40,26 +40,42 @@ namespace mozilla {
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMediaStreamGraphLog;
 #define STREAM_LOG(type, msg) PR_LOG(gMediaStreamGraphLog, type, msg)
 #else
 #define STREAM_LOG(type, msg)
 #endif
 
+// #define ENABLE_LIFECYCLE_LOG
+
+// We don't use NSPR log here because we want this interleaved with adb logcat
+// on Android/B2G
+#ifdef ENABLE_LIFECYCLE_LOG
+#  ifdef ANDROID
+#    include "android/log.h"
+#    define LIFECYCLE_LOG(...)  __android_log_print(ANDROID_LOG_INFO, "Gecko - MSG", ## __VA_ARGS__); printf(__VA_ARGS__);printf("\n");
+#  else
+#    define LIFECYCLE_LOG(...) printf(__VA_ARGS__);printf("\n");
+#  endif
+#else
+#  define LIFECYCLE_LOG(...)
+#endif
+
 /**
  * The singleton graph instance.
  */
 static MediaStreamGraphImpl* gGraph;
 
 MediaStreamGraphImpl::~MediaStreamGraphImpl()
 {
   NS_ASSERTION(IsEmpty(),
                "All streams should have been destroyed by messages from the main thread");
   STREAM_LOG(PR_LOG_DEBUG, ("MediaStreamGraph %p destroyed", this));
+  LIFECYCLE_LOG("MediaStreamGraphImpl::~MediaStreamGraphImpl\n");
 }
 
 
 StreamTime
 MediaStreamGraphImpl::GetDesiredBufferEnd(MediaStream* aStream)
 {
   StreamTime current = IterationEnd() - aStream->mBufferStartTime;
   // When waking up media decoders, we need a longer safety margin, as it can
@@ -521,18 +537,21 @@ MediaStreamGraphImpl::UpdateStreamOrder(
   if (!audioTrackPresent &&
       CurrentDriver()->AsAudioCallbackDriver()) {
     bool started;
     {
       MonitorAutoLock mon(mMonitor);
       started = CurrentDriver()->AsAudioCallbackDriver()->IsStarted();
     }
     if (started) {
-      SystemClockDriver* driver = new SystemClockDriver(this);
-      CurrentDriver()->SwitchAtNextIteration(driver);
+      MonitorAutoLock mon(mMonitor);
+      if (mLifecycleState == LIFECYCLE_RUNNING) {
+        SystemClockDriver* driver = new SystemClockDriver(this);
+        CurrentDriver()->SwitchAtNextIteration(driver);
+      }
     }
   }
 
   if (shouldAEC && !mFarendObserverRef && gFarendObserver) {
     mFarendObserverRef = gFarendObserver;
     mMixer.AddCallback(mFarendObserverRef);
   } else if (!shouldAEC && mFarendObserverRef){
     if (mMixer.FindCallback(mFarendObserverRef)) {
@@ -900,19 +919,22 @@ MediaStreamGraphImpl::CreateOrDestroyAud
           aStream->mAudioOutputStreams.AppendElement();
         audioOutputStream->mAudioPlaybackStartTime = aAudioOutputStartTime;
         audioOutputStream->mBlockedAudioTime = 0;
         audioOutputStream->mLastTickWritten = 0;
         audioOutputStream->mTrackID = tracks->GetID();
 
         if (!CurrentDriver()->AsAudioCallbackDriver() &&
             !CurrentDriver()->Switching()) {
-          AudioCallbackDriver* driver = new AudioCallbackDriver(this);
-          mMixer.AddCallback(driver);
-          CurrentDriver()->SwitchAtNextIteration(driver);
+          MonitorAutoLock mon(mMonitor);
+          if (mLifecycleState == LIFECYCLE_RUNNING) {
+            AudioCallbackDriver* driver = new AudioCallbackDriver(this);
+            mMixer.AddCallback(driver);
+            CurrentDriver()->SwitchAtNextIteration(driver);
+          }
         }
       }
     }
   }
 
   for (int32_t i = audioOutputStreamsFound.Length() - 1; i >= 0; --i) {
     if (!audioOutputStreamsFound[i]) {
       aStream->mAudioOutputStreams.RemoveElementAt(i);
@@ -1451,23 +1473,23 @@ public:
   explicit MediaStreamGraphShutDownRunnable(MediaStreamGraphImpl* aGraph)
     : mGraph(aGraph)
   {}
   NS_IMETHOD Run()
   {
     NS_ASSERTION(mGraph->mDetectedNotRunning,
                  "We should know the graph thread control loop isn't running!");
 
-    STREAM_LOG(PR_LOG_DEBUG, ("Shutting down graph %p", mGraph.get()));
+    LIFECYCLE_LOG("Shutting down graph %p", mGraph.get());
 
     if (mGraph->CurrentDriver()->AsAudioCallbackDriver()) {
       MOZ_ASSERT(!mGraph->CurrentDriver()->AsAudioCallbackDriver()->InCallback());
     }
 
-    mGraph->CurrentDriver()->Stop();
+    mGraph->CurrentDriver()->Shutdown();
 
     // mGraph's thread is not running so it's OK to do whatever here
     if (mGraph->IsEmpty()) {
       // mGraph is no longer needed, so delete it.
       mGraph->Destroy();
     } else {
       // The graph is not empty.  We must be in a forced shutdown, or a
       // non-realtime graph that has finished processing.  Some later
@@ -1554,40 +1576,59 @@ MediaStreamGraphImpl::RunInStableState(b
 
   {
     MonitorAutoLock lock(mMonitor);
     if (aSourceIsMSG) {
       MOZ_ASSERT(mPostedRunInStableStateEvent);
       mPostedRunInStableStateEvent = false;
     }
 
+#ifdef ENABLE_LIFECYCLE_LOG
+  // This should be kept in sync with the LifecycleState enum in
+  // MediaStreamGraphImpl.h
+  const char * LifecycleState_str[] = {
+    "LIFECYCLE_THREAD_NOT_STARTED",
+    "LIFECYCLE_RUNNING",
+    "LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP",
+    "LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN",
+    "LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION"
+  };
+
+  if (mLifecycleState != LIFECYCLE_RUNNING) {
+    LIFECYCLE_LOG("Running %p in stable state. Current state: %s\n",
+        this, LifecycleState_str[mLifecycleState]);
+  }
+#endif
+
     runnables.SwapElements(mUpdateRunnables);
     for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
       StreamUpdate* update = &mStreamUpdates[i];
       if (update->mStream) {
         ApplyStreamUpdate(update);
       }
     }
     mStreamUpdates.Clear();
 
     if (mCurrentTaskMessageQueue.IsEmpty()) {
       if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && IsEmpty()) {
         // Complete shutdown. First, ensure that this graph is no longer used.
         // A new graph graph will be created if one is needed.
-        STREAM_LOG(PR_LOG_DEBUG, ("Disconnecting MediaStreamGraph %p", this));
+        // Asynchronously clean up old graph. We don't want to do this
+        // synchronously because it spins the event loop waiting for threads
+        // to shut down, and we don't want to do that in a stable state handler.
+        mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
+        LIFECYCLE_LOG("Sending MediaStreamGraphShutDownRunnable %p", this);
+        nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this );
+        NS_DispatchToMainThread(event);
+
+        LIFECYCLE_LOG("Disconnecting MediaStreamGraph %p", this);
         if (this == gGraph) {
           // null out gGraph if that's the graph being shut down
           gGraph = nullptr;
         }
-        // Asynchronously clean up old graph. We don't want to do this
-        // synchronously because it spins the event loop waiting for threads
-        // to shut down, and we don't want to do that in a stable state handler.
-        mLifecycleState = LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN;
-        nsCOMPtr<nsIRunnable> event = new MediaStreamGraphShutDownRunnable(this );
-        NS_DispatchToMainThread(event);
       }
     } else {
       if (mLifecycleState <= LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
         MessageBlock* block = mBackMessageQueue.AppendElement();
         block->mMessages.SwapElements(mCurrentTaskMessageQueue);
         block->mGraphUpdateIndex = mNextGraphUpdateIndex;
         ++mNextGraphUpdateIndex;
         CurrentDriver()->EnsureNextIterationLocked();
@@ -1600,16 +1641,19 @@ MediaStreamGraphImpl::RunInStableState(b
       if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP &&
           mRealtime && !mForceShutDown) {
         mLifecycleState = LIFECYCLE_RUNNING;
         // Revive the MediaStreamGraph since we have more messages going to it.
         // Note that we need to put messages into its queue before reviving it,
         // or it might exit immediately.
         {
           MonitorAutoUnlock unlock(mMonitor);
+          LIFECYCLE_LOG("Reviving a graph (%p) ! %s\n",
+              this, CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
+                                                               "SystemDriver");
           CurrentDriver()->Revive();
         }
       }
     }
 
     // Don't start the thread for a non-realtime graph until it has been
     // explicitly started by StartNonRealtimeProcessing.
     if (mLifecycleState == LIFECYCLE_THREAD_NOT_STARTED &&
@@ -1617,17 +1661,20 @@ MediaStreamGraphImpl::RunInStableState(b
       mLifecycleState = LIFECYCLE_RUNNING;
       // Start the thread now. We couldn't start it earlier because
       // the graph might exit immediately on finding it has no streams. The
       // first message for a new graph must create a stream.
       {
         // We should exit the monitor for now, because starting a stream might
         // take locks, and we don't want to deadlock.
         MonitorAutoUnlock unlock(mMonitor);
-        STREAM_LOG(PR_LOG_DEBUG, ("Starting a graph ! %s\n", CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" : "SystemDriver"));
+        LIFECYCLE_LOG("Starting a graph (%p) ! %s\n",
+                      this,
+                      CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
+                                                                 "SystemDriver");
         CurrentDriver()->Start();
       }
     }
 
     if ((mForceShutDown || !mRealtime) &&
         mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
       // Defer calls to RunDuringShutdown() to happen while mMonitor is not held.
       for (uint32_t i = 0; i < mBackMessageQueue.Length(); ++i) {
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -683,17 +683,18 @@ protected:
 class SourceMediaStream : public MediaStream {
 public:
   explicit SourceMediaStream(DOMMediaStream* aWrapper) :
     MediaStream(aWrapper),
     mLastConsumptionState(MediaStreamListener::NOT_CONSUMED),
     mMutex("mozilla::media::SourceMediaStream"),
     mUpdateKnownTracksTime(0),
     mPullEnabled(false),
-    mUpdateFinished(false)
+    mUpdateFinished(false),
+    mNeedsMixing(false)
   {}
 
   virtual SourceMediaStream* AsSourceStream() { return this; }
 
   // Media graph thread only
   virtual void DestroyImpl();
 
   // Call these on any thread.
--- a/content/media/MediaStreamGraphImpl.h
+++ b/content/media/MediaStreamGraphImpl.h
@@ -515,16 +515,19 @@ public:
    * object.
    * 2) Forced shutdown at application shutdown, or completion of a
    * non-realtime graph. A flag is set, RunThread() detects the flag and
    * exits, the next RunInStableState() detects the flag, and dispatches the
    * async event to Shutdown() the graph's threads. However the graph object
    * is not deleted. New messages for the graph are processed synchronously on
    * the main thread if necessary. When the last stream is destroyed, the
    * graph object is deleted.
+   *
+   * This should be kept in sync with the LifecycleState_str array in
+   * MediaStreamGraph.cpp
    */
   enum LifecycleState {
     // The graph thread hasn't started yet.
     LIFECYCLE_THREAD_NOT_STARTED,
     // RunThread() is running normally.
     LIFECYCLE_RUNNING,
     // In the following states, the graph thread is not running so
     // all "graph thread only" state in this class can be used safely
--- a/content/media/fmp4/apple/AppleVTDecoder.cpp
+++ b/content/media/fmp4/apple/AppleVTDecoder.cpp
@@ -444,25 +444,29 @@ AppleVTDecoder::InitializeSession()
     return NS_ERROR_FAILURE;
   }
 
   // Contruct video decoder selection spec.
   AutoCFRelease<CFMutableDictionaryRef> spec =
     CFDictionaryCreateMutable(NULL, 0,
                               &kCFTypeDictionaryKeyCallBacks,
                               &kCFTypeDictionaryValueCallBacks);
+// FIXME: Enabling hardware acceleration causes crashes in
+// VTDecompressionSessionCreate() with multiple videos. Bug 1055694
+#if 0
   // This key is supported (or ignored) but not declared prior to OSX 10.9.
   AutoCFRelease<CFStringRef>
         kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder =
         CFStringCreateWithCString(NULL, "EnableHardwareAcceleratedVideoDecoder",
             kCFStringEncodingUTF8);
 
   CFDictionarySetValue(spec,
       kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder,
       kCFBooleanTrue);
+#endif
 
   VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this };
   rv = VTDecompressionSessionCreate(NULL, // Allocator.
                                     mFormat,
                                     spec, // Video decoder selection.
                                     NULL, // Output video format.
                                     &cb,
                                     &mSession);
--- a/content/media/mediasource/MediaSourceReader.cpp
+++ b/content/media/mediasource/MediaSourceReader.cpp
@@ -36,16 +36,18 @@ extern PRLogModuleInfo* GetMediaSourceAP
 namespace mozilla {
 
 MediaSourceReader::MediaSourceReader(MediaSourceDecoder* aDecoder)
   : MediaDecoderReader(aDecoder)
   , mTimeThreshold(-1)
   , mDropAudioBeforeThreshold(false)
   , mDropVideoBeforeThreshold(false)
   , mEnded(false)
+  , mAudioIsSeeking(false)
+  , mVideoIsSeeking(false)
 {
 }
 
 bool
 MediaSourceReader::IsWaitingMediaResources()
 {
   return mDecoders.IsEmpty() && mPendingDecoders.IsEmpty();
 }
@@ -71,28 +73,36 @@ MediaSourceReader::OnAudioDecoded(AudioD
       MSE_DEBUG("MediaSourceReader(%p)::OnAudioDecoded mTime=%lld < mTimeThreshold=%lld",
                 this, aSample->mTime, mTimeThreshold);
       delete aSample;
       mAudioReader->RequestAudioData();
       return;
     }
     mDropAudioBeforeThreshold = false;
   }
+
+  // If we are seeking we need to make sure the first sample decoded after
+  // that seek has the mDiscontinuity field set to ensure the media decoder
+  // state machine picks up that the seek is complete.
+  if (mAudioIsSeeking) {
+    mAudioIsSeeking = false;
+    aSample->mDiscontinuity = true;
+  }
   GetCallback()->OnAudioDecoded(aSample);
 }
 
 void
 MediaSourceReader::OnAudioEOS()
 {
   MSE_DEBUG("MediaSourceReader(%p)::OnAudioEOS reader=%p (readers=%u)",
             this, mAudioReader.get(), mDecoders.Length());
   if (SwitchReaders(SWITCH_FORCED)) {
     // Success! Resume decoding with next audio decoder.
     RequestAudioData();
-  } else {
+  } else if (IsEnded()) {
     // End of stream.
     MSE_DEBUG("MediaSourceReader(%p)::OnAudioEOS reader=%p EOS (readers=%u)",
               this, mAudioReader.get(), mDecoders.Length());
     GetCallback()->OnAudioEOS();
   }
 }
 
 void
@@ -117,16 +127,25 @@ MediaSourceReader::OnVideoDecoded(VideoD
       MSE_DEBUG("MediaSourceReader(%p)::OnVideoDecoded mTime=%lld < mTimeThreshold=%lld",
                 this, aSample->mTime, mTimeThreshold);
       delete aSample;
       mVideoReader->RequestVideoData(false, mTimeThreshold);
       return;
     }
     mDropVideoBeforeThreshold = false;
   }
+
+  // If we are seeking we need to make sure the first sample decoded after
+  // that seek has the mDiscontinuity field set to ensure the media decoder
+  // state machine picks up that the seek is complete.
+  if (mVideoIsSeeking) {
+    mVideoIsSeeking = false;
+    aSample->mDiscontinuity = true;
+  }
+
   GetCallback()->OnVideoDecoded(aSample);
 }
 
 void
 MediaSourceReader::OnVideoEOS()
 {
   // End of stream. See if we can switch to another video decoder.
   MSE_DEBUG("MediaSourceReader(%p)::OnVideoEOS reader=%p (readers=%u)",
@@ -433,23 +452,25 @@ MediaSourceReader::Seek(int64_t aTime, i
   }
 
   if (IsShutdown()) {
     return NS_ERROR_FAILURE;
   }
 
   ResetDecode();
   if (mAudioReader) {
+    mAudioIsSeeking = true;
     nsresult rv = mAudioReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
     MSE_DEBUG("MediaSourceReader(%p)::Seek audio reader=%p rv=%x", this, mAudioReader.get(), rv);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
   if (mVideoReader) {
+    mVideoIsSeeking = true;
     nsresult rv = mVideoReader->Seek(aTime, aStartTime, aEndTime, aCurrentTime);
     MSE_DEBUG("MediaSourceReader(%p)::Seek video reader=%p rv=%x", this, mVideoReader.get(), rv);
     if (NS_FAILED(rv)) {
       return rv;
     }
   }
   return NS_OK;
 }
--- a/content/media/mediasource/MediaSourceReader.h
+++ b/content/media/mediasource/MediaSourceReader.h
@@ -111,13 +111,21 @@ private:
 
   nsTArray<nsRefPtr<SourceBufferDecoder>> mPendingDecoders;
   nsTArray<nsRefPtr<SourceBufferDecoder>> mDecoders;
 
   nsRefPtr<MediaDecoderReader> mAudioReader;
   nsRefPtr<MediaDecoderReader> mVideoReader;
 
   bool mEnded;
+
+  // For a seek to complete we need to send a sample with
+  // the mDiscontinuity field set to true once we have the
+  // first decoded sample. These flags are set during seeking
+  // so we can detect when we have the first decoded sample
+  // after a seek.
+  bool mAudioIsSeeking;
+  bool mVideoIsSeeking;
 };
 
 } // namespace mozilla
 
 #endif /* MOZILLA_MEDIASOURCEREADER_H_ */
--- a/content/media/mediasource/SourceBuffer.cpp
+++ b/content/media/mediasource/SourceBuffer.cpp
@@ -56,16 +56,27 @@ public:
               this, aLength,
               aLength > 0 ? aData[0] : 0,
               aLength > 1 ? aData[1] : 0,
               aLength > 2 ? aData[2] : 0,
               aLength > 3 ? aData[3] : 0);
     return false;
   }
 
+  virtual bool IsMediaSegmentPresent(const uint8_t* aData, uint32_t aLength)
+  {
+    MSE_DEBUG("ContainerParser(%p)::IsMediaSegmentPresent aLength=%u [%x%x%x%x]",
+              this, aLength,
+              aLength > 0 ? aData[0] : 0,
+              aLength > 1 ? aData[1] : 0,
+              aLength > 2 ? aData[2] : 0,
+              aLength > 3 ? aData[3] : 0);
+    return false;
+  }
+
   virtual bool ParseStartAndEndTimestamps(const uint8_t* aData, uint32_t aLength,
                                           double& aStart, double& aEnd)
   {
     return false;
   }
 
   virtual const nsTArray<uint8_t>& InitData()
   {
@@ -77,17 +88,17 @@ public:
 
 protected:
   nsTArray<uint8_t> mInitData;
 };
 
 class WebMContainerParser : public ContainerParser {
 public:
   WebMContainerParser()
-    : mTimecodeScale(0)
+    : mParser(0), mOffset(0)
   {}
 
   bool IsInitSegmentPresent(const uint8_t* aData, uint32_t aLength)
   {
     ContainerParser::IsInitSegmentPresent(aData, aLength);
     // XXX: This is overly primitive, needs to collect data as it's appended
     // to the SB and handle, rather than assuming everything is present in a
     // single aData segment.
@@ -100,65 +111,102 @@ public:
     // 0x1654ae6b // -> One or more Tracks
     if (aLength >= 4 &&
         aData[0] == 0x1a && aData[1] == 0x45 && aData[2] == 0xdf && aData[3] == 0xa3) {
       return true;
     }
     return false;
   }
 
-  virtual bool ParseStartAndEndTimestamps(const uint8_t* aData, uint32_t aLength,
-                                          double& aStart, double& aEnd)
+  bool IsMediaSegmentPresent(const uint8_t* aData, uint32_t aLength)
   {
+    ContainerParser::IsMediaSegmentPresent(aData, aLength);
     // XXX: This is overly primitive, needs to collect data as it's appended
     // to the SB and handle, rather than assuming everything is present in a
     // single aData segment.
+    // 0x1a45dfa3 // EBML
+    // ...
+    // DocType == "webm"
+    // ...
+    // 0x18538067 // Segment (must be "unknown" size)
+    // 0x1549a966 // -> Segment Info
+    // 0x1654ae6b // -> One or more Tracks
+    if (aLength >= 4 &&
+        aData[0] == 0x1f && aData[1] == 0x43 && aData[2] == 0xb6 && aData[3] == 0x75) {
+      return true;
+    }
+    return false;
+  }
 
-    WebMBufferedParser parser(0);
-    if (mTimecodeScale != 0) {
-      parser.SetTimecodeScale(mTimecodeScale);
+  virtual bool ParseStartAndEndTimestamps(const uint8_t* aData, uint32_t aLength,
+                                          double& aStart, double& aEnd)
+  {
+    bool initSegment = IsInitSegmentPresent(aData, aLength);
+    if (initSegment) {
+      mOffset = 0;
+      mParser = WebMBufferedParser(0);
+      mOverlappedMapping.Clear();
     }
 
+    // XXX if it only adds new mappings, overlapped but not available
+    // (e.g. overlap < 0) frames are "lost" from the reported mappings here.
     nsTArray<WebMTimeDataOffset> mapping;
+    mapping.AppendElements(mOverlappedMapping);
+    mOverlappedMapping.Clear();
     ReentrantMonitor dummy("dummy");
-    parser.Append(aData, aLength, mapping, dummy);
-
-    mTimecodeScale = parser.GetTimecodeScale();
+    mParser.Append(aData, aLength, mapping, dummy);
 
     // XXX This is a bit of a hack.  Assume if there are no timecodes
     // present and it's an init segment that it's _just_ an init segment.
     // We should be more precise.
-    if (IsInitSegmentPresent(aData, aLength)) {
+    if (initSegment) {
       uint32_t length = aLength;
       if (!mapping.IsEmpty()) {
         length = mapping[0].mSyncOffset;
         MOZ_ASSERT(length <= aLength);
       }
       MSE_DEBUG("WebMContainerParser(%p)::ParseStartAndEndTimestamps: Stashed init of %u bytes.",
                 this, length);
 
       mInitData.ReplaceElementsAt(0, mInitData.Length(), aData, length);
     }
+    mOffset += aLength;
 
     if (mapping.IsEmpty()) {
       return false;
     }
 
+    // Exclude frames that we don't enough data to cover the end of.
+    uint32_t endIdx = mapping.Length() - 1;
+    while (mOffset < mapping[endIdx].mEndOffset && endIdx > 0) {
+      endIdx -= 1;
+    }
+
+    if (endIdx == 0) {
+      return false;
+    }
+
     static const double NS_PER_S = 1e9;
     aStart = mapping[0].mTimecode / NS_PER_S;
-    aEnd = mapping.LastElement().mTimecode / NS_PER_S;
+    aEnd = mapping[endIdx].mTimecode / NS_PER_S;
+    aEnd += (mapping[endIdx].mTimecode - mapping[endIdx - 1].mTimecode) / NS_PER_S;
 
-    MSE_DEBUG("WebMContainerParser(%p)::ParseStartAndEndTimestamps: [%f, %f] [fso=%lld, leo=%lld]",
-              this, aStart, aEnd, mapping[0].mSyncOffset, mapping.LastElement().mEndOffset);
+    MSE_DEBUG("WebMContainerParser(%p)::ParseStartAndEndTimestamps: [%f, %f] [fso=%lld, leo=%lld, l=%u endIdx=%u]",
+              this, aStart, aEnd, mapping[0].mSyncOffset, mapping[endIdx].mEndOffset, mapping.Length(), endIdx);
+
+    mapping.RemoveElementsAt(0, endIdx + 1);
+    mOverlappedMapping.AppendElements(mapping);
 
     return true;
   }
 
 private:
-  uint32_t mTimecodeScale;
+  WebMBufferedParser mParser;
+  nsTArray<WebMTimeDataOffset> mOverlappedMapping;
+  int64_t mOffset;
 };
 
 class MP4ContainerParser : public ContainerParser {
 public:
   MP4ContainerParser() : mTimescale(0) {}
 
   bool IsInitSegmentPresent(const uint8_t* aData, uint32_t aLength)
   {
@@ -580,17 +628,18 @@ SourceBuffer::AppendData(const uint8_t* 
     Optional<MediaSourceEndOfStreamError> decodeError(MediaSourceEndOfStreamError::Decode);
     ErrorResult dummy;
     mMediaSource->EndOfStream(decodeError, dummy);
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
   double start, end;
   if (mParser->ParseStartAndEndTimestamps(aData, aLength, start, end)) {
-    if (start <= mLastParsedTimestamp || mLastParsedTimestamp - start > 0.1) {
+    if (mParser->IsMediaSegmentPresent(aData, aLength) &&
+        (start < mLastParsedTimestamp || start - mLastParsedTimestamp > 0.1)) {
       MSE_DEBUG("SourceBuffer(%p)::AppendData: Data (%f, %f) overlaps %f.",
                 this, start, end, mLastParsedTimestamp);
 
       // This data is earlier in the timeline than data we have already
       // processed, so we must create a new decoder to handle the decoding.
       DiscardDecoder();
 
       // If we've got a decoder here, it's not initialized, so we can use it
--- a/content/media/mediasource/SourceBufferDecoder.cpp
+++ b/content/media/mediasource/SourceBufferDecoder.cpp
@@ -59,22 +59,16 @@ SourceBufferDecoder::IsShutdown() const
 
 void
 SourceBufferDecoder::NotifyBytesConsumed(int64_t aBytes, int64_t aOffset)
 {
   MSE_DEBUG("SourceBufferDecoder(%p)::NotifyBytesConsumed UNIMPLEMENTED", this);
 }
 
 int64_t
-SourceBufferDecoder::GetEndMediaTime() const
-{
-  return mMediaDuration;
-}
-
-int64_t
 SourceBufferDecoder::GetMediaDuration()
 {
   return mMediaDuration;
 }
 
 VideoFrameContainer*
 SourceBufferDecoder::GetVideoFrameContainer()
 {
--- a/content/media/mediasource/SourceBufferDecoder.h
+++ b/content/media/mediasource/SourceBufferDecoder.h
@@ -32,17 +32,16 @@ public:
 
   NS_DECL_THREADSAFE_ISUPPORTS
 
   virtual bool IsMediaSeekable() MOZ_FINAL MOZ_OVERRIDE;
   virtual bool IsShutdown() const MOZ_FINAL MOZ_OVERRIDE;
   virtual bool IsTransportSeekable() MOZ_FINAL MOZ_OVERRIDE;
   virtual bool OnDecodeThread() const MOZ_FINAL MOZ_OVERRIDE;
   virtual bool OnStateMachineThread() const MOZ_FINAL MOZ_OVERRIDE;
-  virtual int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;
   virtual int64_t GetMediaDuration() MOZ_FINAL MOZ_OVERRIDE;
   virtual layers::ImageContainer* GetImageContainer() MOZ_FINAL MOZ_OVERRIDE;
   virtual MediaDecoderOwner* GetOwner() MOZ_FINAL MOZ_OVERRIDE;
   virtual SourceBufferResource* GetResource() const MOZ_FINAL MOZ_OVERRIDE;
   virtual ReentrantMonitor& GetReentrantMonitor() MOZ_FINAL MOZ_OVERRIDE;
   virtual VideoFrameContainer* GetVideoFrameContainer() MOZ_FINAL MOZ_OVERRIDE;
   virtual void MetadataLoaded(MediaInfo* aInfo, MetadataTags* aTags) MOZ_FINAL MOZ_OVERRIDE;
   virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
--- a/content/media/webaudio/BufferDecoder.cpp
+++ b/content/media/webaudio/BufferDecoder.cpp
@@ -84,23 +84,16 @@ BufferDecoder::NotifyBytesConsumed(int64
 
 void
 BufferDecoder::NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded)
 {
   // ignore
 }
 
 int64_t
-BufferDecoder::GetEndMediaTime() const
-{
-  // unknown
-  return -1;
-}
-
-int64_t
 BufferDecoder::GetMediaDuration()
 {
   // unknown
   return -1;
 }
 
 void
 BufferDecoder::SetMediaDuration(int64_t aDuration)
--- a/content/media/webaudio/BufferDecoder.h
+++ b/content/media/webaudio/BufferDecoder.h
@@ -38,18 +38,16 @@ public:
   virtual bool OnDecodeThread() const MOZ_FINAL MOZ_OVERRIDE;
 
   virtual MediaResource* GetResource() const MOZ_FINAL MOZ_OVERRIDE;
 
   virtual void NotifyBytesConsumed(int64_t aBytes, int64_t aOffset) MOZ_FINAL MOZ_OVERRIDE;
 
   virtual void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) MOZ_FINAL MOZ_OVERRIDE;
 
-  virtual int64_t GetEndMediaTime() const MOZ_FINAL MOZ_OVERRIDE;
-
   virtual int64_t GetMediaDuration() MOZ_FINAL MOZ_OVERRIDE;
 
   virtual void SetMediaDuration(int64_t aDuration) MOZ_FINAL MOZ_OVERRIDE;
 
   virtual void UpdateEstimatedMediaDuration(int64_t aDuration) MOZ_FINAL MOZ_OVERRIDE;
 
   virtual void SetMediaSeekable(bool aMediaSeekable) MOZ_FINAL MOZ_OVERRIDE;
 
--- a/content/media/webaudio/test/browser.ini
+++ b/content/media/webaudio/test/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
+skip-if = e10s
 support-files =
   browser_mozAudioChannel.html
   browser_mozAudioChannel_muted.html
 
 [browser_mozAudioChannel.js]
 [browser_mozAudioChannel_muted.js]
--- a/content/media/webm/WebMReader.cpp
+++ b/content/media/webm/WebMReader.cpp
@@ -152,16 +152,17 @@ WebMReader::WebMReader(AbstractMediaDeco
   mOpusDecoder(nullptr),
   mSkip(0),
   mSeekPreroll(0),
 #endif
   mVideoTrack(0),
   mAudioTrack(0),
   mAudioStartUsec(-1),
   mAudioFrames(0),
+  mLastVideoFrameTime(0),
   mAudioCodec(-1),
   mVideoCodec(-1),
   mHasVideo(false),
   mHasAudio(false)
 {
   MOZ_COUNT_CTOR(WebMReader);
 #ifdef PR_LOGGING
   if (!gNesteggLog) {
@@ -859,36 +860,33 @@ bool WebMReader::DecodeVideoFrame(bool &
     return false;
   }
 
   uint64_t tstamp = 0;
   r = nestegg_packet_tstamp(packet, &tstamp);
   if (r == -1) {
     return false;
   }
+  mLastVideoFrameTime = tstamp;
 
   // The end time of this frame is the start time of the next frame.  Fetch
   // the timestamp of the next packet for this track.  If we've reached the
   // end of the resource, use the file's duration as the end time of this
   // video frame.
   uint64_t next_tstamp = 0;
   nsAutoRef<NesteggPacketHolder> next_holder(NextPacket(VIDEO));
   if (next_holder) {
     r = nestegg_packet_tstamp(next_holder->mPacket, &next_tstamp);
     if (r == -1) {
       return false;
     }
     PushVideoPacket(next_holder.disown());
   } else {
-    ReentrantMonitorAutoEnter decoderMon(mDecoder->GetReentrantMonitor());
-    int64_t endTime = mDecoder->GetEndMediaTime();
-    if (endTime == -1) {
-      return false;
-    }
-    next_tstamp = endTime * NS_PER_USEC;
+    next_tstamp = tstamp;
+    next_tstamp += tstamp - mLastVideoFrameTime;
   }
 
   int64_t tstamp_usecs = tstamp / NS_PER_USEC;
   for (uint32_t i = 0; i < count; ++i) {
     unsigned char* data;
     size_t length;
     r = nestegg_packet_data(packet, i, &data, &length);
     if (r == -1) {
--- a/content/media/webm/WebMReader.h
+++ b/content/media/webm/WebMReader.h
@@ -219,16 +219,20 @@ private:
   int64_t mAudioStartUsec;
 
   // Number of audio frames we've decoded since decoding began at mAudioStartMs.
   uint64_t mAudioFrames;
 
   // Number of microseconds that must be discarded from the start of the Stream.
   uint64_t mCodecDelay;
 
+  // Calculate the frame duration from the last decodeable frame using the
+  // previous frame's timestamp.  In NS.
+  uint64_t mLastVideoFrameTime;
+
   // Parser state and computed offset-time mappings.  Shared by multiple
   // readers when decoder has been cloned.  Main thread only.
   nsRefPtr<WebMBufferedState> mBufferedState;
 
   // Size of the frame initially present in the stream. The picture region
   // is defined as a ratio relative to this.
   nsIntSize mInitialFrame;
 
--- a/content/media/webspeech/synth/nsSynthVoiceRegistry.h
+++ b/content/media/webspeech/synth/nsSynthVoiceRegistry.h
@@ -18,17 +18,17 @@ namespace mozilla {
 namespace dom {
 
 class RemoteVoice;
 class SpeechSynthesisUtterance;
 class SpeechSynthesisChild;
 class nsSpeechTask;
 class VoiceData;
 
-class nsSynthVoiceRegistry : public nsISynthVoiceRegistry
+class nsSynthVoiceRegistry MOZ_FINAL : public nsISynthVoiceRegistry
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISYNTHVOICEREGISTRY
 
   nsSynthVoiceRegistry();
 
   already_AddRefed<nsSpeechTask> SpeakUtterance(SpeechSynthesisUtterance& aUtterance,
--- a/content/svg/content/src/SVGForeignObjectElement.cpp
+++ b/content/svg/content/src/SVGForeignObjectElement.cpp
@@ -70,32 +70,29 @@ SVGForeignObjectElement::Height()
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 /* virtual */ gfxMatrix
 SVGForeignObjectElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                                                   TransformTypes aWhich) const
 {
-  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
-                    "Skipping eUserSpaceToParent transforms makes no sense");
-
   // 'transform' attribute:
   gfxMatrix fromUserSpace =
     SVGGraphicsElement::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
   // our 'x' and 'y' attributes:
   float x, y;
   const_cast<SVGForeignObjectElement*>(this)->
     GetAnimatedLengthValues(&x, &y, nullptr);
   gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
   if (aWhich == eChildToUserSpace) {
-    return toUserSpace;
+    return toUserSpace * aMatrix;
   }
   NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
   return toUserSpace * fromUserSpace;
 }
 
 /* virtual */ bool
 SVGForeignObjectElement::HasValidDimensions() const
 {
--- a/content/svg/content/src/SVGIFrameElement.cpp
+++ b/content/svg/content/src/SVGIFrameElement.cpp
@@ -59,19 +59,16 @@ SVGIFrameElement::~SVGIFrameElement()
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 /* virtual */ gfxMatrix
 SVGIFrameElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                                            TransformTypes aWhich) const
 {
-  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
-                    "Skipping eUserSpaceToParent transforms makes no sense");
-
   // 'transform' attribute:
   gfxMatrix fromUserSpace =
     SVGGraphicsElement::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
   // our 'x' and 'y' attributes:
   float x, y;
--- a/content/svg/content/src/SVGSVGElement.cpp
+++ b/content/svg/content/src/SVGSVGElement.cpp
@@ -951,35 +951,32 @@ SVGSVGElement::GetLength(uint8_t aCtxTyp
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 /* virtual */ gfxMatrix
 SVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                                         TransformTypes aWhich) const
 {
-  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
-                    "Skipping eUserSpaceToParent transforms makes no sense");
-
   // 'transform' attribute:
   gfxMatrix fromUserSpace =
     SVGSVGElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
 
   if (IsInner()) {
     float x, y;
     const_cast<SVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
     if (aWhich == eAllTransforms) {
       // the common case
       return ThebesMatrix(GetViewBoxTransform()) * gfxMatrix().Translate(gfxPoint(x, y)) * fromUserSpace;
     }
     NS_ABORT_IF_FALSE(aWhich == eChildToUserSpace, "Unknown TransformTypes");
-    return ThebesMatrix(GetViewBoxTransform()) * gfxMatrix().Translate(gfxPoint(x, y));
+    return ThebesMatrix(GetViewBoxTransform()) * gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
   }
 
   if (IsRoot()) {
     gfxMatrix zoomPanTM;
     zoomPanTM.Translate(gfxPoint(mCurrentTranslate.GetX(), mCurrentTranslate.GetY()));
     zoomPanTM.Scale(mCurrentScale, mCurrentScale);
     return ThebesMatrix(GetViewBoxTransform()) * zoomPanTM * fromUserSpace;
   }
--- a/content/svg/content/src/SVGTransformableElement.cpp
+++ b/content/svg/content/src/SVGTransformableElement.cpp
@@ -88,19 +88,16 @@ SVGTransformableElement::IsEventAttribut
 
 //----------------------------------------------------------------------
 // nsSVGElement overrides
 
 gfxMatrix
 SVGTransformableElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                                                   TransformTypes aWhich) const
 {
-  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
-                    "Skipping eUserSpaceToParent transforms makes no sense");
-
   gfxMatrix result(aMatrix);
 
   if (aWhich == eChildToUserSpace) {
     // We don't have anything to prepend.
     // eChildToUserSpace is not the common case, which is why we return
     // 'result' to benefit from NRVO rather than returning aMatrix before
     // creating 'result'.
     return result;
--- a/content/svg/content/src/SVGUseElement.cpp
+++ b/content/svg/content/src/SVGUseElement.cpp
@@ -420,31 +420,28 @@ SVGUseElement::UnlinkSource()
 
 //----------------------------------------------------------------------
 // nsSVGElement methods
 
 /* virtual */ gfxMatrix
 SVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
                                         TransformTypes aWhich) const
 {
-  NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
-                    "Skipping eUserSpaceToParent transforms makes no sense");
-
   // 'transform' attribute:
   gfxMatrix fromUserSpace =
     SVGUseElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
   if (aWhich == eUserSpaceToParent) {
     return fromUserSpace;
   }
   // our 'x' and 'y' attributes:
   float x, y;
   const_cast<SVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nullptr);
   gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
   if (aWhich == eChildToUserSpace) {
-    return toUserSpace;
+    return toUserSpace * aMatrix;
   }
   NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
   return toUserSpace * fromUserSpace;
 }
 
 /* virtual */ bool
 SVGUseElement::HasValidDimensions() const
 {
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -87,11 +87,13 @@ skip-if = e10s # Bug ?????? - test touch
 skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
 [browser_bug92473.js]
 skip-if = e10s # Bug ?????? - BrowserSetForcedCharacterSet() in browser.js references docShell
 [browser_bug941562.js]
 skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
 [browser_uriFixupIntegration.js]
 skip-if = e10s
 [browser_loadDisallowInherit.js]
+skip-if = e10s
 [browser_loadURI.js]
 skip-if = e10s # Bug ?????? - event handler checks event.target is the content document and test e10s-utils doesn't do that.
 [browser_search_notification.js]
+skip-if = e10s
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -114,33 +114,53 @@ struct nsDelayedBlurOrFocusEvent
      mTarget(aOther.mTarget) { }
 
   uint32_t mType;
   nsCOMPtr<nsIPresShell> mPresShell;
   nsCOMPtr<nsIDocument> mDocument;
   nsCOMPtr<EventTarget> mTarget;
 };
 
+inline void ImplCycleCollectionUnlink(nsDelayedBlurOrFocusEvent& aField)
+{
+  aField.mPresShell = nullptr;
+  aField.mDocument = nullptr;
+  aField.mTarget = nullptr;
+}
+
+inline void
+ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
+                            nsDelayedBlurOrFocusEvent& aField,
+                            const char* aName,
+                            uint32_t aFlags = 0)
+{
+  CycleCollectionNoteChild(aCallback, aField.mPresShell.get(), aName, aFlags);
+  CycleCollectionNoteChild(aCallback, aField.mDocument.get(), aName, aFlags);
+  CycleCollectionNoteChild(aCallback, aField.mTarget.get(), aName, aFlags);
+}
+
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsFocusManager)
   NS_INTERFACE_MAP_ENTRY(nsIFocusManager)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFocusManager)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFocusManager)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFocusManager)
 
 NS_IMPL_CYCLE_COLLECTION(nsFocusManager,
                          mActiveWindow,
                          mFocusedWindow,
                          mFocusedContent,
                          mFirstBlurEvent,
                          mFirstFocusEvent,
-                         mWindowBeingLowered)
+                         mWindowBeingLowered,
+                         mDelayedBlurFocusEvents,
+                         mMouseButtonEventHandlingDocument)
 
 nsFocusManager* nsFocusManager::sInstance = nullptr;
 bool nsFocusManager::sMouseFocusesFormControl = false;
 bool nsFocusManager::sTestMode = false;
 
 static const char* kObservedPrefs[] = {
   "accessibility.browsewithcaret",
   "accessibility.tabfocus_applies_to_xul",
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1391,115 +1391,16 @@ static const JSFunctionSpec TraceMallocF
     JS_FS("TraceMallocCloseLogFD",      TraceMallocCloseLogFD,      1, 0),
     JS_FS("TraceMallocLogTimestamp",    TraceMallocLogTimestamp,    1, 0),
     JS_FS("TraceMallocDumpAllocations", TraceMallocDumpAllocations, 1, 0),
     JS_FS_END
 };
 
 #endif /* NS_TRACE_MALLOC */
 
-#ifdef MOZ_DMD
-
-#include <errno.h>
-
-namespace mozilla {
-namespace dmd {
-
-// See https://wiki.mozilla.org/Performance/MemShrink/DMD for instructions on
-// how to use DMD.
-
-static FILE *
-OpenDMDOutputFile(JSContext *cx, JS::CallArgs &args)
-{
-  JSString *str = JS::ToString(cx, args.get(0));
-  if (!str)
-    return nullptr;
-  JSAutoByteString pathname(cx, str);
-  if (!pathname)
-    return nullptr;
-
-  FILE* fp = fopen(pathname.ptr(), "w");
-  if (!fp) {
-    JS_ReportError(cx, "DMD can't open %s: %s",
-                   pathname.ptr(), strerror(errno));
-    return nullptr;
-  }
-  return fp;
-}
-
-static bool
-AnalyzeReports(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-  if (!dmd::IsRunning()) {
-    JS_ReportError(cx, "DMD is not running");
-    return false;
-  }
-
-  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-  FILE *fp = OpenDMDOutputFile(cx, args);
-  if (!fp) {
-    return false;
-  }
-
-  dmd::ClearReports();
-  dmd::RunReportersForThisProcess();
-  dmd::Writer writer(FpWrite, fp);
-  dmd::AnalyzeReports(writer);
-
-  fclose(fp);
-
-  args.rval().setUndefined();
-  return true;
-}
-
-// This will be removed eventually.
-static bool
-ReportAndDump(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-  JS_ReportWarning(cx, "DMDReportAndDump() is deprecated; "
-                   "please use DMDAnalyzeReports() instead");
-
-  return AnalyzeReports(cx, argc, vp);
-}
-
-static bool
-AnalyzeHeap(JSContext *cx, unsigned argc, JS::Value *vp)
-{
-  if (!dmd::IsRunning()) {
-    JS_ReportError(cx, "DMD is not running");
-    return false;
-  }
-
-  JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-  FILE *fp = OpenDMDOutputFile(cx, args);
-  if (!fp) {
-    return false;
-  }
-
-  dmd::Writer writer(FpWrite, fp);
-  dmd::AnalyzeHeap(writer);
-
-  fclose(fp);
-
-  args.rval().setUndefined();
-  return true;
-}
-
-} // namespace dmd
-} // namespace mozilla
-
-static const JSFunctionSpec DMDFunctions[] = {
-    JS_FS("DMDReportAndDump",  dmd::ReportAndDump,  1, 0),
-    JS_FS("DMDAnalyzeReports", dmd::AnalyzeReports, 1, 0),
-    JS_FS("DMDAnalyzeHeap",    dmd::AnalyzeHeap,    1, 0),
-    JS_FS_END
-};
-
-#endif  // defined(MOZ_DMD)
-
 #ifdef MOZ_JPROF
 
 #include <signal.h>
 
 inline bool
 IsJProfAction(struct sigaction *action)
 {
     return (action->sa_sigaction &&
@@ -1613,23 +1514,16 @@ nsJSContext::InitClasses(JS::Handle<JSOb
 
 #ifdef NS_TRACE_MALLOC
   if (nsContentUtils::IsCallerChrome()) {
     // Attempt to initialize TraceMalloc functions
     ::JS_DefineFunctions(cx, aGlobalObj, TraceMallocFunctions);
   }
 #endif
 
-#ifdef MOZ_DMD
-  if (nsContentUtils::IsCallerChrome()) {
-    // Attempt to initialize DMD functions
-    ::JS_DefineFunctions(cx, aGlobalObj, DMDFunctions);
-  }
-#endif
-
 #ifdef MOZ_JPROF
   // Attempt to initialize JProf functions
   ::JS_DefineFunctions(cx, aGlobalObj, JProfFunctions);
 #endif
 
   return NS_OK;
 }
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1247,17 +1247,17 @@ XrayResolveProperty(JSContext* cx, JS::H
   return true;
 }
 
 static bool
 ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle<JSObject*> wrapper,
                               JS::Handle<JSObject*> obj,
                               size_t protoAndIfaceCacheIndex, unsigned attrs,
                               JS::MutableHandle<JSPropertyDescriptor> desc,
-                              bool cacheOnHolder)
+                              bool& cacheOnHolder)
 {
   JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
   {
     JSAutoCompartment ac(cx, global);
     ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
     JSObject* protoOrIface =
       protoAndIfaceCache.EntrySlotIfExists(protoAndIfaceCacheIndex);
     if (!protoOrIface) {
--- a/dom/bluetooth/BluetoothRilListener.cpp
+++ b/dom/bluetooth/BluetoothRilListener.cpp
@@ -108,22 +108,22 @@ MobileConnectionListener::NotifyUssdRece
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyDataError(const nsAString & message)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MobileConnectionListener::NotifyCFStateChange(bool success,
-                                              uint16_t action,
-                                              uint16_t reason,
-                                              const nsAString& number,
-                                              uint16_t timeSeconds,
-                                              uint16_t serviceClass)
+MobileConnectionListener::NotifyCFStateChanged(bool success,
+                                               uint16_t action,
+                                               uint16_t reason,
+                                               const nsAString& number,
+                                               uint16_t timeSeconds,
+                                               uint16_t serviceClass)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active,
                                                        uint32_t timeoutMs)
 {
@@ -149,28 +149,46 @@ MobileConnectionListener::NotifyRadioSta
 }
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyClirModeChanged(uint32_t aMode)
 {
   return NS_OK;
 }
 
+NS_IMETHODIMP
+MobileConnectionListener::NotifyLastKnownNetworkChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyLastKnownHomeNetworkChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyNetworkSelectionModeChanged()
+{
+  return NS_OK;
+}
+
 bool
 MobileConnectionListener::Listen(bool aStart)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> provider =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
+  nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(service, false);
 
   nsresult rv;
   if (aStart) {
-    rv = provider->RegisterMobileConnectionMsg(mClientId, this);
+    rv = service->RegisterListener(mClientId, this);
   } else {
-    rv = provider->UnregisterMobileConnectionMsg(mClientId, this);
+    rv = service->UnregisterListener(mClientId, this);
   }
 
   return NS_SUCCEEDED(rv);
 }
 
 /**
  *  TelephonyListener Implementation
  */
@@ -347,23 +365,23 @@ BluetoothRilListener::Listen(bool aStart
 }
 
 void
 BluetoothRilListener::SelectClient()
 {
   // Reset mClientId
   mClientId = mMobileConnListeners.Length();
 
-  nsCOMPtr<nsIMobileConnectionProvider> connection =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(connection);
+  nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(service);
 
   for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
     nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-    connection->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
+    service->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
     if (!voiceInfo) {
       BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
       continue;
     }
 
     nsString regState;
     voiceInfo->GetState(regState);
     if (regState.EqualsLiteral("registered")) {
--- a/dom/bluetooth/BluetoothRilListener.h
+++ b/dom/bluetooth/BluetoothRilListener.h
@@ -7,17 +7,17 @@
 #ifndef mozilla_dom_bluetooth_bluetoothrillistener_h__
 #define mozilla_dom_bluetooth_bluetoothrillistener_h__
 
 #include "BluetoothCommon.h"
 
 #include "nsAutoPtr.h"
 
 #include "nsIIccProvider.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsITelephonyService.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothRilListener;
 
 class IccListener : public nsIIccListener
 {
--- a/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -14,17 +14,17 @@
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsContentUtils.h"
 #include "nsIAudioManager.h"
 #include "nsIDOMIccInfo.h"
 #include "nsIIccProvider.h"
 #include "nsIMobileConnectionInfo.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsIMobileNetworkInfo.h"
 #include "nsIObserverService.h"
 #include "nsISettingsService.h"
 #include "nsITelephonyService.h"
 #include "nsRadioInterfaceLayer.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
@@ -607,18 +607,18 @@ BluetoothHfpManager::HandleVolumeChanged
     sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs,
                                           new VolumeControlResultHandler());
   }
 }
 
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> connection =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  nsCOMPtr<nsIMobileConnectionService> connection =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
   connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
--- a/dom/bluetooth/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth/bluez/BluetoothHfpManager.cpp
@@ -23,17 +23,17 @@
 #include "nsIObserverService.h"
 #include "nsISettingsService.h"
 #include "nsServiceManagerUtils.h"
 
 #ifdef MOZ_B2G_RIL
 #include "nsIDOMIccInfo.h"
 #include "nsIIccProvider.h"
 #include "nsIMobileConnectionInfo.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsIMobileNetworkInfo.h"
 #include "nsITelephonyService.h"
 #include "nsRadioInterfaceLayer.h"
 #endif
 
 /**
  * BRSF bitmask of AG supported features. See 4.34.1 "Bluetooth Defined AT
  * Capabilities" in Bluetooth hands-free profile 1.6
@@ -601,18 +601,18 @@ BluetoothHfpManager::HandleVolumeChanged
     SendCommand(RESPONSE_VGS, mCurrentVgs);
   }
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> connection =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  nsCOMPtr<nsIMobileConnectionService> connection =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
   connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
--- a/dom/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth2/BluetoothAdapter.cpp
@@ -33,37 +33,17 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(Bluet
 
 // QueryInterface implementation for BluetoothAdapter
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, DOMEventTargetHelper)
 
-/*
- * A comparator that does the comparison of BluetoothDevice instances.
- * Two BluetoothDevices are equivalent if they have an identical address.
- */
-class BluetoothDeviceComparator
-{
-public:
-  bool Equals(const BluetoothDevice* aDeviceA,
-              const BluetoothDevice* aDeviceB) const
-  {
-    nsString addressA;
-    nsString addressB;
-
-    aDeviceA->GetAddress(addressA);
-    aDeviceB->GetAddress(addressB);
-
-    return addressA.Equals(addressB);
-  }
-};
-
-class StartDiscoveryTask : public BluetoothReplyRunnable
+class StartDiscoveryTask MOZ_FINAL : public BluetoothReplyRunnable
 {
 public:
   StartDiscoveryTask(BluetoothAdapter* aAdapter, Promise* aPromise)
     : BluetoothReplyRunnable(nullptr, aPromise,
                              NS_LITERAL_STRING("StartDiscovery"))
     , mAdapter(aAdapter)
   {
     MOZ_ASSERT(aPromise);
@@ -204,20 +184,20 @@ public:
   }
 };
 
 static int kCreatePairedDeviceTimeout = 50000; // unit: msec
 
 BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aWindow,
                                    const BluetoothValue& aValue)
   : DOMEventTargetHelper(aWindow)
-  , mDiscoveryHandleInUse(nullptr)
   , mState(BluetoothAdapterState::Disabled)
   , mDiscoverable(false)
   , mDiscovering(false)
+  , mDiscoveryHandleInUse(nullptr)
 {
   MOZ_ASSERT(aWindow);
   MOZ_ASSERT(IsDOMBinding());
 
   mPairingReqs = BluetoothPairingListener::Create(aWindow);
 
   const InfallibleTArray<BluetoothNamedValue>& values =
     aValue.get_ArrayOfBluetoothNamedValue();
@@ -299,17 +279,17 @@ BluetoothAdapter::SetPropertyByValue(con
       BT_APPEND_NAMED_VALUE(props, "Address", pairedDeviceAddresses[i]);
       BT_APPEND_NAMED_VALUE(props, "Paired", true);
 
       // Create paired device with 'address' and 'paired' attributes
       nsRefPtr<BluetoothDevice> pairedDevice =
         BluetoothDevice::Create(GetOwner(), BluetoothValue(props));
 
       // Append to adapter's device array if the device hasn't been created
-      if (!mDevices.Contains(pairedDevice, BluetoothDeviceComparator())) {
+      if (!mDevices.Contains(pairedDevice)) {
         mDevices.AppendElement(pairedDevice);
       }
     }
 
     // Retrieve device properties, result will be handled by device objects.
     GetPairedDeviceProperties(pairedDeviceAddresses);
   } else {
     BT_WARNING("Not handling adapter property: %s",
@@ -656,78 +636,93 @@ BluetoothAdapter::Pair(const nsAString& 
 
 already_AddRefed<Promise>
 BluetoothAdapter::Unpair(const nsAString& aDeviceAddress, ErrorResult& aRv)
 {
   return PairUnpair(false, aDeviceAddress, aRv);
 }
 
 already_AddRefed<Promise>
-BluetoothAdapter::EnableDisable(bool aEnable, ErrorResult& aRv)
+BluetoothAdapter::Enable(ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
   if (!global) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsRefPtr<Promise> promise = Promise::Create(global, aRv);
   NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
 
-  // Ensure BluetoothService is available before modifying adapter state
+  /**
+   * Ensure
+   * - adapter is disabled, and
+   * - BluetoothService is available.
+   */
+  BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Disabled,
+                        NS_ERROR_DOM_INVALID_STATE_ERR);
   BluetoothService* bs = BluetoothService::Get();
   BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
 
-  // Modify adapter state to Enabling/Disabling if adapter is in a valid state
-  nsAutoString methodName;
-  if (aEnable) {
-    // Enable local adapter
-    BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Disabled,
-                          NS_ERROR_DOM_INVALID_STATE_ERR);
-    methodName.AssignLiteral("Enable");
-    mState = BluetoothAdapterState::Enabling;
-  } else {
-    // Disable local adapter
-    BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled,
-                          NS_ERROR_DOM_INVALID_STATE_ERR);
-    methodName.AssignLiteral("Disable");
-    mState = BluetoothAdapterState::Disabling;
-  }
-
-  // Notify applications of adapter state change to Enabling/Disabling
-  HandleAdapterStateChanged();
+  // Set adapter state "Enabling"
+  SetAdapterState(BluetoothAdapterState::Enabling);
 
   // Wrap runnable to handle result
   nsRefPtr<BluetoothReplyRunnable> result =
     new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */
                                    promise,
-                                   methodName);
+                                   NS_LITERAL_STRING("Enable"));
 
-  if (NS_FAILED(bs->EnableDisable(aEnable, result))) {
-    // Restore mState and notify applications of adapter state change
-    mState = aEnable ? BluetoothAdapterState::Disabled
-                     : BluetoothAdapterState::Enabled;
-    HandleAdapterStateChanged();
-
+  if (NS_FAILED(bs->EnableDisable(true, result))) {
+    // Restore adapter state and reject promise
+    SetAdapterState(BluetoothAdapterState::Disabled);
     promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
   }
 
   return promise.forget();
 }
 
 already_AddRefed<Promise>
-BluetoothAdapter::Enable(ErrorResult& aRv)
-{
-  return EnableDisable(true, aRv);
-}
-
-already_AddRefed<Promise>
 BluetoothAdapter::Disable(ErrorResult& aRv)
 {
-  return EnableDisable(false, aRv);
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
+  if (!global) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  nsRefPtr<Promise> promise = Promise::Create(global, aRv);
+  NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
+
+  /**
+   * Ensure
+   * - adapter is enabled, and
+   * - BluetoothService is available.
+   */
+  BT_ENSURE_TRUE_REJECT(mState == BluetoothAdapterState::Enabled,
+                        NS_ERROR_DOM_INVALID_STATE_ERR);
+  BluetoothService* bs = BluetoothService::Get();
+  BT_ENSURE_TRUE_REJECT(bs, NS_ERROR_NOT_AVAILABLE);
+
+  // Set adapter state "Disabling"
+  SetAdapterState(BluetoothAdapterState::Disabling);
+
+  // Wrap runnable to handle result
+  nsRefPtr<BluetoothReplyRunnable> result =
+    new BluetoothVoidReplyRunnable(nullptr, /* DOMRequest */
+                                   promise,
+                                   NS_LITERAL_STRING("Disable"));
+
+  if (NS_FAILED(bs->EnableDisable(false, result))) {
+    // Restore adapter state and reject promise
+    SetAdapterState(BluetoothAdapterState::Enabled);
+    promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
+  }
+
+  return promise.forget();
 }
 
 BluetoothAdapterAttribute
 BluetoothAdapter::ConvertStringToAdapterAttribute(const nsAString& aString)
 {
   using namespace
     mozilla::dom::BluetoothAdapterAttributeValues;
 
@@ -763,18 +758,25 @@ BluetoothAdapter::IsAdapterAttributeChan
       return mDiscovering != aValue.get_bool();
     default:
       BT_WARNING("Type %d is not handled", uint32_t(aType));
       return false;
   }
 }
 
 void
-BluetoothAdapter::HandleAdapterStateChanged()
+BluetoothAdapter::SetAdapterState(BluetoothAdapterState aState)
 {
+  if (mState == aState) {
+    return;
+  }
+
+  mState = aState;
+
+  // Fire BluetoothAttributeEvent for changed adapter state
   nsTArray<nsString> types;
   BT_APPEND_ENUM_STRING(types,
                         BluetoothAdapterAttribute,
                         BluetoothAdapterAttribute::State);
   DispatchAttributeEvent(types);
 }
 
 void
@@ -811,20 +813,17 @@ BluetoothAdapter::HandleDeviceFound(cons
 {
   MOZ_ASSERT(mDiscoveryHandleInUse);
   MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
 
   // Create a temporary discovered BluetoothDevice to check existence
   nsRefPtr<BluetoothDevice> discoveredDevice =
     BluetoothDevice::Create(GetOwner(), aValue);
 
-  size_t index = mDevices.IndexOf(discoveredDevice,
-                                  0, /* aStart */
-                                  BluetoothDeviceComparator());
-
+  size_t index = mDevices.IndexOf(discoveredDevice);
   if (index == mDevices.NoIndex) {
     // New device, append it to adapter's device array
     mDevices.AppendElement(discoveredDevice);
   } else {
     // Existing device, discard temporary discovered device
     discoveredDevice = mDevices[index];
   }
 
@@ -852,20 +851,17 @@ BluetoothAdapter::HandlePairingRequest(c
 
   // Create a temporary device with deviceAddress for searching
   InfallibleTArray<BluetoothNamedValue> props;
   BT_APPEND_NAMED_VALUE(props, "Address", deviceAddress);
   nsRefPtr<BluetoothDevice> device =
     BluetoothDevice::Create(GetOwner(), props);
 
   // Find the remote device by address
-  size_t index = mDevices.IndexOf(device,
-                                  0, /* aStart */
-                                  BluetoothDeviceComparator());
-
+  size_t index = mDevices.IndexOf(device);
   if (index == mDevices.NoIndex) {
     BT_WARNING("Cannot find the remote device with address %s",
                NS_ConvertUTF16toUTF8(deviceAddress).get());
     return;
   }
 
   // Notify application of pairing requests
   mPairingReqs->DispatchPairingEvent(mDevices[index], passkey, type);
@@ -904,24 +900,21 @@ BluetoothAdapter::HandleDevicePaired(con
     BT_WARNING("HandleDevicePaired() is called when adapter isn't enabled.");
     return;
   }
 
   // Create paired device with 'address' and 'paired' attributes
   nsRefPtr<BluetoothDevice> pairedDevice =
     BluetoothDevice::Create(GetOwner(), aValue);
 
-  size_t index = mDevices.IndexOf(pairedDevice,
-                                  0, /* aStart */
-                                  BluetoothDeviceComparator());
-
-  if (index != mDevices.NoIndex) {
+  size_t index = mDevices.IndexOf(pairedDevice);
+  if (index == mDevices.NoIndex) {
+    mDevices.AppendElement(pairedDevice);
+  } else {
     pairedDevice = mDevices[index];
-  } else {
-    mDevices.AppendElement(pairedDevice);
   }
 
   // Notify application of paired device
   BluetoothDeviceEventInit init;
   init.mDevice = pairedDevice;
   DispatchDeviceEvent(NS_LITERAL_STRING("devicepaired"), init);
 }
 
@@ -934,26 +927,24 @@ BluetoothAdapter::HandleDeviceUnpaired(c
     BT_WARNING("HandleDeviceUnpaired() is called when adapter isn't enabled.");
     return;
   }
 
   // Create unpaired device with 'address' and 'paired' attributes
   nsRefPtr<BluetoothDevice> unpairedDevice =
     BluetoothDevice::Create(GetOwner(), aValue);
 
-  size_t index = mDevices.IndexOf(unpairedDevice,
-                                  0, /* aStart */
-                                  BluetoothDeviceComparator());
+  size_t index = mDevices.IndexOf(unpairedDevice);
 
   nsString deviceAddress;
-  if (index != mDevices.NoIndex) {
+  if (index == mDevices.NoIndex) {
+    unpairedDevice->GetAddress(deviceAddress);
+  } else {
     mDevices[index]->GetAddress(deviceAddress);
     mDevices.RemoveElementAt(index);
-  } else {
-    unpairedDevice->GetAddress(deviceAddress);
   }
 
   // Notify application of unpaired device
   BluetoothDeviceEventInit init;
   init.mAddress = deviceAddress;
   DispatchDeviceEvent(NS_LITERAL_STRING("deviceunpaired"), init);
 }
 
--- a/dom/bluetooth2/BluetoothAdapter.h
+++ b/dom/bluetooth2/BluetoothAdapter.h
@@ -2,59 +2,52 @@
 /* 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/. */
 
 #ifndef mozilla_dom_bluetooth_bluetoothadapter_h__
 #define mozilla_dom_bluetooth_bluetoothadapter_h__
 
+#include "BluetoothCommon.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DOMEventTargetHelper.h"
 #include "mozilla/dom/BluetoothAdapter2Binding.h"
 #include "mozilla/dom/BluetoothDeviceEvent.h"
 #include "mozilla/dom/Promise.h"
-#include "BluetoothCommon.h"
 #include "nsCOMPtr.h"
 
 namespace mozilla {
 namespace dom {
 class DOMRequest;
 struct MediaMetaData;
 struct MediaPlayStatus;
 }
 }
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothDevice;
 class BluetoothDiscoveryHandle;
-class BluetoothSignal;
 class BluetoothNamedValue;
 class BluetoothPairingListener;
+class BluetoothSignal;
 class BluetoothValue;
 
 class BluetoothAdapter : public DOMEventTargetHelper
                        , public BluetoothSignalObserver
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
                                            DOMEventTargetHelper)
 
-  static already_AddRefed<BluetoothAdapter>
-  Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
-
-  void Notify(const BluetoothSignal& aParam);
-
-  void SetPropertyByValue(const BluetoothNamedValue& aValue);
-
-  virtual void DisconnectFromOwner() MOZ_OVERRIDE;
-
+  /****************************************************************************
+   * Attribute Getters
+   ***************************************************************************/
   BluetoothAdapterState State() const
   {
     return mState;
   }
 
   void GetAddress(nsString& aAddress) const
   {
     aAddress = mAddress;
@@ -78,116 +71,159 @@ public:
     return mDiscoverable;
   }
 
   BluetoothPairingListener* PairingReqs() const
   {
     return mPairingReqs;
   }
 
-  /**
-   * Update this adapter's discovery handle in use (mDiscoveryHandleInUse).
-   *
-   * |mDiscoveryHandleInUse| is set to the latest discovery handle when adapter
-   * just starts discovery, and is reset to nullptr when discovery is stopped
-   * by some adapter.
-   *
-   * @param aDiscoveryHandle [in] the discovery handle to set.
-   */
-  void SetDiscoveryHandleInUse(BluetoothDiscoveryHandle* aDiscoveryHandle);
+  /****************************************************************************
+   * Event Handlers
+   ***************************************************************************/
+  IMPL_EVENT_HANDLER(attributechanged);
+  IMPL_EVENT_HANDLER(devicepaired);
+  IMPL_EVENT_HANDLER(deviceunpaired);
+  IMPL_EVENT_HANDLER(a2dpstatuschanged);
+  IMPL_EVENT_HANDLER(hfpstatuschanged);
+  IMPL_EVENT_HANDLER(requestmediaplaystatus);
+  IMPL_EVENT_HANDLER(scostatuschanged);
+
+  /****************************************************************************
+   * Methods (Web API Implementation)
+   ***************************************************************************/
+  already_AddRefed<Promise> Enable(ErrorResult& aRv);
+  already_AddRefed<Promise> Disable(ErrorResult& aRv);
 
   already_AddRefed<Promise> SetName(const nsAString& aName, ErrorResult& aRv);
-  already_AddRefed<Promise>
-    SetDiscoverable(bool aDiscoverable, ErrorResult& aRv);
+  already_AddRefed<Promise> SetDiscoverable(bool aDiscoverable,
+                                            ErrorResult& aRv);
   already_AddRefed<Promise> StartDiscovery(ErrorResult& aRv);
   already_AddRefed<Promise> StopDiscovery(ErrorResult& aRv);
-
-  already_AddRefed<Promise>
-    Pair(const nsAString& aDeviceAddress, ErrorResult& aRv);
-  already_AddRefed<Promise>
-    Unpair(const nsAString& aDeviceAddress, ErrorResult& aRv);
+  already_AddRefed<Promise> Pair(const nsAString& aDeviceAddress,
+                                 ErrorResult& aRv);
+  already_AddRefed<Promise> Unpair(const nsAString& aDeviceAddress,
+                                   ErrorResult& aRv);
 
   /**
    * Get a list of paired bluetooth devices.
    *
    * @param aDevices [out] Devices array to return
    */
   void GetPairedDevices(nsTArray<nsRefPtr<BluetoothDevice> >& aDevices);
 
-  already_AddRefed<Promise> EnableDisable(bool aEnable, ErrorResult& aRv);
-  already_AddRefed<Promise> Enable(ErrorResult& aRv);
-  already_AddRefed<Promise> Disable(ErrorResult& aRv);
-
+  // Connection related methods
   already_AddRefed<DOMRequest>
     Connect(BluetoothDevice& aDevice,
-            const Optional<short unsigned int>& aServiceUuid, ErrorResult& aRv);
+            const Optional<short unsigned int>& aServiceUuid,
+            ErrorResult& aRv);
   already_AddRefed<DOMRequest>
     Disconnect(BluetoothDevice& aDevice,
                const Optional<short unsigned int>& aServiceUuid,
                ErrorResult& aRv);
-  already_AddRefed<DOMRequest>
-    GetConnectedDevices(uint16_t aServiceUuid, ErrorResult& aRv);
+  already_AddRefed<DOMRequest> GetConnectedDevices(uint16_t aServiceUuid,
+                                                   ErrorResult& aRv);
 
+  // OPP file transfer related methods
+  already_AddRefed<DOMRequest> SendFile(const nsAString& aDeviceAddress,
+                                        nsIDOMBlob* aBlob,
+                                        ErrorResult& aRv);
+  already_AddRefed<DOMRequest> StopSendingFile(const nsAString& aDeviceAddress,
+                                               ErrorResult& aRv);
   already_AddRefed<DOMRequest>
-    SendFile(const nsAString& aDeviceAddress, nsIDOMBlob* aBlob,
-             ErrorResult& aRv);
-  already_AddRefed<DOMRequest>
-    StopSendingFile(const nsAString& aDeviceAddress, ErrorResult& aRv);
-  already_AddRefed<DOMRequest>
-    ConfirmReceivingFile(const nsAString& aDeviceAddress, bool aConfirmation,
+    ConfirmReceivingFile(const nsAString& aDeviceAddress,
+                         bool aConfirmation,
                          ErrorResult& aRv);
 
+  // SCO related methods
   already_AddRefed<DOMRequest> ConnectSco(ErrorResult& aRv);
   already_AddRefed<DOMRequest> DisconnectSco(ErrorResult& aRv);
   already_AddRefed<DOMRequest> IsScoConnected(ErrorResult& aRv);
 
+  // Handfree CDMA related methods
   already_AddRefed<DOMRequest> AnswerWaitingCall(ErrorResult& aRv);
   already_AddRefed<DOMRequest> IgnoreWaitingCall(ErrorResult& aRv);
   already_AddRefed<DOMRequest> ToggleCalls(ErrorResult& aRv);
 
+  // AVRCP related methods
   already_AddRefed<DOMRequest>
     SendMediaMetaData(const MediaMetaData& aMediaMetaData, ErrorResult& aRv);
   already_AddRefed<DOMRequest>
-    SendMediaPlayStatus(const MediaPlayStatus& aMediaPlayStatus, ErrorResult& aRv);
+    SendMediaPlayStatus(const MediaPlayStatus& aMediaPlayStatus,
+                        ErrorResult& aRv);
 
-  IMPL_EVENT_HANDLER(a2dpstatuschanged);
-  IMPL_EVENT_HANDLER(hfpstatuschanged);
-  IMPL_EVENT_HANDLER(requestmediaplaystatus);
-  IMPL_EVENT_HANDLER(scostatuschanged);
-  IMPL_EVENT_HANDLER(attributechanged);
-  IMPL_EVENT_HANDLER(devicepaired);
-  IMPL_EVENT_HANDLER(deviceunpaired);
+  /****************************************************************************
+   * Others
+   ***************************************************************************/
+  static already_AddRefed<BluetoothAdapter>
+    Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
 
+  void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
-  virtual JSObject*
-    WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual void DisconnectFromOwner() MOZ_OVERRIDE;
+
+  /**
+   * Set this adapter's discovery handle in use (mDiscoveryHandleInUse).
+   *
+   * |mDiscoveryHandleInUse| is set to the latest discovery handle when adapter
+   * just starts discovery, and is reset to nullptr when discovery is stopped
+   * by some adapter.
+   *
+   * @param aDiscoveryHandle [in] Discovery handle to set.
+   */
+  void SetDiscoveryHandleInUse(BluetoothDiscoveryHandle* aDiscoveryHandle);
 
 private:
   BluetoothAdapter(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
   ~BluetoothAdapter();
 
-  already_AddRefed<Promise>
-    PairUnpair(bool aPair, const nsAString& aDeviceAddress, ErrorResult& aRv);
+  /**
+   * Set adapter properties according to properties array
+   *
+   * @param aValue [in] Properties array to set with
+   */
+  void SetPropertyByValue(const BluetoothNamedValue& aValue);
+
+  /**
+   * Set adapter state and fire BluetoothAttributeEvent if state changed.
+   *
+   * @param aState [in] The new adapter state
+   */
+  void SetAdapterState(BluetoothAdapterState aState);
 
-  bool IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
-                                 const BluetoothValue& aValue);
-  void HandleAdapterStateChanged();
-  void HandlePropertyChanged(const BluetoothValue& aValue);
-  void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
-  BluetoothAdapterAttribute
-    ConvertStringToAdapterAttribute(const nsAString& aString);
+  /**
+   * Pair/Unpair adapter to device of given address.
+   * This function is called by methods Enable() and Disable().
+   *
+   * @param aPair          [in]  Whether to pair or unpair adapter to device.
+   * @param aDeviceAddress [in]  Address of device to pair/unpair.
+   * @param aRv            [out] Error result to set in case of error.
+   */
+  already_AddRefed<Promise> PairUnpair(bool aPair,
+                            const nsAString& aDeviceAddress,
+                            ErrorResult& aRv);
 
+  /**
+   * Retrieve properties of paired devices.
+   *
+   * @param aDeviceAddresses [in] Addresses array of paired devices
+   */
   void GetPairedDeviceProperties(const nsTArray<nsString>& aDeviceAddresses);
 
-  void HandleDeviceFound(const BluetoothValue& aValue);
-  void HandlePairingRequest(const BluetoothValue& aValue);
+  /**
+   * Handle "PropertyChanged" bluetooth signal.
+   *
+   * @param aValue [in] Array of changed properties
+   */
+  void HandlePropertyChanged(const BluetoothValue& aValue);
 
   /**
    * Handle DEVICE_PAIRED_ID bluetooth signal.
    *
    * @param aValue [in] Properties array of the paired device.
    *                    The array should contain two properties:
    *                    - nsString  'Address'
    *                    - bool      'Paired'
@@ -200,45 +236,116 @@ private:
    * @param aValue [in] Properties array of the unpaired device.
    *                    The array should contain two properties:
    *                    - nsString  'Address'
    *                    - bool      'Paired'
    */
   void HandleDeviceUnpaired(const BluetoothValue& aValue);
 
   /**
+   * Handle "DeviceFound" bluetooth signal.
+   *
+   * @param aValue [in] Properties array of the discovered device.
+   */
+  void HandleDeviceFound(const BluetoothValue& aValue);
+
+  /**
+   * Handle "PairingRequest" bluetooth signal.
+   *
+   * @param aValue [in] Array of information about the pairing request.
+   */
+  void HandlePairingRequest(const BluetoothValue& aValue);
+
+  /**
+   * Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
+   */
+  void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
+
+  /**
    * Fire BluetoothDeviceEvent to trigger
    * ondeviceparied/ondeviceunpaired event handler.
    *
    * @param aType [in] Event type to fire
    * @param aInit [in] Event initialization value
    */
   void DispatchDeviceEvent(const nsAString& aType,
                            const BluetoothDeviceEventInit& aInit);
 
   /**
-   * mDevices holds references of all created device objects.
-   * It is an empty array when the adapter state is disabled.
+   * Convert string to BluetoothAdapterAttribute.
+   *
+   * @param aString [in] String to convert
+   */
+  BluetoothAdapterAttribute
+    ConvertStringToAdapterAttribute(const nsAString& aString);
+
+  /**
+   * Check whether value of given adapter property has changed.
+   *
+   * @param aType  [in] Adapter property to check
+   * @param aValue [in] New value of the adapter property
+   */
+  bool IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
+                                 const BluetoothValue& aValue);
+
+  /****************************************************************************
+   * Variables
+   ***************************************************************************/
+  /**
+   * Current state of this adapter. Can be Disabled/Disabling/Enabled/Enabling.
+   */
+  BluetoothAdapterState mState;
+
+  /**
+   * BD address of this adapter.
+   */
+  nsString mAddress;
+
+  /**
+   * Human-readable name of this adapter.
+   */
+  nsString mName;
+
+  /**
+   * Whether this adapter can be discovered by nearby devices.
+   */
+  bool mDiscoverable;
+
+  /**
+   * Whether this adapter is discovering nearby devices.
+   */
+  bool mDiscovering;
+
+  /**
+   * Handle to fire pairing requests of different pairing types.
+   */
+  nsRefPtr<BluetoothPairingListener> mPairingReqs;
+
+  /**
+   * Handle to fire 'ondevicefound' event handler for discovered device.
+   *
+   * This variable is set to the latest discovery handle when adapter just
+   * starts discovery, and is reset to nullptr when discovery is stopped by
+   * some adapter.
+   */
+  nsRefPtr<BluetoothDiscoveryHandle> mDiscoveryHandleInUse;
+
+  /**
+   * Arrays of references to BluetoothDevices created by this adapter.
+   * This array is empty when adapter state is Disabled.
    *
    * Devices will be appended when
    * 1) Enabling BT: Paired devices reported by stack.
    * 2) Discovering: Discovered devices during discovery operation.
    * A device won't be appended if a device object with the same
    * address already exists.
    *
    * Devices will be removed when
    * 1) Starting discovery: All unpaired devices will be removed before this
    *    adapter starts a new discovery.
    * 2) Disabling BT: All devices will be removed.
    */
   nsTArray<nsRefPtr<BluetoothDevice> > mDevices;
-  nsRefPtr<BluetoothDiscoveryHandle> mDiscoveryHandleInUse;
-  nsRefPtr<BluetoothPairingListener> mPairingReqs;
-  BluetoothAdapterState mState;
-  nsString mAddress;
-  nsString mName;
-  bool mDiscoverable;
-  bool mDiscovering;
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth2/BluetoothDevice.cpp
+++ b/dom/bluetooth2/BluetoothDevice.cpp
@@ -22,17 +22,17 @@ USING_BLUETOOTH_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTION_INHERITED(BluetoothDevice, DOMEventTargetHelper, mCod)
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothDevice)
 NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
 
 NS_IMPL_ADDREF_INHERITED(BluetoothDevice, DOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(BluetoothDevice, DOMEventTargetHelper)
 
-class FetchUuidsTask : public BluetoothReplyRunnable
+class FetchUuidsTask MOZ_FINAL : public BluetoothReplyRunnable
 {
 public:
   FetchUuidsTask(Promise* aPromise,
                  const nsAString& aName,
                  BluetoothDevice* aDevice)
     : BluetoothReplyRunnable(nullptr /* DOMRequest */, aPromise, aName)
     , mDevice(aDevice)
   {
--- a/dom/bluetooth2/BluetoothDevice.h
+++ b/dom/bluetooth2/BluetoothDevice.h
@@ -28,25 +28,22 @@ class BluetoothValue;
 class BluetoothSignal;
 class BluetoothSocket;
 
 class BluetoothDevice MOZ_FINAL : public DOMEventTargetHelper
                                 , public BluetoothSignalObserver
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
-
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothDevice,
                                            DOMEventTargetHelper)
 
-  static already_AddRefed<BluetoothDevice>
-  Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
-
-  void Notify(const BluetoothSignal& aParam);
-
+  /****************************************************************************
+   * Attribute Getters
+   ***************************************************************************/
   void GetAddress(nsString& aAddress) const
   {
     aAddress = mAddress;
   }
 
   BluetoothClassOfDevice* Cod() const
   {
     return mCod;
@@ -57,52 +54,120 @@ public:
     aName = mName;
   }
 
   bool Paired() const
   {
     return mPaired;
   }
 
-  void GetUuids(nsTArray<nsString>& aUuids) {
+  void GetUuids(nsTArray<nsString>& aUuids) const
+  {
     aUuids = mUuids;
   }
 
+  /****************************************************************************
+   * Event Handlers
+   ***************************************************************************/
+  IMPL_EVENT_HANDLER(attributechanged);
+
+  /****************************************************************************
+   * Methods (Web API Implementation)
+   ***************************************************************************/
   already_AddRefed<Promise> FetchUuids(ErrorResult& aRv);
 
-  void SetPropertyByValue(const BluetoothNamedValue& aValue);
-
-  BluetoothDeviceAttribute
-  ConvertStringToDeviceAttribute(const nsAString& aString);
+  /****************************************************************************
+   * Others
+   ***************************************************************************/
+  static already_AddRefed<BluetoothDevice>
+    Create(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
 
-  bool
-  IsDeviceAttributeChanged(BluetoothDeviceAttribute aType,
-                           const BluetoothValue& aValue);
-
-  void HandlePropertyChanged(const BluetoothValue& aValue);
-
-  void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
-
-  IMPL_EVENT_HANDLER(attributechanged);
-
+  void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
      return GetOwner();
   }
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
+  /**
+   * Override operator== for device comparison
+   */
+  bool operator==(BluetoothDevice& aDevice) const
+  {
+    nsString address;
+    aDevice.GetAddress(address);
+    return mAddress.Equals(address);
+  }
+
 private:
   BluetoothDevice(nsPIDOMWindow* aOwner, const BluetoothValue& aValue);
   ~BluetoothDevice();
 
+  /**
+   * Set device properties according to properties array
+   *
+   * @param aValue [in] Properties array to set with
+   */
+  void SetPropertyByValue(const BluetoothNamedValue& aValue);
+
+  /**
+   * Handle "PropertyChanged" bluetooth signal.
+   *
+   * @param aValue [in] Array of changed properties
+   */
+  void HandlePropertyChanged(const BluetoothValue& aValue);
+
+  /**
+   * Fire BluetoothAttributeEvent to trigger onattributechanged event handler.
+   */
+  void DispatchAttributeEvent(const nsTArray<nsString>& aTypes);
+
+  /**
+   * Convert string to BluetoothDeviceAttribute.
+   *
+   * @param aString [in] String to convert
+   */
+  BluetoothDeviceAttribute
+    ConvertStringToDeviceAttribute(const nsAString& aString);
+
+  /**
+   * Check whether value of given device property has changed.
+   *
+   * @param aType  [in] Device property to check
+   * @param aValue [in] New value of the device property
+   */
+  bool IsDeviceAttributeChanged(BluetoothDeviceAttribute aType,
+                                const BluetoothValue& aValue);
+
+  /****************************************************************************
+   * Variables
+   ***************************************************************************/
+  /**
+   * BD address of this device.
+   */
   nsString mAddress;
+
+  /**
+   * Class of device (CoD) that describes this device's capabilities.
+   */
   nsRefPtr<BluetoothClassOfDevice> mCod;
+
+  /**
+   * Human-readable name of this device.
+   */
   nsString mName;
+
+  /**
+   * Whether this device is paired or not.
+   */
   bool mPaired;
+
+  /**
+   * Cached UUID list of services which this device provides.
+   */
   nsTArray<nsString> mUuids;
-
 };
 
 END_BLUETOOTH_NAMESPACE
 
 #endif
--- a/dom/bluetooth2/BluetoothManager.h
+++ b/dom/bluetooth2/BluetoothManager.h
@@ -21,55 +21,64 @@ class BluetoothAdapter;
 class BluetoothValue;
 
 class BluetoothManager : public DOMEventTargetHelper
                        , public BluetoothSignalObserver
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
-  // Never returns null
-  static already_AddRefed<BluetoothManager> Create(nsPIDOMWindow* aWindow);
-  static bool CheckPermission(nsPIDOMWindow* aWindow);
+  /****************************************************************************
+   * Event Handlers
+   ***************************************************************************/
+  IMPL_EVENT_HANDLER(attributechanged);
+  IMPL_EVENT_HANDLER(adapteradded);
+  IMPL_EVENT_HANDLER(adapterremoved);
 
+  /****************************************************************************
+   * Methods (Web API Implementation)
+   ***************************************************************************/
   /**
    * Return default adapter if it exists, nullptr otherwise. The function is
    * called when applications access property BluetoothManager.defaultAdapter
    */
   BluetoothAdapter* GetDefaultAdapter();
 
   /**
    * Return adapters array. The function is called when applications call
    * method BluetoothManager.getAdapters()
    *
    * @param aAdapters [out] Adapters array to return
    */
   void GetAdapters(nsTArray<nsRefPtr<BluetoothAdapter> >& aAdapters);
 
-  /**
-   * Create a BluetoothAdapter object based on properties array
-   * and append it into adapters array.
-   *
-   * @param aValue [in] Properties array to create BluetoothAdapter object
-   */
-  void AppendAdapter(const BluetoothValue& aValue);
-
-  IMPL_EVENT_HANDLER(attributechanged);
-  IMPL_EVENT_HANDLER(adapteradded);
-  IMPL_EVENT_HANDLER(adapterremoved);
+  /****************************************************************************
+   * Others
+   ***************************************************************************/
+  // Never returns null
+  static already_AddRefed<BluetoothManager> Create(nsPIDOMWindow* aWindow);
+  static bool CheckPermission(nsPIDOMWindow* aWindow);
 
   void Notify(const BluetoothSignal& aData); // BluetoothSignalObserver
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
   virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
+  /**
+   * Create a BluetoothAdapter object based on properties array
+   * and append it into adapters array.
+   *
+   * @param aValue [in] Properties array to create BluetoothAdapter object
+   */
+  void AppendAdapter(const BluetoothValue& aValue);
+
 private:
   BluetoothManager(nsPIDOMWindow* aWindow);
   ~BluetoothManager();
 
   /**
    * Start/Stop listening to bluetooth signal.
    *
    * @param aStart [in] Whether to start or stop listening to bluetooth signal
--- a/dom/bluetooth2/BluetoothRilListener.cpp
+++ b/dom/bluetooth2/BluetoothRilListener.cpp
@@ -108,22 +108,22 @@ MobileConnectionListener::NotifyUssdRece
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyDataError(const nsAString & message)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
-MobileConnectionListener::NotifyCFStateChange(bool success,
-                                              uint16_t action,
-                                              uint16_t reason,
-                                              const nsAString& number,
-                                              uint16_t timeSeconds,
-                                              uint16_t serviceClass)
+MobileConnectionListener::NotifyCFStateChanged(bool success,
+                                               uint16_t action,
+                                               uint16_t reason,
+                                               const nsAString& number,
+                                               uint16_t timeSeconds,
+                                               uint16_t serviceClass)
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyEmergencyCbModeChanged(bool active,
                                                        uint32_t timeoutMs)
 {
@@ -149,28 +149,46 @@ MobileConnectionListener::NotifyRadioSta
 }
 
 NS_IMETHODIMP
 MobileConnectionListener::NotifyClirModeChanged(uint32_t aMode)
 {
   return NS_OK;
 }
 
+NS_IMETHODIMP
+MobileConnectionListener::NotifyLastKnownNetworkChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyLastKnownHomeNetworkChanged()
+{
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileConnectionListener::NotifyNetworkSelectionModeChanged()
+{
+  return NS_OK;
+}
+
 bool
 MobileConnectionListener::Listen(bool aStart)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> provider =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE(provider, false);
+  nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE(service, false);
 
   nsresult rv;
   if (aStart) {
-    rv = provider->RegisterMobileConnectionMsg(mClientId, this);
+    rv = service->RegisterListener(mClientId, this);
   } else {
-    rv = provider->UnregisterMobileConnectionMsg(mClientId, this);
+    rv = service->UnregisterListener(mClientId, this);
   }
 
   return NS_SUCCEEDED(rv);
 }
 
 /**
  *  TelephonyListener Implementation
  */
@@ -347,23 +365,23 @@ BluetoothRilListener::Listen(bool aStart
 }
 
 void
 BluetoothRilListener::SelectClient()
 {
   // Reset mClientId
   mClientId = mMobileConnListeners.Length();
 
-  nsCOMPtr<nsIMobileConnectionProvider> connection =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
-  NS_ENSURE_TRUE_VOID(connection);
+  nsCOMPtr<nsIMobileConnectionService> service =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
+  NS_ENSURE_TRUE_VOID(service);
 
   for (uint32_t i = 0; i < mMobileConnListeners.Length(); i++) {
     nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
-    connection->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
+    service->GetVoiceConnectionInfo(i, getter_AddRefs(voiceInfo));
     if (!voiceInfo) {
       BT_WARNING("%s: Failed to get voice connection info", __FUNCTION__);
       continue;
     }
 
     nsString regState;
     voiceInfo->GetState(regState);
     if (regState.EqualsLiteral("registered")) {
--- a/dom/bluetooth2/BluetoothRilListener.h
+++ b/dom/bluetooth2/BluetoothRilListener.h
@@ -7,17 +7,17 @@
 #ifndef mozilla_dom_bluetooth_bluetoothrillistener_h__
 #define mozilla_dom_bluetooth_bluetoothrillistener_h__
 
 #include "BluetoothCommon.h"
 
 #include "nsAutoPtr.h"
 
 #include "nsIIccProvider.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsITelephonyService.h"
 
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothRilListener;
 
 class IccListener : public nsIIccListener
 {
--- a/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluedroid/hfp/BluetoothHfpManager.cpp
@@ -14,17 +14,17 @@
 #include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/Services.h"
 #include "mozilla/StaticPtr.h"
 #include "nsContentUtils.h"
 #include "nsIAudioManager.h"
 #include "nsIDOMIccInfo.h"
 #include "nsIIccProvider.h"
 #include "nsIMobileConnectionInfo.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsIMobileNetworkInfo.h"
 #include "nsIObserverService.h"
 #include "nsISettingsService.h"
 #include "nsITelephonyService.h"
 #include "nsRadioInterfaceLayer.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
@@ -610,18 +610,18 @@ BluetoothHfpManager::HandleVolumeChanged
     sBluetoothHfpInterface->VolumeControl(HFP_VOLUME_TYPE_SPEAKER, mCurrentVgs,
                                           new VolumeControlResultHandler());
   }
 }
 
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> connection =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  nsCOMPtr<nsIMobileConnectionService> connection =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
   connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
--- a/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
+++ b/dom/bluetooth2/bluez/BluetoothHfpManager.cpp
@@ -23,17 +23,17 @@
 #include "nsIObserverService.h"
 #include "nsISettingsService.h"
 #include "nsServiceManagerUtils.h"
 
 #ifdef MOZ_B2G_RIL
 #include "nsIDOMIccInfo.h"
 #include "nsIIccProvider.h"
 #include "nsIMobileConnectionInfo.h"
-#include "nsIMobileConnectionProvider.h"
+#include "nsIMobileConnectionService.h"
 #include "nsIMobileNetworkInfo.h"
 #include "nsITelephonyService.h"
 #include "nsRadioInterfaceLayer.h"
 #endif
 
 /**
  * BRSF bitmask of AG supported features. See 4.34.1 "Bluetooth Defined AT
  * Capabilities" in Bluetooth hands-free profile 1.6
@@ -601,18 +601,18 @@ BluetoothHfpManager::HandleVolumeChanged
     SendCommand(RESPONSE_VGS, mCurrentVgs);
   }
 }
 
 #ifdef MOZ_B2G_RIL
 void
 BluetoothHfpManager::HandleVoiceConnectionChanged(uint32_t aClientId)
 {
-  nsCOMPtr<nsIMobileConnectionProvider> connection =
-    do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  nsCOMPtr<nsIMobileConnectionService> connection =
+    do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
   NS_ENSURE_TRUE_VOID(connection);
 
   nsCOMPtr<nsIMobileConnectionInfo> voiceInfo;
   connection->GetVoiceConnectionInfo(aClientId, getter_AddRefs(voiceInfo));
   NS_ENSURE_TRUE_VOID(voiceInfo);
 
   nsString type;
   voiceInfo->GetType(type);
--- a/dom/browser-element/BrowserElementChildPreload.js
+++ b/dom/browser-element/BrowserElementChildPreload.js
@@ -191,16 +191,21 @@ BrowserElementChild.prototype = {
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('DOMLinkAdded',
                      this._linkAddedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
+    addEventListener('MozScrolledAreaChanged',
+                     this._mozScrollAreaChanged.bind(this),
+                     /* useCapture = */ true,
+                     /* wantsUntrusted = */ false);
+
     addEventListener('DOMMetaAdded',
                      this._metaChangedHandler.bind(this),
                      /* useCapture = */ true,
                      /* wantsUntrusted = */ false);
 
     addEventListener('DOMMetaChanged',
                      this._metaChangedHandler.bind(this),
                      /* useCapture = */ true,
@@ -231,16 +236,17 @@ BrowserElementChild.prototype = {
       sendAsyncMsg('firstpaint');
     });
 
     let self = this;
 
     let mmCalls = {
       "purge-history": this._recvPurgeHistory,
       "get-screenshot": this._recvGetScreenshot,
+      "get-contentdimensions": this._recvGetContentDimensions,
       "set-visible": this._recvSetVisible,
       "get-visible": this._recvVisible,
       "send-mouse-event": this._recvSendMouseEvent,
       "send-touch-event": this._recvSendTouchEvent,
       "get-can-go-back": this._recvCanGoBack,
       "get-can-go-forward": this._recvCanGoForward,
       "go-back": this._recvGoBack,
       "go-forward": this._recvGoForward,
@@ -869,16 +875,39 @@ BrowserElementChild.prototype = {
 
     // Try to wait for the event loop to go idle before we take the screenshot,
     // but once we've waited maxDelayMS milliseconds, go ahead and take it
     // anyway.
     Cc['@mozilla.org/message-loop;1'].getService(Ci.nsIMessageLoop).postIdleTask(
       takeScreenshotClosure, maxDelayMS);
   },
 
+  _recvGetContentDimensions: function(data) {
+    debug("Received getContentDimensions message: (" + data.json.id + ")");
+    sendAsyncMsg('got-contentdimensions', {
+      id: data.json.id,
+      successRv: this._getContentDimensions()
+    });
+  },
+
+  _mozScrollAreaChanged: function(e) {
+    let dimensions = this._getContentDimensions();
+    sendAsyncMsg('scrollareachanged', {
+      width: dimensions.width,
+      height: dimensions.height
+    });
+  },
+
+  _getContentDimensions: function() {
+    return {
+      width: content.document.body.scrollWidth,
+      height: content.document.body.scrollHeight
+    }
+  },
+
   /**
    * Actually take a screenshot and foward the result up to our parent, given
    * the desired maxWidth and maxHeight (in CSS pixels), and given the
    * DOMRequest ID associated with the request from the parent.
    */
   _takeScreenshot: function(maxWidth, maxHeight, mimeType, domRequestID) {
     // You can think of the screenshotting algorithm as carrying out the
     // following steps:
--- a/dom/browser-element/BrowserElementParent.jsm
+++ b/dom/browser-element/BrowserElementParent.jsm
@@ -133,16 +133,17 @@ function BrowserElementParent(frameLoade
     defineNoReturnMethod('stop', this._stop);
     defineMethod('download', this._download);
     defineDOMRequestMethod('purgeHistory', 'purge-history');
     defineMethod('getScreenshot', this._getScreenshot);
     defineNoReturnMethod('zoom', this._zoom);
 
     defineDOMRequestMethod('getCanGoBack', 'get-can-go-back');
     defineDOMRequestMethod('getCanGoForward', 'get-can-go-forward');
+    defineDOMRequestMethod('getContentDimensions', 'get-contentdimensions');
   }
 
   defineMethod('addNextPaintListener', this._addNextPaintListener);
   defineMethod('removeNextPaintListener', this._removeNextPaintListener);
 
   let principal = this._frameElement.ownerDocument.nodePrincipal;
   let perm = Services.perms
              .testExactPermissionFromPrincipal(principal, "input-manage");
@@ -242,16 +243,17 @@ BrowserElementParent.prototype = {
       "close": this._fireEventFromMsg,
       "error": this._fireEventFromMsg,
       "firstpaint": this._fireProfiledEventFromMsg,
       "documentfirstpaint": this._fireProfiledEventFromMsg,
       "nextpaint": this._recvNextPaint,
       "keyevent": this._fireKeyEvent,
       "got-purge-history": this._gotDOMRequestResult,
       "got-screenshot": this._gotDOMRequestResult,
+      "got-contentdimensions": this._gotDOMRequestResult,
       "got-can-go-back": this._gotDOMRequestResult,
       "got-can-go-forward": this._gotDOMRequestResult,
       "fullscreen-origin-change": this._remoteFullscreenOriginChange,
       "rollback-fullscreen": this._remoteFrameFullscreenReverted,
       "exit-fullscreen": this._exitFullscreen,
       "got-visible": this._gotDOMRequestResult,
       "visibilitychange": this._childVisibilityChange,
       "got-set-input-method-active": this._gotDOMRequestResult,
@@ -259,16 +261,17 @@ BrowserElementParent.prototype = {
     };
 
     let mmSecuritySensitiveCalls = {
       "showmodalprompt": this._handleShowModalPrompt,
       "contextmenu": this._fireCtxMenuEvent,
       "securitychange": this._fireEventFromMsg,
       "locationchange": this._fireEventFromMsg,
       "iconchange": this._fireEventFromMsg,
+      "scrollareachanged": this._fireEventFromMsg,
       "titlechange": this._fireProfiledEventFromMsg,
       "opensearch": this._fireEventFromMsg,
       "manifestchange": this._fireEventFromMsg,
       "metachange": this._fireEventFromMsg,
       "resize": this._fireEventFromMsg,
       "activitydone": this._fireEventFromMsg,
       "scroll": this._fireEventFromMsg
     };
@@ -565,17 +568,18 @@ BrowserElementParent.prototype = {
    *
    */
   _gotDOMRequestResult: function(data) {
     let req = this._pendingDOMRequests[data.json.id];
     delete this._pendingDOMRequests[data.json.id];
 
     if ('successRv' in data.json) {
       debug("Successful gotDOMRequestResult.");
-      Services.DOMRequest.fireSuccess(req, data.json.successRv);
+      let clientObj = Cu.cloneInto(data.json.successRv, this._window);
+      Services.DOMRequest.fireSuccess(req, clientObj);
     }
     else {
       debug("Got error in gotDOMRequestResult.");
       Services.DOMRequest.fireErrorAsync(req, data.json.errorMsg);
     }
   },
 
   _setVisible: function(visible) {
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/browserElement_GetContentDimensions.js
@@ -0,0 +1,67 @@
+/* Any copyright is dedicated to the public domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Bug 757859 - Test the getContentDimensions functionality of mozbrowser
+
+"use strict";
+SimpleTest.waitForExplicitFinish();
+browserElementTestHelpers.setEnabledPref(true);
+browserElementTestHelpers.addPermission();
+
+var resizeContent = function() {
+  var innerBox = content.document.getElementById('abox');
+  innerBox.style.width = '800px';
+  innerBox.style.height = '800px';
+}
+
+function runTest() {
+
+  var iframe1 = document.createElement('iframe');
+  SpecialPowers.wrap(iframe1).mozbrowser = true;
+
+  var iframeWidth = 400;
+  var iframeHeight = 400;
+  var numIframeLoaded = 0;
+  var numResizeEvents = 0;
+  var mm;
+
+  iframe1.src = 'data:text/html,<html><body><div id=\'abox\' ' +
+    'style=\'background:blue;width:200px;height:200px\'>test</div></body></html>';
+  iframe1.style.width = iframeWidth + 'px';
+  iframe1.style.height = iframeHeight + 'px';
+  document.body.appendChild(iframe1);
+
+  function iframeScrollAreaChanged(e) {
+    numResizeEvents++;
+    if (numResizeEvents === 1) {
+      ok(true, 'Resize event when changing content size');
+      ok(e.detail.width > iframeWidth, 'Iframes content is larger than iframe');
+      ok(e.detail.height > iframeHeight, 'Iframes content is larger than iframe');
+      iframe1.src = 'data:text/html,<html><body><div id=\'abox\' ' +
+        'style=\'background:blue;width:200px;height:200px\'>test</div></body></html>';
+    } else if (numResizeEvents === 2) {
+      ok(true, 'Resize event when changing src');
+      iframe1.removeEventListener('mozbrowserresize', iframeScrollAreaChanged);
+      SimpleTest.finish();
+    }
+  }
+
+  function iframeLoadedHandler() {
+    iframe1.removeEventListener('mozbrowserloadend', iframeLoadedHandler);
+    mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
+    iframe1.getContentDimensions().onsuccess = function(e) {
+      ok(typeof e.target.result.width === 'number', 'Received width');
+      ok(typeof e.target.result.height === 'number', 'Received height');
+      ok(e.target.result.height <= iframeHeight, 'Iframes content is smaller than iframe');
+      ok(e.target.result.width <= iframeWidth, 'Iframes content is smaller than iframe');
+      iframe1.addEventListener('mozbrowserscrollareachanged', iframeScrollAreaChanged);
+      mm.loadFrameScript('data:,(' + resizeContent.toString() + ')();', false);
+    }
+  }
+
+  iframe1.addEventListener('mozbrowserloadend', iframeLoadedHandler);
+}
+
+addEventListener('load', function() {
+  SimpleTest.executeSoon(runTest);
+});
--- a/dom/browser-element/mochitest/mochitest-oop.ini
+++ b/dom/browser-element/mochitest/mochitest-oop.ini
@@ -90,8 +90,9 @@ skip-if = (toolkit == 'gonk' && !debug)
 disabled = bug 930449
 # Disabled until bug 924771 makes them stop timing out
 [test_browserElement_oop_CloseFromOpener.html]
 disabled = bug 924771
 [test_browserElement_oop_CloseApp.html]
 disabled = bug 924771
 [test_browserElement_oop_ExposableURI.html]
 disabled = bug 924771
+[test_browserElement_oop_GetContentDimensions.html]
--- a/dom/browser-element/mochitest/mochitest.ini
+++ b/dom/browser-element/mochitest/mochitest.ini
@@ -61,16 +61,18 @@ support-files =
   browserElement_TargetTop.js
   browserElement_Titlechange.js
   browserElement_TopBarrier.js
   browserElement_VisibilityChange.js
   browserElement_XFrameOptions.js
   browserElement_XFrameOptionsAllowFrom.js
   browserElement_XFrameOptionsDeny.js
   browserElement_XFrameOptionsSameOrigin.js
+  browserElement_XFrameOptionsSameOrigin.js
+  browserElement_GetContentDimensions.js
   file_browserElement_AlertInFrame.html
   file_browserElement_AlertInFrame_Inner.html
   file_browserElement_AppFramePermission.html
   file_browserElement_AppWindowNamespace.html
   file_browserElement_ThemeColor.html
   file_browserElement_BrowserWindowNamespace.html
   file_browserElement_CloseApp.html
   file_browserElement_CloseFromOpener.html
@@ -196,8 +198,9 @@ skip-if = (toolkit == 'gonk' && !debug)
 [test_browserElement_inproc_XFrameOptionsSameOrigin.html]
 [test_browserElement_oop_NextPaint.html]
 # Disabled due to https://bugzilla.mozilla.org/show_bug.cgi?id=774100
 [test_browserElement_inproc_Reload.html]
 disabled = bug 774100
 # Disabled due to focus issues (no bug that I'm aware of)
 [test_browserElement_oop_KeyEvents.html]
 disabled =
+[test_browserElement_inproc_GetContentDimensions.html]
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_inproc_GetContentDimensions.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test of browser element.</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript;version=1.7" src="browserElement_GetContentDimensions.js">
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/browser-element/mochitest/test_browserElement_oop_GetContentDimensions.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test of browser element.</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="browserElementTestHelpers.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<script type="application/javascript;version=1.7" src="browserElement_GetContentDimensions.js">
+</script>
+</body>
+</html>
--- a/dom/canvas/WebGLExtensions.h
+++ b/dom/canvas/WebGLExtensions.h
@@ -48,230 +48,230 @@ protected:
     WebGLExtensionType::WrapObject(JSContext *cx) { \
         return dom::WebGLExtensionType##Binding::Wrap(cx, this); \
     }
 
 class WebGLExtensionCompressedTextureATC
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionCompressedTextureATC(WebGLContext*);
+    explicit WebGLExtensionCompressedTextureATC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureATC();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionCompressedTextureETC1
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionCompressedTextureETC1(WebGLContext*);
+    explicit WebGLExtensionCompressedTextureETC1(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureETC1();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionCompressedTexturePVRTC
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionCompressedTexturePVRTC(WebGLContext*);
+    explicit WebGLExtensionCompressedTexturePVRTC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTexturePVRTC();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionCompressedTextureS3TC
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionCompressedTextureS3TC(WebGLContext*);
+    explicit WebGLExtensionCompressedTextureS3TC(WebGLContext*);
     virtual ~WebGLExtensionCompressedTextureS3TC();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionDebugRendererInfo
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionDebugRendererInfo(WebGLContext*);
+    explicit WebGLExtensionDebugRendererInfo(WebGLContext*);
     virtual ~WebGLExtensionDebugRendererInfo();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionDebugShaders
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionDebugShaders(WebGLContext*);
+    explicit WebGLExtensionDebugShaders(WebGLContext*);
     virtual ~WebGLExtensionDebugShaders();
 
     void GetTranslatedShaderSource(WebGLShader* shader, nsAString& retval);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionDepthTexture
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionDepthTexture(WebGLContext*);
+    explicit WebGLExtensionDepthTexture(WebGLContext*);
     virtual ~WebGLExtensionDepthTexture();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionElementIndexUint
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionElementIndexUint(WebGLContext*);
+    explicit WebGLExtensionElementIndexUint(WebGLContext*);
     virtual ~WebGLExtensionElementIndexUint();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionFragDepth
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionFragDepth(WebGLContext*);
+    explicit WebGLExtensionFragDepth(WebGLContext*);
     virtual ~WebGLExtensionFragDepth();
 
     static bool IsSupported(const WebGLContext* context);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionLoseContext
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionLoseContext(WebGLContext*);
+    explicit WebGLExtensionLoseContext(WebGLContext*);
     virtual ~WebGLExtensionLoseContext();
 
     void LoseContext();
     void RestoreContext();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionSRGB
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionSRGB(WebGLContext*);
+    explicit WebGLExtensionSRGB(WebGLContext*);
     virtual ~WebGLExtensionSRGB();
 
     static bool IsSupported(const WebGLContext* context);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionStandardDerivatives
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionStandardDerivatives(WebGLContext*);
+    explicit WebGLExtensionStandardDerivatives(WebGLContext*);
     virtual ~WebGLExtensionStandardDerivatives();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionShaderTextureLod
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionShaderTextureLod(WebGLContext*);
+    explicit WebGLExtensionShaderTextureLod(WebGLContext*);
     virtual ~WebGLExtensionShaderTextureLod();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureFilterAnisotropic
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionTextureFilterAnisotropic(WebGLContext*);
+    explicit WebGLExtensionTextureFilterAnisotropic(WebGLContext*);
     virtual ~WebGLExtensionTextureFilterAnisotropic();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureFloat
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionTextureFloat(WebGLContext*);
+    explicit WebGLExtensionTextureFloat(WebGLContext*);
     virtual ~WebGLExtensionTextureFloat();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureFloatLinear
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionTextureFloatLinear(WebGLContext*);
+    explicit WebGLExtensionTextureFloatLinear(WebGLContext*);
     virtual ~WebGLExtensionTextureFloatLinear();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureHalfFloat
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionTextureHalfFloat(WebGLContext*);
+    explicit WebGLExtensionTextureHalfFloat(WebGLContext*);
     virtual ~WebGLExtensionTextureHalfFloat();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionTextureHalfFloatLinear
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionTextureHalfFloatLinear(WebGLContext*);
+    explicit WebGLExtensionTextureHalfFloatLinear(WebGLContext*);
     virtual ~WebGLExtensionTextureHalfFloatLinear();
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionColorBufferFloat
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionColorBufferFloat(WebGLContext*);
+    explicit WebGLExtensionColorBufferFloat(WebGLContext*);
     virtual ~WebGLExtensionColorBufferFloat();
 
     static bool IsSupported(const WebGLContext*);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionColorBufferHalfFloat
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionColorBufferHalfFloat(WebGLContext*);
+    explicit WebGLExtensionColorBufferHalfFloat(WebGLContext*);
     virtual ~WebGLExtensionColorBufferHalfFloat();
 
     static bool IsSupported(const WebGLContext*);
 
     DECL_WEBGL_EXTENSION_GOOP
 };
 
 class WebGLExtensionDrawBuffers
     : public WebGLExtensionBase
 {
 public:
-    WebGLExtensionDrawBuffers(WebGLContext*);
+    explicit WebGLExtensionDrawBuffers(WebGLContext*);
     virtual ~WebGLExtensionDrawBuffers();
 
     void DrawBuffersWEBGL(const dom::Sequence<GLenum>& buffers);
 
     static bool IsSupported(const WebGLContext*);
 
     static const size_t sMinColorAttachments = 4;
     static const size_t sMinDrawBuffers = 4;
--- a/dom/canvas/test/webgl-conformance/generate-wrappers-and-manifest.py
+++ b/dom/canvas/test/webgl-conformance/generate-wrappers-and-manifest.py
@@ -21,17 +21,17 @@ def GetTestList():
 # Internals
 
 BASE_TEST_LIST_FILENAME = '00_test_list.txt'
 
 def AccumTests(path, listFile, out_testList):
     listFilePath = os.path.join(path, listFile)
     assert os.path.exists(listFilePath), 'Bad `listFilePath`: ' + listFilePath
 
-    with open(listFilePath) as fIn:
+    with open(listFilePath, 'rb') as fIn:
         for line in fIn:
             line = line.rstrip()
             if not line:
                 continue
 
             strippedLine = line.lstrip()
             if strippedLine.startswith('//'):
                 continue
@@ -41,16 +41,17 @@ def AccumTests(path, listFile, out_testL
                 continue
 
             split = line.rsplit('.', 1)
             assert len(split) == 2, 'Bad split for `line`: ' + line
             (name, ext) = split
 
             if ext == 'html':
                 newTestFilePath = os.path.join(path, line)
+                newTestFilePath = newTestFilePath.replace(os.sep, '/')
                 out_testList.append(newTestFilePath)
                 continue
 
             assert ext == 'txt', 'Bad `ext` on `line`: ' + line
 
             split = line.rsplit('/', 1)
             nextListFile = split[-1]
             nextPath = ''
@@ -68,24 +69,24 @@ def AccumTests(path, listFile, out_testL
 
 def FillTemplate(inFilePath, templateDict, outFilePath):
     templateShell = ImportTemplate(inFilePath)
     OutputFilledTemplate(templateShell, templateDict, outFilePath)
     return
 
 
 def ImportTemplate(inFilePath):
-    with open(inFilePath, 'r') as f:
+    with open(inFilePath, 'rb') as f:
         return TemplateShell(f)
 
 
 def OutputFilledTemplate(templateShell, templateDict, outFilePath):
     spanStrList = templateShell.Fill(templateDict)
 
-    with open(outFilePath, 'w') as f:
+    with open(outFilePath, 'wb') as f:
         f.writelines(spanStrList)
     return
 
 ##############################
 # Internals
 
 def WrapWithIndent(lines, indentLen):
   split = lines.split('\n')
@@ -183,63 +184,62 @@ class TemplateShell:
                 indentLen += len(span)
             continue
 
         return ret
 
 ########################################################################
 # Output
 
-def WriteWrappers(testFilePathList):
+def WriteWrappers(testWebPathList):
     templateShell = ImportTemplate(WRAPPER_TEMPLATE_FILEPATH)
 
     if not os.path.exists(WRAPPERS_DIR):
         os.mkdir(WRAPPERS_DIR)
     assert os.path.isdir(WRAPPERS_DIR)
 
-    wrapperFilePathList = []
-    for testFilePath in testFilePathList:
+    wrapperManifestPathList = []
+    for testWebPath in testWebPathList:
         # Mochitests must start with 'test_' or similar, or the test
         # runner will ignore our tests.
         # The error text is "is not a valid test".
-        wrapperFilePath = 'test_' + testFilePath.replace(os.sep, '__')
+        wrapperFilePath = 'test_' + testWebPath.replace('/', '__')
         wrapperFilePath = os.path.join(WRAPPERS_DIR, wrapperFilePath)
 
-        testFilePath = testFilePath.replace(os.sep, '/')
-
         templateDict = {
-            'TEST_PATH': testFilePath,
+            'TEST_PATH': testWebPath,
         }
 
         print('Writing \'' + wrapperFilePath + '\'')
         OutputFilledTemplate(templateShell, templateDict,
                              wrapperFilePath)
 
-        wrapperFilePathList.append(wrapperFilePath)
+        wrapperManifestPath = wrapperFilePath.replace(os.sep, '/')
+        wrapperManifestPathList.append(wrapperManifestPath)
         continue
 
-    return wrapperFilePathList
+    return wrapperManifestPathList
 
 
-def WriteManifest(wrapperFilePathList, supportFilePathList):
+def WriteManifest(wrapperManifestPathList, supportFilePathList):
     errataMap = LoadErrata()
 
     # DEFAULT_ERRATA
     defaultHeader = '[DEFAULT]'
     defaultErrataStr = ''
     if defaultHeader in errataMap:
         defaultErrataStr = '\n'.join(errataMap[defaultHeader])
         del errataMap[defaultHeader]
 
     # SUPPORT_FILES
     supportFilePathList = sorted(supportFilePathList)
     supportFilesStr = '\n'.join(supportFilePathList)
 
     # MANIFEST_TESTS
-    headerList = ['[' + x + ']' for x in wrapperFilePathList]
+    headerList = ['[' + x + ']' for x in wrapperManifestPathList]
 
     manifestTestLineList = []
     for header in headerList:
         manifestTestLineList.append(header)
 
         if not header in errataMap:
             continue
 
@@ -274,17 +274,17 @@ ERRATA_FILEPATH = 'mochitest-errata.ini'
 kManifestHeaderRegex = re.compile(r'\[[^\]]*?\]')
 
 
 def LoadErrata():
     nodeMap = {}
 
     nodeHeader = None
     nodeLineList = []
-    with open(ERRATA_FILEPATH, 'r') as f:
+    with open(ERRATA_FILEPATH, 'rb') as f:
         for line in f:
             line = line.rstrip()
             cur = line.lstrip()
             if cur.startswith('#'):
                 continue
 
             if not cur:
                 continue
@@ -326,27 +326,28 @@ def GetSupportFileList():
     return ret
 
 
 def GetFilePathListForDir(baseDir):
     ret = []
     for root, folders, files in os.walk(baseDir):
         for f in files:
             filePath = os.path.join(root, f)
+            filePath = filePath.replace(os.sep, '/')
             ret.append(filePath)
 
     return ret
 
 
 if __name__ == '__main__':
     fileDir = os.path.dirname(__file__)
     assert not fileDir, 'Run this file from its directory, not ' + fileDir
 
-    testFilePathList = GetTestList()
+    testWebPathList = GetTestList()
 
-    wrapperFilePathList = WriteWrappers(testFilePathList)
+    wrapperFilePathList = WriteWrappers(testWebPathList)
 
     supportFilePathList = GetSupportFileList()
     WriteManifest(wrapperFilePathList, supportFilePathList)
 
     print('Done!')
 
 
--- a/dom/events/ScrollAreaEvent.cpp
+++ b/dom/events/ScrollAreaEvent.cpp
@@ -11,19 +11,19 @@
 
 namespace mozilla {
 namespace dom {
 
 ScrollAreaEvent::ScrollAreaEvent(EventTarget* aOwner,
                                  nsPresContext* aPresContext,
                                  InternalScrollAreaEvent* aEvent)
   : UIEvent(aOwner, aPresContext, aEvent)
-  , mClientArea(nullptr)
+  , mClientArea(new DOMRect(nullptr))
 {
-  mClientArea.SetLayoutRect(aEvent ? aEvent->mArea : nsRect());
+  mClientArea->SetLayoutRect(aEvent ? aEvent->mArea : nsRect());
 }
 
 NS_IMPL_ADDREF_INHERITED(ScrollAreaEvent, UIEvent)
 NS_IMPL_RELEASE_INHERITED(ScrollAreaEvent, UIEvent)
 
 NS_INTERFACE_MAP_BEGIN(ScrollAreaEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMScrollAreaEvent)
 NS_INTERFACE_MAP_END_INHERITING(UIEvent)
@@ -52,17 +52,17 @@ ScrollAreaEvent::InitScrollAreaEvent(con
                                      float aY,
                                      float aWidth,
                                      float aHeight)
 {
   nsresult rv =
     UIEvent::InitUIEvent(aEventType, aCanBubble, aCancelable, aView, aDetail);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mClientArea.SetRect(aX, aY, aWidth, aHeight);
+  mClientArea->SetRect(aX, aY, aWidth, aHeight);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP_(void)
 ScrollAreaEvent::Serialize(IPC::Message* aMsg,
                            bool aSerializeInterfaceType)
 {
@@ -83,17 +83,17 @@ ScrollAreaEvent::Deserialize(const IPC::
 {
   NS_ENSURE_TRUE(Event::Deserialize(aMsg, aIter), false);
 
   float x, y, width, height;
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &x), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &y), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &width), false);
   NS_ENSURE_TRUE(IPC::ReadParam(aMsg, aIter, &height), false);
-  mClientArea.SetRect(x, y, width, height);
+  mClientArea->SetRect(x, y, width, height);
 
   return true;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 using namespace mozilla;
--- a/dom/events/ScrollAreaEvent.h
+++ b/dom/events/ScrollAreaEvent.h
@@ -40,32 +40,32 @@ public:
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE
   {
     return ScrollAreaEventBinding::Wrap(aCx, this);
   }
 
   float X() const
   {
-    return mClientArea.Left();
+    return mClientArea->Left();
   }
 
   float Y() const
   {
-    return mClientArea.Top();
+    return mClientArea->Top();
   }
 
   float Width() const
   {
-    return mClientArea.Width();
+    return mClientArea->Width();
   }
 
   float Height() const
   {
-    return mClientArea.Height();
+    return mClientArea->Height();
   }
 
   void InitScrollAreaEvent(const nsAString& aType,
                            bool aCanBubble,
                            bool aCancelable,
                            nsIDOMWindow* aView,
                            int32_t aDetail,
                            float aX, float aY,
@@ -74,15 +74,15 @@ public:
   {
     aRv = InitScrollAreaEvent(aType, aCanBubble, aCancelable, aView,
                               aDetail, aX, aY, aWidth, aHeight);
   }
 
 protected:
   ~ScrollAreaEvent() {}
 
-  DOMRect mClientArea;
+  nsRefPtr<DOMRect> mClientArea;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_ScrollAreaEvent_h_
--- a/dom/interfaces/base/nsIServiceWorkerManager.idl
+++ b/dom/interfaces/base/nsIServiceWorkerManager.idl
@@ -3,17 +3,17 @@
  * 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 "domstubs.idl"
 
 interface nsIDocument;
 interface nsIURI;
 
-[uuid(91b9d3fc-1654-44da-b438-15123cdbe7aa)]
+[uuid(8d2f64db-5585-4876-a1c9-391e16549068)]
 interface nsIServiceWorkerManager : nsISupports
 {
   /**
    * Registers a ServiceWorker with script loaded from `aScriptURI` to act as
    * the ServiceWorker for aScope.  Requires a valid entry settings object on
    * the stack. This means you must call this from content code 'within'
    * a window.
    *
@@ -56,20 +56,29 @@ interface nsIServiceWorkerManager : nsIS
 
   /**
    * Documents that have called MaybeStartControlling() should call this when
    * they are destroyed. This function may be called multiple times, and is
    * idempotent.
    */
   [notxpcom,nostdcall] void MaybeStopControlling(in nsIDocument aDoc);
 
-  // Returns a ServiceWorker
-  [noscript] nsISupports GetInstalling(in nsIDOMWindow aWindow);
-  [noscript] nsISupports GetWaiting(in nsIDOMWindow aWindow);
-  [noscript] nsISupports GetActive(in nsIDOMWindow aWindow);
+  /*
+   * Returns a ServiceWorker.
+   * window is the window of the caller. scope is the registration's scope and must be
+   * a valid entry that window is allowed to load, otherwise this will return nullptr.
+   * These are only meant to be called from ServiceWorkerRegistration instances.
+   */
+  [noscript] nsISupports GetInstalling(in nsIDOMWindow aWindow, in DOMString aScope);
+  [noscript] nsISupports GetWaiting(in nsIDOMWindow aWindow, in DOMString aScope);
+  [noscript] nsISupports GetActive(in nsIDOMWindow aWindow, in DOMString aScope);
+
+  /*
+   * Returns a ServiceWorker.
+   */
   [noscript] nsISupports GetDocumentController(in nsIDOMWindow aWindow);
 
   // Testing
   DOMString getScopeForUrl(in DOMString path);
 };
 
 %{ C++
 #define SERVICEWORKERMANAGER_CONTRACTID "@mozilla.org/serviceworkers/manager;1"
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -149,16 +149,21 @@
 #include "AudioChannelService.h"
 #include "JavaScriptChild.h"
 #include "mozilla/dom/DataStoreService.h"
 #include "mozilla/dom/telephony/PTelephonyChild.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/net/NeckoMessageUtils.h"
 #include "mozilla/RemoteSpellCheckEngineChild.h"
 
+#ifdef MOZ_B2G_RIL
+#include "mozilla/dom/mobileconnection/MobileConnectionChild.h"
+using namespace mozilla::dom::mobileconnection;
+#endif
+
 using namespace base;
 using namespace mozilla;
 using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::indexedDB;
@@ -1217,16 +1222,53 @@ ContentChild::DeallocPFileSystemRequestC
     mozilla::dom::FileSystemTaskBase* child =
       static_cast<mozilla::dom::FileSystemTaskBase*>(aFileSystem);
     // The reference is increased in FileSystemTaskBase::Start of
     // FileSystemTaskBase.cpp. We should decrease it after IPC.
     NS_RELEASE(child);
     return true;
 }
 
+PMobileConnectionChild*
+ContentChild::SendPMobileConnectionConstructor(PMobileConnectionChild* aActor,
+                                               const uint32_t& aClientId)
+{
+#ifdef MOZ_B2G_RIL
+    // Add an extra ref for IPDL. Will be released in
+    // ContentChild::DeallocPMobileConnectionChild().
+    static_cast<MobileConnectionChild*>(aActor)->AddRef();
+    return PContentChild::SendPMobileConnectionConstructor(aActor, aClientId);
+#else
+    MOZ_CRASH("No support for mobileconnection on this platform!");;
+#endif
+}
+
+PMobileConnectionChild*
+ContentChild::AllocPMobileConnectionChild(const uint32_t& aClientId)
+{
+#ifdef MOZ_B2G_RIL
+    NS_NOTREACHED("No one should be allocating PMobileConnectionChild actors");
+    return nullptr;
+#else
+    MOZ_CRASH("No support for mobileconnection on this platform!");;
+#endif
+}
+
+bool
+ContentChild::DeallocPMobileConnectionChild(PMobileConnectionChild* aActor)
+{
+#ifdef MOZ_B2G_RIL
+    // MobileConnectionChild is refcounted, must not be freed manually.
+    static_cast<MobileConnectionChild*>(aActor)->Release();
+    return true;
+#else
+    MOZ_CRASH("No support for mobileconnection on this platform!");
+#endif
+}
+
 PNeckoChild*
 ContentChild::AllocPNeckoChild()
 {
     return new NeckoChild();
 }
 
 bool
 ContentChild::DeallocPNeckoChild(PNeckoChild* necko)
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -186,16 +186,24 @@ public:
     RecvDataStoreNotify(const uint32_t& aAppId, const nsString& aName,
                         const nsString& aManifestURL) MOZ_OVERRIDE;
 
     virtual PTestShellChild* AllocPTestShellChild() MOZ_OVERRIDE;
     virtual bool DeallocPTestShellChild(PTestShellChild*) MOZ_OVERRIDE;
     virtual bool RecvPTestShellConstructor(PTestShellChild*) MOZ_OVERRIDE;
     jsipc::JavaScriptChild *GetCPOWManager();
 
+    PMobileConnectionChild*
+    SendPMobileConnectionConstructor(PMobileConnectionChild* aActor,
+                                     const uint32_t& aClientId);
+    virtual PMobileConnectionChild*
+    AllocPMobileConnectionChild(const uint32_t& aClientId) MOZ_OVERRIDE;
+    virtual bool
+    DeallocPMobileConnectionChild(PMobileConnectionChild* aActor) MOZ_OVERRIDE;
+
     virtual PNeckoChild* AllocPNeckoChild() MOZ_OVERRIDE;
     virtual bool DeallocPNeckoChild(PNeckoChild*) MOZ_OVERRIDE;
 
     virtual PScreenManagerChild*
     AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
                              float* aSystemDefaultScale,
                              bool* aSuccess) MOZ_OVERRIDE;
     virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) MOZ_OVERRIDE;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -172,16 +172,21 @@ using namespace mozilla::system;
 #endif
 
 #ifdef ENABLE_TESTS
 #include "BackgroundChildImpl.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "nsIIPCBackgroundChildCreateCallback.h"
 #endif
 
+#ifdef MOZ_B2G_RIL
+#include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
+using namespace mozilla::dom::mobileconnection;
+#endif
+
 #if defined(MOZ_CONTENT_SANDBOX) && defined(XP_LINUX)
 #include "mozilla/Sandbox.h"
 #endif
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 static const char* sClipboardTextFlavors[] = { kUnicodeMime };
 
 using base::ChildPrivileges;
@@ -3089,16 +3094,42 @@ ContentParent::AllocPTestShellParent()
 
 bool
 ContentParent::DeallocPTestShellParent(PTestShellParent* shell)
 {
     delete shell;
     return true;
 }
 
+PMobileConnectionParent*
+ContentParent::AllocPMobileConnectionParent(const uint32_t& aClientId)
+{
+#ifdef MOZ_B2G_RIL
+    nsRefPtr<MobileConnectionParent> parent = new MobileConnectionParent(aClientId);
+    // We release this ref in DeallocPMobileConnectionParent().
+    parent->AddRef();
+
+    return parent;
+#else
+    MOZ_CRASH("No support for mobileconnection on this platform!");
+#endif
+}
+
+bool
+ContentParent::DeallocPMobileConnectionParent(PMobileConnectionParent* aActor)
+{
+#ifdef MOZ_B2G_RIL
+    // MobileConnectionParent is refcounted, must not be freed manually.
+    static_cast<MobileConnectionParent*>(aActor)->Release();
+    return true;
+#else
+    MOZ_CRASH("No support for mobileconnection on this platform!");
+#endif
+}
+
 PNeckoParent*
 ContentParent::AllocPNeckoParent()
 {
     return new NeckoParent();
 }
 
 bool
 ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -458,16 +458,19 @@ private:
                                      const FileDescriptor& aGCLog,
                                      const FileDescriptor& aCCLog) MOZ_OVERRIDE;
     virtual bool
     DeallocPCycleCollectWithLogsParent(PCycleCollectWithLogsParent* aActor) MOZ_OVERRIDE;
 
     virtual PTestShellParent* AllocPTestShellParent() MOZ_OVERRIDE;
     virtual bool DeallocPTestShellParent(PTestShellParent* shell) MOZ_OVERRIDE;
 
+    virtual PMobileConnectionParent* AllocPMobileConnectionParent(const uint32_t& aClientId) MOZ_OVERRIDE;
+    virtual bool DeallocPMobileConnectionParent(PMobileConnectionParent* aActor) MOZ_OVERRIDE;
+
     virtual bool DeallocPNeckoParent(PNeckoParent* necko) MOZ_OVERRIDE;
 
     virtual PExternalHelperAppParent* AllocPExternalHelperAppParent(
             const OptionalURIParams& aUri,
             const nsCString& aMimeContentType,
             const nsCString& aContentDisposition,
             const uint32_t& aContentDispositionHint,
             const nsString& aContentDispositionFilename, 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -17,16 +17,17 @@ include protocol PExternalHelperApp;
 include protocol PDeviceStorageRequest;
 include protocol PFileDescriptorSet;
 include protocol PFMRadio;
 include protocol PFileSystemRequest;
 include protocol PHal;
 include protocol PImageBridge;
 include protocol PIndexedDB;
 include protocol PMemoryReportRequest;
+include protocol PMobileConnection;
 include protocol PNecko;
 include protocol PScreenManager;
 include protocol PSharedBufferManager;
 include protocol PSms;
 include protocol PSpeechSynthesis;
 include protocol PStorage;
 include protocol PTelephony;
 include protocol PTestShell;
@@ -305,16 +306,17 @@ intr protocol PContent
     manages PDeviceStorageRequest;
     manages PFileSystemRequest;
     manages PExternalHelperApp;
     manages PFileDescriptorSet;
     manages PFMRadio;
     manages PHal;
     manages PIndexedDB;
     manages PMemoryReportRequest;
+    manages PMobileConnection;
     manages PNecko;
     manages PScreenManager;
     manages PSms;
     manages PSpeechSynthesis;
     manages PStorage;
     manages PTelephony;
     manages PTestShell;
     manages PJavaScript;
@@ -493,16 +495,18 @@ parent:
 
     sync IsSecureURI(uint32_t type, URIParams uri, uint32_t flags)
         returns (bool isSecureURI);
 
     PHal();
 
     PIndexedDB();
 
+    PMobileConnection(uint32_t clientId);
+
     PNecko();
 
     rpc PScreenManager()
         returns (uint32_t numberOfScreens,
                  float systemDefaultScale,
                  bool success);
 
     PSms();
--- a/dom/mobileconnection/DOMMMIError.cpp
+++ b/dom/mobileconnection/DOMMMIError.cpp
@@ -1,13 +1,13 @@
 /* -*- Mode: C++; 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/. */
+ * 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 "DOMMMIError.h"
 #include "mozilla/dom/DOMMMIErrorBinding.h"
 
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(DOMMMIError)
 
@@ -32,24 +32,8 @@ DOMMMIError::DOMMMIError(nsPIDOMWindow* 
 {
 }
 
 JSObject*
 DOMMMIError::WrapObject(JSContext* aCx)
 {
   return DOMMMIErrorBinding::Wrap(aCx, this);
 }
-
-// WebIDL interface
-
-/* static */ already_AddRefed<DOMMMIError>
-DOMMMIError::Constructor(const GlobalObject& aGlobal,
-                         const nsAString& aServiceCode,
-                         const nsAString& aName,
-                         const nsAString& aMessage,
-                         const Nullable<int16_t>& aInfo,
-                         ErrorResult& aRv) {
-  nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.GetAsSupports());
-  nsRefPtr<DOMMMIError> error = new DOMMMIError(window, aName, aMessage,
-                                                aServiceCode, aInfo);
-
-  return error.forget();
-}
--- a/dom/mobileconnection/DOMMMIError.h
+++ b/dom/mobileconnection/DOMMMIError.h
@@ -1,13 +1,13 @@
 /* -*- Mode: C++; 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/. */
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_MmiError_h
 #define mozilla_dom_MmiError_h
 
 #include "mozilla/dom/DOMError.h"
 
 namespace mozilla {
 namespace dom {
@@ -21,20 +21,16 @@ public:
   DOMMMIError(nsPIDOMWindow* aWindow, const nsAString& aName,
               const nsAString& aMessage, const nsAString& aServiceCode,
               const Nullable<int16_t>& aInfo);
 
   virtual JSObject*
   WrapObject(JSContext* aCx) MOZ_OVERRIDE;
 
   // WebIDL interface
-  static already_AddRefed<DOMMMIError>
-  Constructor(const GlobalObject& aGlobal, const nsAString& aServiceCode,
-              const nsAString& aName, const nsAString& aMessage,
-              const Nullable<int16_t>& aInfo, ErrorResult& aRv);
 
   void
   GetServiceCode(nsString& aServiceCode) const
   {
     aServiceCode = mServiceCode;
   }
 
   Nullable<int16_t>
--- a/dom/mobileconnection/MobileCellInfo.cpp
+++ b/dom/mobileconnection/MobileCellInfo.cpp
@@ -12,31 +12,53 @@ using namespace mozilla::dom;
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(MobileCellInfo, mWindow)
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(MobileCellInfo)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(MobileCellInfo)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MobileCellInfo)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
+  NS_INTERFACE_MAP_ENTRY(nsIMobileCellInfo)
 NS_INTERFACE_MAP_END
 
 MobileCellInfo::MobileCellInfo(nsPIDOMWindow* aWindow)
   : mWindow(aWindow)
   , mGsmLocationAreaCode(-1)
   , mGsmCellId(-1)
   , mCdmaBaseStationId(-1)
   , mCdmaBaseStationLatitude(-1)
   , mCdmaBaseStationLongitude(-1)
   , mCdmaSystemId(-1)
   , mCdmaNetworkId(-1)
 {
   SetIsDOMBinding();
 }
 
+MobileCellInfo::MobileCellInfo(int32_t aGsmLocationAreaCode,
+                               int64_t aGsmCellId,
+                               int32_t aCdmaBaseStationId,
+                               int32_t aCdmaBaseStationLatitude,
+                               int32_t aCdmaBaseStationLongitude,
+                               int32_t aCdmaSystemId,
+                               int32_t aCdmaNetworkId)
+  : mGsmLocationAreaCode(aGsmLocationAreaCode)
+  , mGsmCellId(aGsmCellId)
+  , mCdmaBaseStationId(aCdmaBaseStationId)
+  , mCdmaBaseStationLatitude(aCdmaBaseStationLatitude)
+  , mCdmaBaseStationLongitude(aCdmaBaseStationLongitude)
+  , mCdmaSystemId(aCdmaSystemId)
+  , mCdmaNetworkId(aCdmaNetworkId)
+{
+  // The instance created by this way is only used for IPC stuff. It won't be
+  // expose to JS directly, we will clone this instance to the one that is
+  // maintained in MobileConnectionChild. So we don't need SetIsDOMBinding()
+  // here.
+}
+
 void
 MobileCellInfo::Update(nsIMobileCellInfo* aInfo)
 {
   if (!aInfo) {
     return;
   }
 
   aInfo->GetGsmLocationAreaCode(&mGsmLocationAreaCode);
@@ -46,10 +68,62 @@ MobileCellInfo::Update(nsIMobileCellInfo
   aInfo->GetCdmaBaseStationLongitude(&mCdmaBaseStationLongitude);
   aInfo->GetCdmaSystemId(&mCdmaSystemId);
   aInfo->GetCdmaNetworkId(&mCdmaNetworkId);
 }
 
 JSObject*
 MobileCellInfo::WrapObject(JSContext* aCx)
 {
+  MOZ_ASSERT(IsDOMBinding());
   return MozMobileCellInfoBinding::Wrap(aCx, this);
 }
+
+// nsIMobileCellInfo
+
+NS_IMETHODIMP
+MobileCellInfo::GetGsmLocationAreaCode(int32_t* aGsmLocationAreaCode)
+{
+  *aGsmLocationAreaCode = GsmLocationAreaCode();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCellInfo::GetGsmCellId(int64_t* aGsmCellId)
+{
+  *aGsmCellId = GsmCellId();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCellInfo::GetCdmaBaseStationId(int32_t* aCdmaBaseStationId)
+{
+  *aCdmaBaseStationId = CdmaBaseStationId();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCellInfo::GetCdmaBaseStationLatitude(int32_t* aCdmaBaseStationLatitude)
+{
+  *aCdmaBaseStationLatitude = CdmaBaseStationLatitude();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCellInfo::GetCdmaBaseStationLongitude(int32_t* aCdmaBaseStationLongitude)
+{
+  *aCdmaBaseStationLongitude = CdmaBaseStationLongitude();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCellInfo::GetCdmaSystemId(int32_t* aCdmaSystemId)
+{
+  *aCdmaSystemId = CdmaSystemId();
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MobileCellInfo::GetCdmaNetworkId(int32_t* aCdmaNetworkId)
+{
+  *aCdmaNetworkId = CdmaNetworkId();
+  return NS_OK;
+}
--- a/dom/mobileconnection/MobileCellInfo.h
+++ b/dom/mobileconnection/MobileCellInfo.h
@@ -9,25 +9,31 @@
 
 #include "nsIMobileCellInfo.h"
 #include "nsPIDOMWindow.h"
 #include "nsWrapperCache.h"
 
 namespace mozilla {
 namespace dom {
 
-class MobileCellInfo MOZ_FINAL : public nsISupports
+class MobileCellInfo MOZ_FINAL : public nsIMobileCellInfo
                                , public nsWrapperCache
 {
 public:
+  NS_DECL_NSIMOBILECELLINFO
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MobileCellInfo)
 
   MobileCellInfo(nsPIDOMWindow* aWindow);
 
+  MobileCellInfo(int32_t aGsmLocationAreaCode, int64_t aGsmCellId,
+                 int32_t aCdmaBaseStationId, int32_t aCdmaBaseStationLatitude,
+                 int32_t aCdmaBaseStationLongitude, int32_t aCdmaSystemId,
+                 int32_t aCdmaNetworkId);
+
   void
   Update(nsIMobileCellInfo* aInfo);
 
   nsPIDOMWindow*
   GetParentObject() const
   {
     return mWindow;
   }
--- a/dom/mobileconnection/MobileConnection.cpp
+++ b/dom/mobileconnection/MobileConnection.cpp
@@ -1,32 +1,31 @@
 /* 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 "MobileConnection.h"
 
+#include "MobileConnectionCallback.h"
 #include "mozilla/dom/CFStateChangeEvent.h"
 #include "mozilla/dom/DataErrorEvent.h"
 #include "mozilla/dom/MozClirModeEvent.h"
 #include "mozilla/dom/MozEmergencyCbModeEvent.h"
 #include "mozilla/dom/MozOtaStatusEvent.h"
 #include "mozilla/dom/ToJSValue.h"
 #include "mozilla/dom/USSDReceivedEvent.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "nsIDOMDOMRequest.h"
 #include "nsIPermissionManager.h"
 #include "nsIVariant.h"
 #include "nsJSON.h"
 #include "nsJSUtils.h"
 #include "nsServiceManagerUtils.h"
 
-#define NS_RILCONTENTHELPER_CONTRACTID "@mozilla.org/ril/content-helper;1"
-
 #define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum)      \
 {                                                                       \
   uint32_t i = 0;                                                       \
   for (const EnumEntry* entry = _enumType##Values::strings;             \
        entry->value;                                                    \
        ++entry, ++i) {                                                  \
     if (_string.EqualsASCII(entry->value)) {                            \
       _enum.SetValue(static_cast<_enumType>(i));                        \
@@ -36,16 +35,17 @@
 
 #define CONVERT_ENUM_TO_STRING(_enumType, _enum, _string)               \
 {                                                                       \
   uint32_t index = uint32_t(_enum);                                     \
   _string.AssignASCII(_enumType##Values::strings[index].value,          \
                       _enumType##Values::strings[index].length);        \
 }
 
+using mozilla::ErrorResult;
 using namespace mozilla::dom;
 
 class MobileConnection::Listener MOZ_FINAL : public nsIMobileConnectionListener
 {
   MobileConnection* mMobileConnection;
 
 public:
   NS_DECL_ISUPPORTS
@@ -72,17 +72,17 @@ private:
 
 NS_IMPL_ISUPPORTS(MobileConnection::Listener, nsIMobileConnectionListener)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MobileConnection,
                                                   DOMEventTargetHelper)
   // Don't traverse mListener because it doesn't keep any reference to
-  // MobileConnection but a raw pointer instead. Neither does mProvider because
+  // MobileConnection but a raw pointer instead. Neither does mService because
   // it's an xpcom service and is only released at shutting down.
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVoice)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mData)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MobileConnection,
                                                 DOMEventTargetHelper)
   tmp->Shutdown();
@@ -100,44 +100,44 @@ NS_IMPL_ADDREF_INHERITED(MobileConnectio
 NS_IMPL_RELEASE_INHERITED(MobileConnection, DOMEventTargetHelper)
 
 MobileConnection::MobileConnection(nsPIDOMWindow* aWindow, uint32_t aClientId)
   : DOMEventTargetHelper(aWindow)
   , mClientId(aClientId)
 {
   SetIsDOMBinding();
 
-  mProvider = do_GetService(NS_RILCONTENTHELPER_CONTRACTID);
+  mService = do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
 
-  // Not being able to acquire the provider isn't fatal since we check
+  // Not being able to acquire the service isn't fatal since we check
   // for it explicitly below.
-  if (!mProvider) {
-    NS_WARNING("Could not acquire nsIMobileConnectionProvider!");
+  if (!mService) {
+    NS_WARNING("Could not acquire nsIMobileConnectionService!");
     return;
   }
 
   mListener = new Listener(this);
   mVoice = new MobileConnectionInfo(GetOwner());
   mData = new MobileConnectionInfo(GetOwner());
 
   if (CheckPermission("mobileconnection")) {
-    DebugOnly<nsresult> rv = mProvider->RegisterMobileConnectionMsg(mClientId, mListener);
+    DebugOnly<nsresult> rv = mService->RegisterListener(mClientId, mListener);
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
-                     "Failed registering mobile connection messages with provider");
+                     "Failed registering mobile connection messages with service");
     UpdateVoice();
     UpdateData();
   }
 }
 
 void
 MobileConnection::Shutdown()
 {
   if (mListener) {
-    if (mProvider) {
-      mProvider->UnregisterMobileConnectionMsg(mClientId, mListener);
+    if (mService) {
+      mService->UnregisterListener(mClientId, mListener);
     }
 
     mListener->Disconnect();
     mListener = nullptr;
   }
 }
 
 MobileConnection::~MobileConnection()
@@ -170,61 +170,61 @@ MobileConnection::CheckPermission(const 
   uint32_t permission = nsIPermissionManager::DENY_ACTION;
   permMgr->TestPermissionFromWindow(GetOwner(), aType, &permission);
   return permission == nsIPermissionManager::ALLOW_ACTION;
 }
 
 void
 MobileConnection::UpdateVoice()
 {
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
   nsCOMPtr<nsIMobileConnectionInfo> info;
-  mProvider->GetVoiceConnectionInfo(mClientId, getter_AddRefs(info));
+  mService->GetVoiceConnectionInfo(mClientId, getter_AddRefs(info));
   mVoice->Update(info);
 }
 
 void
 MobileConnection::UpdateData()
 {
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
   nsCOMPtr<nsIMobileConnectionInfo> info;
-  mProvider->GetDataConnectionInfo(mClientId, getter_AddRefs(info));
+  mService->GetDataConnectionInfo(mClientId, getter_AddRefs(info));
   mData->Update(info);
 }
 
 // WebIDL interface
 
 void
 MobileConnection::GetLastKnownNetwork(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
-  mProvider->GetLastKnownNetwork(mClientId, aRetVal);
+  mService->GetLastKnownNetwork(mClientId, aRetVal);
 }
 
 void
 MobileConnection::GetLastKnownHomeNetwork(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
-  mProvider->GetLastKnownHomeNetwork(mClientId, aRetVal);
+  mService->GetLastKnownHomeNetwork(mClientId, aRetVal);
 }
 
 // All fields below require the "mobileconnection" permission.
 
 MobileConnectionInfo*
 MobileConnection::Voice() const
 {
   return mVoice;
@@ -236,66 +236,66 @@ MobileConnection::Data() const
   return mData;
 }
 
 void
 MobileConnection::GetIccId(nsString& aRetVal) const
 {
   aRetVal.SetIsVoid(true);
 
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
-  mProvider->GetIccId(mClientId, aRetVal);
+  mService->GetIccId(mClientId, aRetVal);
 }
 
 Nullable<MobileNetworkSelectionMode>
 MobileConnection::GetNetworkSelectionMode() const
 {
   Nullable<MobileNetworkSelectionMode> retVal =
     Nullable<MobileNetworkSelectionMode>();
 
-  if (!mProvider) {
+  if (!mService) {
     return retVal;
   }
 
   nsAutoString mode;
-  mProvider->GetNetworkSelectionMode(mClientId, mode);
+  mService->GetNetworkSelectionMode(mClientId, mode);
   CONVERT_STRING_TO_NULLABLE_ENUM(mode, MobileNetworkSelectionMode, retVal);
 
   return retVal;
 }
 
 Nullable<MobileRadioState>
 MobileConnection::GetRadioState() const
 {
   Nullable<MobileRadioState> retVal = Nullable<MobileRadioState>();
 
-  if (!mProvider) {
+  if (!mService) {
     return retVal;
   }
 
   nsAutoString state;
-  mProvider->GetRadioState(mClientId, state);
+  mService->GetRadioState(mClientId, state);
   CONVERT_STRING_TO_NULLABLE_ENUM(state, MobileRadioState, retVal);
 
   return retVal;
 }
 
 void
 MobileConnection::GetSupportedNetworkTypes(nsTArray<MobileNetworkType>& aTypes) const
 {
-  if (!mProvider) {
+  if (!mService) {
     return;
   }
 
   nsCOMPtr<nsIVariant> variant;
-  mProvider->GetSupportedNetworkTypes(mClientId,
-                                      getter_AddRefs(variant));
+  mService->GetSupportedNetworkTypes(mClientId,
+                                     getter_AddRefs(variant));
 
   uint16_t type;
   nsIID iid;
   uint32_t count;
   void* data;
 
   // Convert the nsIVariant to an array.  We own the resulting buffer and its
   // elements.
@@ -317,253 +317,281 @@ MobileConnection::GetSupportedNetworkTyp
     }
   }
   NS_Free(data);
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetNetworks(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetNetworks(mClientId, GetOwner(),
-                                       getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetNetworks(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SelectNetwork(MobileNetworkInfo& aNetwork, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SelectNetwork(mClientId, GetOwner(), &aNetwork,
-                                         getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SelectNetwork(mClientId, &aNetwork, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SelectNetworkAutomatically(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SelectNetworkAutomatically(mClientId, GetOwner(),
-                                                      getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SelectNetworkAutomatically(mClientId,
+                                                     requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetPreferredNetworkType(MobilePreferredNetworkType& aType,
                                           ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsAutoString type;
   CONVERT_ENUM_TO_STRING(MobilePreferredNetworkType, aType, type);
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetPreferredNetworkType(mClientId, GetOwner(), type,
-                                                   getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetPreferredNetworkType(mClientId, type,
+                                                  requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetPreferredNetworkType(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetPreferredNetworkType(mClientId, GetOwner(),
-                                                   getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetPreferredNetworkType(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetRoamingPreference(MobileRoamingMode& aMode,
                                        ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   nsAutoString mode;
   CONVERT_ENUM_TO_STRING(MobileRoamingMode, aMode, mode);
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetRoamingPreference(mClientId, GetOwner(), mode,
-                                                getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetRoamingPreference(mClientId, mode, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetRoamingPreference(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetRoamingPreference(mClientId, GetOwner(),
-                                                getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetRoamingPreference(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
+    return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetVoicePrivacyMode(bool aEnabled, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetVoicePrivacyMode(mClientId, GetOwner(), aEnabled,
-                                               getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetVoicePrivacyMode(mClientId, aEnabled,
+                                              requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetVoicePrivacyMode(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetVoicePrivacyMode(mClientId, GetOwner(),
-                                               getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetVoicePrivacyMode(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SendMMI(const nsAString& aMMIString, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SendMMI(mClientId, GetOwner(), aMMIString,
-                                   getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SendMMI(mClientId, aMMIString, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::CancelMMI(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->CancelMMI(mClientId, GetOwner(),
-                                     getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->CancelMMI(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallForwardingOption(uint16_t aReason, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallForwarding(mClientId, GetOwner(), aReason,
-                                             getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallForwarding(mClientId, aReason, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallForwardingOption(const MozCallForwardingOptions& aOptions,
                                           ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -571,32 +599,34 @@ MobileConnection::SetCallForwardingOptio
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallForwarding(mClientId, GetOwner(), options,
-                                             getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallForwarding(mClientId, options, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallBarringOption(const MozCallBarringOptions& aOptions,
                                        ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -604,32 +634,34 @@ MobileConnection::GetCallBarringOption(c
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallBarring(mClientId, GetOwner(), options,
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallBarring(mClientId, options, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallBarringOption(const MozCallBarringOptions& aOptions,
                                        ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -637,32 +669,34 @@ MobileConnection::SetCallBarringOption(c
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallBarring(mClientId, GetOwner(), options,
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallBarring(mClientId, options, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::ChangeCallBarringPassword(const MozCallBarringOptions& aOptions,
                                             ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
   AutoJSAPI jsapi;
   if (!NS_WARN_IF(jsapi.Init(GetOwner()))) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
@@ -670,144 +704,157 @@ MobileConnection::ChangeCallBarringPassw
 
   JSContext *cx = jsapi.cx();
   JS::Rooted<JS::Value> options(cx);
   if (!ToJSValue(cx, aOptions, &options)) {
     aRv.Throw(NS_ERROR_TYPE_ERR);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->ChangeCallBarringPassword(mClientId,
-                                                     GetOwner(),
-                                                     options,
-                                                     getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->ChangeCallBarringPassword(mClientId, options,
+                                                    requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallWaitingOption(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallWaiting(mClientId, GetOwner(),
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallWaiting(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallWaitingOption(bool aEnabled, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallWaiting(mClientId, GetOwner(), aEnabled,
-                                          getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallWaiting(mClientId, aEnabled, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::GetCallingLineIdRestriction(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->GetCallingLineIdRestriction(mClientId, GetOwner(),
-                                                       getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->GetCallingLineIdRestriction(mClientId,
+                                                      requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetCallingLineIdRestriction(uint16_t aMode,
                                               ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetCallingLineIdRestriction(mClientId,
-                                                       GetOwner(),
-                                                       aMode,
-                                                       getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetCallingLineIdRestriction(mClientId, aMode,
+                                                      requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::ExitEmergencyCbMode(ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->ExitEmergencyCbMode(mClientId, GetOwner(),
-                                               getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->ExitEmergencyCbMode(mClientId, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 already_AddRefed<DOMRequest>
 MobileConnection::SetRadioEnabled(bool aEnabled, ErrorResult& aRv)
 {
-  if (!mProvider) {
+  if (!mService) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  nsCOMPtr<nsIDOMDOMRequest> request;
-  nsresult rv = mProvider->SetRadioEnabled(mClientId, GetOwner(), aEnabled,
-                                           getter_AddRefs(request));
+  nsRefPtr<DOMRequest> request = new DOMRequest(GetOwner());
+  nsRefPtr<MobileConnectionCallback> requestCallback =
+    new MobileConnectionCallback(GetOwner(), request);
+
+  nsresult rv = mService->SetRadioEnabled(mClientId, aEnabled, requestCallback);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return nullptr;
   }
 
-  return request.forget().downcast<DOMRequest>();
+  return request.forget();
 }
 
 // nsIMobileConnectionListener
 
 NS_IMETHODIMP
 MobileConnection::NotifyVoiceChanged()
 {
   if (!CheckPermission("mobileconnection")) {
@@ -865,22 +912,22 @@ MobileConnection::NotifyDataError(const 
 
   nsRefPtr<DataErrorEvent> event =
     DataErrorEvent::Constructor(this, NS_LITERAL_STRING("dataerror"), init);
 
   return DispatchTrustedEvent(event);
 }
 
 NS_IMETHODIMP
-MobileConnection::NotifyCFStateChange(bool aSuccess,
-                                      unsigned short aAction,
-                                      unsigned short aReason,
-                                      const nsAString& aNumber,
-                                      unsigned short aSeconds,
-                                      unsigned short aServiceClass)
+MobileConnection::NotifyCFStateChanged(bool aSuccess,
+                                       unsigned short aAction,
+                                       unsigned short aReason,
+                                       const nsAString& aNumber,
+                                       unsigned short aSeconds,
+                                       unsigned short aServiceClass)
 {
   if (!CheckPermission("mobileconnection")) {
     return NS_OK;
   }
 
   C