From ae6214cb514623ac4bff6577824729008e055c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Pag=C3=A8s?= Date: Thu, 18 Dec 2014 11:53:14 -0500 Subject: [PATCH 001/183] Bug 794984 - [mozprocess] Add ability to separate stderr from stdout, r=ahal A new parameter called 'processStderrLine' is added. When specified, stdout gets processed by the 'processOutputLine' callbacks and stderr is processed by the 'processStderrLine' callbacks. When not specified, stderr is redirected to stdout which is the same default behaviour. A side effect of this is that mozprocess now uses three threads to process output. One thread each for stdout and stderr that reads output lines and stores them in a Queue as fast as possible, this makes sure there is no blocking in stdout.write(). A third thread executes the callbacks. --HG-- extra : rebase_source : d4601a6ae21ca61bfdca308c68155ce2c2e09e43 --- .../mozprocess/mozprocess/processhandler.py | 304 +++++++++--------- testing/mozbase/mozprocess/tests/manifest.ini | 1 + .../mozprocess/tests/test_process_reader.py | 95 ++++++ 3 files changed, 245 insertions(+), 155 deletions(-) create mode 100644 testing/mozbase/mozprocess/tests/test_process_reader.py diff --git a/testing/mozbase/mozprocess/mozprocess/processhandler.py b/testing/mozbase/mozprocess/mozprocess/processhandler.py index 65f6e5177437..2aa64c4246de 100644 --- a/testing/mozbase/mozprocess/mozprocess/processhandler.py +++ b/testing/mozbase/mozprocess/mozprocess/processhandler.py @@ -11,7 +11,7 @@ import sys import threading import time import traceback -from Queue import Queue +from Queue import Queue, Empty from datetime import datetime __all__ = ['ProcessHandlerMixin', 'ProcessHandler'] @@ -40,7 +40,13 @@ class ProcessHandlerMixin(object): :param env: is the environment to use for the process (defaults to os.environ). :param ignore_children: causes system to ignore child processes when True, defaults to False (which tracks child processes). :param kill_on_timeout: when True, the process will be killed when a timeout is reached. When False, the caller is responsible for killing the process. Failure to do so could cause a call to wait() to hang indefinitely. (Defaults to True.) - :param processOutputLine: function or list of functions to be called for each line of output produced by the process (defaults to None). + :param processOutputLine: function or list of functions to be called for + each line of output produced by the process (defaults to an empty + list). + :param processStderrLine: function or list of functions to be called + for each line of error output - stderr - produced by the process + (defaults to an empty list). If this is not specified, stderr lines + will be sent to the *processOutputLine* callbacks. :param onTimeout: function or list of functions to be called when the process times out. :param onFinish: function or list of functions to be called when the process terminates normally without timing out. :param kwargs: additional keyword args to pass directly into Popen. @@ -594,6 +600,7 @@ falling back to not using job objects for managing child processes""" ignore_children = False, kill_on_timeout = True, processOutputLine=(), + processStderrLine=(), onTimeout=(), onFinish=(), **kwargs): @@ -602,9 +609,7 @@ falling back to not using job objects for managing child processes""" self.cwd = cwd self.didTimeout = False self._ignore_children = ignore_children - self._kill_on_timeout = kill_on_timeout self.keywordargs = kwargs - self.outThread = None self.read_buffer = '' if env is None: @@ -612,15 +617,29 @@ falling back to not using job objects for managing child processes""" self.env = env # handlers - if callable(processOutputLine): - processOutputLine = [processOutputLine] - self.processOutputLineHandlers = list(processOutputLine) - if callable(onTimeout): - onTimeout = [onTimeout] - self.onTimeoutHandlers = list(onTimeout) - if callable(onFinish): - onFinish = [onFinish] - self.onFinishHandlers = list(onFinish) + def to_callable_list(arg): + if callable(arg): + arg = [arg] + return CallableList(arg) + + processOutputLine = to_callable_list(processOutputLine) + processStderrLine = to_callable_list(processStderrLine) + onTimeout = to_callable_list(onTimeout) + onFinish = to_callable_list(onFinish) + + def on_timeout(): + self.didTimeout = True + if kill_on_timeout: + self.kill() + onTimeout.insert(0, on_timeout) + + self._stderr = subprocess.STDOUT + if processStderrLine: + self._stderr = subprocess.PIPE + self.reader = ProcessReader(stdout_callback=processOutputLine, + stderr_callback=processStderrLine, + finished_callback=onFinish, + timeout_callback=onTimeout) # It is common for people to pass in the entire array with the cmd and # the args together since this is how Popen uses it. Allow for that. @@ -654,11 +673,10 @@ falling back to not using job objects for managing child processes""" being killed. """ self.didTimeout = False - self.startTime = datetime.now() # default arguments args = dict(stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, + stderr=self._stderr, cwd=self.cwd, env=self.env, ignore_children=self._ignore_children) @@ -690,7 +708,7 @@ falling back to not using job objects for managing child processes""" self.proc.kill(sig=sig) # When we kill the the managed process we also have to wait for the - # outThread to be finished. Otherwise consumers would have to assume + # reader thread to be finished. Otherwise consumers would have to assume # that it still has not completely shutdown. return self.wait() except AttributeError: @@ -700,36 +718,6 @@ falling back to not using job objects for managing child processes""" else: raise - def readWithTimeout(self, f, timeout): - """ - Try to read a line of output from the file object *f*. - - *f* must be a pipe, like the *stdout* member of a subprocess.Popen - object created with stdout=PIPE. If no output - is received within *timeout* seconds, return a blank line. - - Returns a tuple (line, did_timeout), where *did_timeout* is True - if the read timed out, and False otherwise. - """ - # Calls a private member because this is a different function based on - # the OS - return self._readWithTimeout(f, timeout) - - def processOutputLine(self, line): - """Called for each line of output that a process sends to stdout/stderr.""" - for handler in self.processOutputLineHandlers: - handler(line) - - def onTimeout(self): - """Called when a process times out.""" - for handler in self.onTimeoutHandlers: - handler() - - def onFinish(self): - """Called when a process finishes without a timeout.""" - for handler in self.onFinishHandlers: - handler() - def poll(self): """Check if child process has terminated @@ -739,10 +727,10 @@ falling back to not using job objects for managing child processes""" - '0' if the process ended without failures """ - # Ensure that we first check for the outputThread status. Otherwise + # Ensure that we first check for the reader status. Otherwise # we might mark the process as finished while output is still getting # processed. - if self.outThread and self.outThread.isAlive(): + if self.reader.is_alive(): return None elif hasattr(self.proc, "returncode"): return self.proc.returncode @@ -760,43 +748,15 @@ falling back to not using job objects for managing child processes""" for that number of seconds without producing any output before being killed. """ - def _processOutput(): - self.didTimeout = False - logsource = self.proc.stdout - - lineReadTimeout = None - if timeout: - lineReadTimeout = timeout - (datetime.now() - self.startTime).seconds - elif outputTimeout: - lineReadTimeout = outputTimeout - - (lines, self.didTimeout) = self.readWithTimeout(logsource, lineReadTimeout) - while lines != "": - for line in lines.splitlines(): - self.processOutputLine(line.rstrip()) - - if self.didTimeout: - break - - if timeout: - lineReadTimeout = timeout - (datetime.now() - self.startTime).seconds - (lines, self.didTimeout) = self.readWithTimeout(logsource, lineReadTimeout) - - if self.didTimeout: - if self._kill_on_timeout: - self.proc.kill() - self.onTimeout() - else: - self.onFinish() - + # this method is kept for backward compatibility if not hasattr(self, 'proc'): - self.run() - - if not self.outThread: - self.outThread = threading.Thread(target=_processOutput) - self.outThread.daemon = True - self.outThread.start() - + self.run(timeout=timeout, outputTimeout=outputTimeout) + # self.run will call this again + return + if not self.reader.is_alive(): + self.reader.timeout = timeout + self.reader.output_timeout = outputTimeout + self.reader.start(self.proc) def wait(self, timeout=None): """ @@ -813,12 +773,12 @@ falling back to not using job objects for managing child processes""" - '0' if the process ended without failures """ - if self.outThread and self.outThread is not threading.current_thread(): - # Thread.join() blocks the main thread until outThread is finished + if self.reader.thread and self.reader.thread is not threading.current_thread(): + # Thread.join() blocks the main thread until the reader thread is finished # wake up once a second in case a keyboard interrupt is sent count = 0 - while self.outThread.isAlive(): - self.outThread.join(timeout=1) + while self.reader.is_alive(): + self.reader.thread.join(timeout=1) count += 1 if timeout and count > timeout: return None @@ -832,77 +792,111 @@ falling back to not using job objects for managing child processes""" "use ProcessHandler.wait() instead" return self.wait(timeout=timeout) - - ### Private methods from here on down. Thar be dragons. - - if isWin: - # Windows Specific private functions are defined in this block - PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe - GetLastError = ctypes.windll.kernel32.GetLastError - - @staticmethod - def _normalize_newline(line): - # adb on windows returns \r\r\n at the end of each line, to get around - # this normalize all newlines to have a unix-style '\n' - # http://src.chromium.org/viewvc/chrome/trunk/src/build/android/pylib/android_commands.py#l1944 - return re.sub(r'\r+\n?$', '\n', line) - - def _readWithTimeout(self, f, timeout): - if timeout is None: - # shortcut to allow callers to pass in "None" for no timeout. - return (self._normalize_newline(f.readline()), False) - x = msvcrt.get_osfhandle(f.fileno()) - l = ctypes.c_long() - done = time.time() + timeout - while time.time() < done: - if self.PeekNamedPipe(x, None, 0, None, ctypes.byref(l), None) == 0: - err = self.GetLastError() - if err == 38 or err == 109: # ERROR_HANDLE_EOF || ERROR_BROKEN_PIPE - return ('', False) - else: - raise OSError("readWithTimeout got error: %d", err) - if l.value > 0: - # we're assuming that the output is line-buffered, - # which is not unreasonable - return (self._normalize_newline(f.readline()), False) - time.sleep(0.01) - return ('', True) - - else: - # Generic - def _readWithTimeout(self, f, timeout): - while True: - try: - (r, w, e) = select.select([f], [], [], timeout) - except: - # return a blank line - return ('', True) - - if len(r) == 0: - return ('', True) - - output = os.read(f.fileno(), 4096) - if not output: - output = self.read_buffer - self.read_buffer = '' - return (output, False) - self.read_buffer += output - if '\n' not in self.read_buffer: - time.sleep(0.01) - continue - tmp = self.read_buffer.split('\n') - lines, self.read_buffer = tmp[:-1], tmp[-1] - real_lines = [x for x in lines if x != ''] - if not real_lines: - time.sleep(0.01) - continue - break - return ('\n'.join(lines), False) - @property def pid(self): return self.proc.pid +class CallableList(list): + def __call__(self, *args, **kwargs): + for e in self: + e(*args, **kwargs) + + def __add__(self, lst): + return CallableList(list.__add__(self, lst)) + +class ProcessReader(object): + def __init__(self, stdout_callback=None, stderr_callback=None, + finished_callback=None, timeout_callback=None, + timeout=None, output_timeout=None): + self.stdout_callback = stdout_callback or (lambda line: True) + self.stderr_callback = stderr_callback or (lambda line: True) + self.finished_callback = finished_callback or (lambda: True) + self.timeout_callback = timeout_callback or (lambda: True) + self.timeout = timeout + self.output_timeout = output_timeout + self.thread = None + + def _create_stream_reader(self, name, stream, queue, callback): + thread = threading.Thread(name=name, + target=self._read_stream, + args=(stream, queue, callback)) + thread.daemon = True + thread.start() + return thread + + def _read_stream(self, stream, queue, callback): + for line in iter(stream.readline, b''): + queue.put((line, callback)) + stream.close() + + def start(self, proc): + queue = Queue() + stdout_reader = None + if proc.stdout: + stdout_reader = self._create_stream_reader('ProcessReaderStdout', + proc.stdout, + queue, + self.stdout_callback) + stderr_reader = None + if proc.stderr and proc.stderr != proc.stdout: + stderr_reader = self._create_stream_reader('ProcessReaderStderr', + proc.stderr, + queue, + self.stderr_callback) + self.thread = threading.Thread(name='ProcessReader', + target=self._read, + args=(stdout_reader, + stderr_reader, + queue)) + self.thread.daemon = True + self.thread.start() + + def _read(self, stdout_reader, stderr_reader, queue): + start_time = time.time() + timed_out = False + timeout = self.timeout + if timeout is not None: + timeout += start_time + output_timeout = self.output_timeout + if output_timeout is not None: + output_timeout += start_time + + while (stdout_reader and stdout_reader.is_alive()) \ + or (stderr_reader and stderr_reader.is_alive()): + has_line = True + try: + line, callback = queue.get(True, 0.02) + except Empty: + has_line = False + now = time.time() + if not has_line: + if output_timeout is not None and now > output_timeout: + timed_out = True + break + else: + if output_timeout is not None: + output_timeout = now + self.output_timeout + callback(line.rstrip()) + if timeout is not None and now > timeout: + timed_out = True + break + # process remaining lines to read + while not queue.empty(): + line, callback = queue.get(False) + callback(line.rstrip()) + if timed_out: + self.timeout_callback() + if stdout_reader: + stdout_reader.join() + if stderr_reader: + stderr_reader.join() + if not timed_out: + self.finished_callback() + + def is_alive(self): + if self.thread: + return self.thread.is_alive() + return False ### default output handlers ### these should be callables that take the output line diff --git a/testing/mozbase/mozprocess/tests/manifest.ini b/testing/mozbase/mozprocess/tests/manifest.ini index a61bdfd2477a..d869952e3f36 100644 --- a/testing/mozbase/mozprocess/tests/manifest.ini +++ b/testing/mozbase/mozprocess/tests/manifest.ini @@ -15,3 +15,4 @@ disabled = bug 921632 [test_mozprocess_wait.py] [test_mozprocess_output.py] [test_mozprocess_params.py] +[test_process_reader.py] diff --git a/testing/mozbase/mozprocess/tests/test_process_reader.py b/testing/mozbase/mozprocess/tests/test_process_reader.py new file mode 100644 index 000000000000..5fd17b4be72e --- /dev/null +++ b/testing/mozbase/mozprocess/tests/test_process_reader.py @@ -0,0 +1,95 @@ +import unittest +import subprocess +import sys +from mozprocess.processhandler import ProcessReader, StoreOutput + +def run_python(str_code, stdout=subprocess.PIPE, stderr=subprocess.PIPE): + cmd = [sys.executable, '-c', str_code] + return subprocess.Popen(cmd, stdout=stdout, stderr=stderr) + +class TestProcessReader(unittest.TestCase): + def setUp(self): + self.out = StoreOutput() + self.err = StoreOutput() + self.finished = False + def on_finished(): + self.finished = True + self.timeout = False + def on_timeout(): + self.timeout = True + self.reader = ProcessReader(stdout_callback=self.out, + stderr_callback=self.err, + finished_callback=on_finished, + timeout_callback=on_timeout) + + def test_stdout_callback(self): + proc = run_python('print 1; print 2') + self.reader.start(proc) + self.reader.thread.join() + + self.assertEqual(self.out.output, ['1', '2']) + self.assertEqual(self.err.output, []) + + def test_stderr_callback(self): + proc = run_python('import sys; sys.stderr.write("hello world\\n")') + self.reader.start(proc) + self.reader.thread.join() + + self.assertEqual(self.out.output, []) + self.assertEqual(self.err.output, ['hello world']) + + def test_stdout_and_stderr_callbacks(self): + proc = run_python('import sys; sys.stderr.write("hello world\\n"); print 1; print 2') + self.reader.start(proc) + self.reader.thread.join() + + self.assertEqual(self.out.output, ['1', '2']) + self.assertEqual(self.err.output, ['hello world']) + + def test_finished_callback(self): + self.assertFalse(self.finished) + proc = run_python('') + self.reader.start(proc) + self.reader.thread.join() + self.assertTrue(self.finished) + + def test_timeout(self): + self.reader.timeout = 0.05 + self.assertFalse(self.timeout) + proc = run_python('import time; time.sleep(0.1)') + self.reader.start(proc) + self.reader.thread.join() + self.assertTrue(self.timeout) + self.assertFalse(self.finished) + + def test_output_timeout(self): + self.reader.output_timeout = 0.05 + self.assertFalse(self.timeout) + proc = run_python('import time; time.sleep(0.1)') + self.reader.start(proc) + self.reader.thread.join() + self.assertTrue(self.timeout) + self.assertFalse(self.finished) + + def test_read_without_eol(self): + proc = run_python('import sys; sys.stdout.write("1")') + self.reader.start(proc) + self.reader.thread.join() + self.assertEqual(self.out.output, ['1']) + + def test_read_with_strange_eol(self): + proc = run_python('import sys; sys.stdout.write("1\\r\\r\\r\\n")') + self.reader.start(proc) + self.reader.thread.join() + self.assertEqual(self.out.output, ['1']) + + def test_mixed_stdout_stderr(self): + proc = run_python('import sys; sys.stderr.write("hello world\\n"); print 1; print 2', stderr=subprocess.STDOUT) + self.reader.start(proc) + self.reader.thread.join() + + self.assertEqual(sorted(self.out.output), sorted(['1', '2', 'hello world'])) + self.assertEqual(self.err.output, []) + +if __name__ == '__main__': + unittest.main() From a425715aebc17a47d4a974e8323f56c407a59e57 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Thu, 18 Dec 2014 12:20:32 -0700 Subject: [PATCH 002/183] Bug 1112827: Add IPDL's implicit typedefs to the set of explicit typedefs, preventing duplicates in generated code; r=bent --- ipc/ipdl/ipdl/lower.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 3bb885b11d6e..031b15e14ed1 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -1329,7 +1329,15 @@ with some new IPDL/C++ nodes that are tuned for C++ codegen.""" # fully-qualified name. e.g. |Foo| rather than |a::b::Foo|. self.typedefs = [ ] self.typedefSet = set([ Typedef(Type('mozilla::ipc::ActorHandle'), - 'ActorHandle') ]) + 'ActorHandle'), + Typedef(Type('base::ProcessId'), + 'ProcessId'), + Typedef(Type('mozilla::ipc::ProtocolId'), + 'ProtocolId'), + Typedef(Type('mozilla::ipc::Transport'), + 'Transport'), + Typedef(Type('mozilla::ipc::TransportDescriptor'), + 'TransportDescriptor') ]) self.protocolName = None def visitTranslationUnit(self, tu): @@ -2787,14 +2795,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): self.cls.addstmt(typedef) for typedef in self.includedActorTypedefs: self.cls.addstmt(typedef) - # XXX these don't really fit in the other lists; just include - # them here for now - self.cls.addstmts([ - Typedef(Type('base::ProcessId'), 'ProcessId'), - Typedef(Type('mozilla::ipc::ProtocolId'), 'ProtocolId'), - Typedef(Type('mozilla::ipc::Transport'), 'Transport'), - Typedef(Type('mozilla::ipc::TransportDescriptor'), 'TransportDescriptor') - ]) self.cls.addstmt(Whitespace.NL) From 145ebfeec299daccbf4ae22bf39ad3155347bc11 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 9 Jul 2014 12:26:51 -0700 Subject: [PATCH 003/183] Bug 1036602 - add D3D11 support for VR rendering; r=bas From fbb1e2ba9936896a1eb932585218401f4c95e411 Mon Sep 17 00:00:00 2001 --- gfx/layers/d3d11/CompositorD3D11.cpp | 212 +++++++++++++++++++++++++++++++++- gfx/layers/d3d11/CompositorD3D11.fx | 1 + gfx/layers/d3d11/CompositorD3D11.h | 9 ++ gfx/layers/d3d11/CompositorD3D11VR.fx | 71 ++++++++++++ 4 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 gfx/layers/d3d11/CompositorD3D11VR.fx --- gfx/layers/d3d11/CompositorD3D11.cpp | 212 +++++++++++++++++++++++++- gfx/layers/d3d11/CompositorD3D11.fx | 1 + gfx/layers/d3d11/CompositorD3D11.h | 9 ++ gfx/layers/d3d11/CompositorD3D11VR.fx | 71 +++++++++ 4 files changed, 290 insertions(+), 3 deletions(-) create mode 100644 gfx/layers/d3d11/CompositorD3D11VR.fx diff --git a/gfx/layers/d3d11/CompositorD3D11.cpp b/gfx/layers/d3d11/CompositorD3D11.cpp index 11225837b301..2e3e196cdc51 100644 --- a/gfx/layers/d3d11/CompositorD3D11.cpp +++ b/gfx/layers/d3d11/CompositorD3D11.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ @@ -7,6 +7,7 @@ #include "TextureD3D11.h" #include "CompositorD3D11Shaders.h" +#include "CompositorD3D11ShadersVR.h" #include "gfxWindowsPlatform.h" #include "nsIWidget.h" @@ -16,6 +17,7 @@ #include "nsWindowsHelpers.h" #include "gfxPrefs.h" #include "gfxCrashReporterUtils.h" +#include "gfxVR.h" #include "mozilla/EnumeratedArray.h" @@ -67,6 +69,27 @@ struct DeviceAttachmentsD3D11 RefPtr mComponentBlendState; RefPtr mDisabledBlendState; RefPtr mSyncTexture; + + // + // VR pieces + // + RefPtr mVRDistortionInputLayout; + RefPtr mVRDistortionConstants; + + typedef EnumeratedArray> + VRVertexShaderArray; + typedef EnumeratedArray> + VRPixelShaderArray; + + VRVertexShaderArray mVRDistortionVS; + VRPixelShaderArray mVRDistortionPS; + + // These will be created/filled in as needed during rendering whenever the configuration + // changes. + VRHMDConfiguration mVRConfiguration; + RefPtr mVRDistortionVertices[2]; // one for each eye + RefPtr mVRDistortionIndices[2]; + uint32_t mVRDistortionIndexCount[2]; }; CompositorD3D11::CompositorD3D11(nsIWidget* aWidget) @@ -282,13 +305,34 @@ CompositorD3D11::Initialize() RefPtr texture; hr = mDevice->CreateTexture2D(&desc, nullptr, byRef(texture)); - if (FAILED(hr)) { return false; } hr = texture->QueryInterface((IDXGIResource**)byRef(mAttachments->mSyncTexture)); + if (FAILED(hr)) { + return false; + } + + // + // VR additions + // + D3D11_INPUT_ELEMENT_DESC vrlayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + hr = mDevice->CreateInputLayout(vrlayout, + sizeof(vrlayout) / sizeof(D3D11_INPUT_ELEMENT_DESC), + OculusVRDistortionVS, + sizeof(OculusVRDistortionVS), + byRef(mAttachments->mVRDistortionInputLayout)); + cBufferDesc.ByteWidth = sizeof(gfx::VRDistortionConstants); + hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mVRDistortionConstants)); if (FAILED(hr)) { return false; } @@ -589,6 +633,141 @@ CompositorD3D11::ClearRect(const gfx::Rect& aRect) mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF); } +void +CompositorD3D11::DrawVRDistortion(const gfx::Rect& aRect, + const gfx::Rect& aClipRect, + const EffectChain& aEffectChain, + gfx::Float aOpacity, + const gfx::Matrix4x4& aTransform) +{ + MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EffectTypes::VR_DISTORTION); + + if (aEffectChain.mSecondaryEffects[EffectTypes::MASK] || + aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) + { + NS_WARNING("DrawVRDistortion: ignoring secondary effect!"); + } + + HRESULT hr; + + EffectVRDistortion* vrEffect = + static_cast(aEffectChain.mPrimaryEffect.get()); + + TextureSourceD3D11* source = vrEffect->mTexture->AsSourceD3D11(); + gfx::IntSize size = vrEffect->mRenderTarget->GetSize(); // XXX source->GetSize() + + VRHMDInfo* hmdInfo = vrEffect->mHMD; + VRDistortionConstants shaderConstants; + + // do we need to recreate the VR buffers, since the config has changed? + if (hmdInfo->GetConfiguration() != mAttachments->mVRConfiguration) { + D3D11_SUBRESOURCE_DATA sdata = { 0 }; + CD3D11_BUFFER_DESC desc(0, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE); + + // XXX as an optimization, we should really pack the indices and vertices for both eyes + // into one buffer instead of needing one eye each. Then we can just bind them once. + for (uint32_t eye = 0; eye < 2; eye++) { + const gfx::VRDistortionMesh& mesh = hmdInfo->GetDistortionMesh(eye); + + desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + desc.ByteWidth = mesh.mVertices.Length() * sizeof(gfx::VRDistortionVertex); + sdata.pSysMem = mesh.mVertices.Elements(); + + hr = mDevice->CreateBuffer(&desc, &sdata, byRef(mAttachments->mVRDistortionVertices[eye])); + if (FAILED(hr)) { + NS_WARNING("CreateBuffer failed"); + return; + } + + desc.BindFlags = D3D11_BIND_INDEX_BUFFER; + desc.ByteWidth = mesh.mIndices.Length() * sizeof(uint16_t); + sdata.pSysMem = mesh.mIndices.Elements(); + + hr = mDevice->CreateBuffer(&desc, &sdata, byRef(mAttachments->mVRDistortionIndices[eye])); + if (FAILED(hr)) { + NS_WARNING("CreateBuffer failed"); + return; + } + + mAttachments->mVRDistortionIndexCount[eye] = mesh.mIndices.Length(); + } + + mAttachments->mVRConfiguration = hmdInfo->GetConfiguration(); + } + + // XXX do I need to set a scissor rect? Is this the right scissor rect? + D3D11_RECT scissor; + scissor.left = aClipRect.x; + scissor.right = aClipRect.XMost(); + scissor.top = aClipRect.y; + scissor.bottom = aClipRect.YMost(); + mContext->RSSetScissorRects(1, &scissor); + + // Triangle lists and same layout for both eyes + mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + mContext->IASetInputLayout(mAttachments->mVRDistortionInputLayout); + + // Shaders for this HMD + mContext->VSSetShader(mAttachments->mVRDistortionVS[mAttachments->mVRConfiguration.hmdType], nullptr, 0); + mContext->PSSetShader(mAttachments->mVRDistortionPS[mAttachments->mVRConfiguration.hmdType], nullptr, 0); + + // This is the source texture SRV for the pixel shader + // XXX, um should we cache this SRV? + RefPtr view; + mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view)); + ID3D11ShaderResourceView* srView = view; + mContext->PSSetShaderResources(0, 1, &srView); + + + gfx::IntSize vpSizeInt = mCurrentRT->GetSize(); + gfx::Size vpSize(vpSizeInt.width, vpSizeInt.height); + ID3D11Buffer* vbuffer; + UINT vsize, voffset; + + for (uint32_t eye = 0; eye < 2; eye++) { + gfx::IntRect eyeViewport; + eyeViewport.x = eye * size.width / 2; + eyeViewport.y = 0; + eyeViewport.width = size.width / 2; + eyeViewport.height = size.height; + + hmdInfo->FillDistortionConstants(eye, + size, eyeViewport, + vpSize, aRect, + shaderConstants); + + // D3D has clip space top-left as -1,1 so we need to flip the Y coordinate offset here + shaderConstants.destinationScaleAndOffset[1] = - shaderConstants.destinationScaleAndOffset[1]; + + // XXX I really want to write a templated helper for these next 4 lines + D3D11_MAPPED_SUBRESOURCE resource; + mContext->Map(mAttachments->mVRDistortionConstants, 0, D3D11_MAP_WRITE_DISCARD, 0, &resource); + *(gfx::VRDistortionConstants*)resource.pData = shaderConstants; + mContext->Unmap(mAttachments->mVRDistortionConstants, 0); + + // XXX is there a better way to change a bunch of these things from what they were set to + // in BeginFrame/etc? + vbuffer = mAttachments->mVRDistortionVertices[eye]; + vsize = sizeof(gfx::VRDistortionVertex); + voffset = 0; + mContext->IASetVertexBuffers(0, 1, &vbuffer, &vsize, &voffset); + mContext->IASetIndexBuffer(mAttachments->mVRDistortionIndices[eye], DXGI_FORMAT_R16_UINT, 0); + + ID3D11Buffer* constBuf = mAttachments->mVRDistortionConstants; + mContext->VSSetConstantBuffers(0, 1, &constBuf); + + mContext->DrawIndexed(mAttachments->mVRDistortionIndexCount[eye], 0, 0); + } + + // restore previous configurations + vbuffer = mAttachments->mVertexBuffer; + vsize = sizeof(Vertex); + voffset = 0; + mContext->IASetVertexBuffers(0, 1, &vbuffer, &vsize, &voffset); + mContext->IASetIndexBuffer(nullptr, DXGI_FORMAT_R16_UINT, 0); + mContext->IASetInputLayout(mAttachments->mInputLayout); +} + void CompositorD3D11::DrawQuad(const gfx::Rect& aRect, const gfx::Rect& aClipRect, @@ -601,6 +780,12 @@ CompositorD3D11::DrawQuad(const gfx::Rect& aRect, } MOZ_ASSERT(mCurrentRT, "No render target"); + + if (aEffectChain.mPrimaryEffect->mType == EffectTypes::VR_DISTORTION) { + DrawVRDistortion(aRect, aClipRect, aEffectChain, aOpacity, aTransform); + return; + } + memcpy(&mVSConstants.layerTransform, &aTransform._11, 64); IntPoint origin = mCurrentRT->GetOrigin(); mVSConstants.renderTargetOffset[0] = origin.x; @@ -966,7 +1151,7 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize) { D3D11_VIEWPORT viewport; viewport.MaxDepth = 1.0f; - viewport.MinDepth = 0; + viewport.MinDepth = 0.0f; viewport.Width = aSize.width; viewport.Height = aSize.height; viewport.TopLeftX = 0; @@ -974,6 +1159,8 @@ CompositorD3D11::PrepareViewport(const gfx::IntSize& aSize) mContext->RSSetViewports(1, &viewport); + // This view matrix translates coordinates from 0..width and 0..height to + // -1..1 on the X axis, and -1..1 on the Y axis (flips the Y coordinate) Matrix viewMatrix = Matrix::Translation(-1.0, 1.0); viewMatrix.PreScale(2.0f / float(aSize.width), 2.0f / float(aSize.height)); viewMatrix.PreScale(1.0f, -1.0f); @@ -1113,6 +1300,25 @@ CompositorD3D11::CreateShaders() return false; } + + /* VR stuff */ + + hr = mDevice->CreateVertexShader(OculusVRDistortionVS, + sizeof(OculusVRDistortionVS), + nullptr, + byRef(mAttachments->mVRDistortionVS[VRHMDType::Oculus])); + if (FAILED(hr)) { + return false; + } + + hr = mDevice->CreatePixelShader(OculusVRDistortionPS, + sizeof(OculusVRDistortionPS), + nullptr, + byRef(mAttachments->mVRDistortionPS[VRHMDType::Oculus])); + if (FAILED(hr)) { + return false; + } + return true; } diff --git a/gfx/layers/d3d11/CompositorD3D11.fx b/gfx/layers/d3d11/CompositorD3D11.fx index ca189b5a028c..e5a586e8f347 100644 --- a/gfx/layers/d3d11/CompositorD3D11.fx +++ b/gfx/layers/d3d11/CompositorD3D11.fx @@ -71,6 +71,7 @@ SamplerState LayerTextureSamplerLinear float4 TransformedPosition(float2 aInPosition) { // the current vertex's position on the quad + // [x,y,0,1] is mandated by the CSS Transforms spec as the point value to transform float4 position = float4(0, 0, 0, 1); // We use 4 component floats to uniquely describe a rectangle, by the structure diff --git a/gfx/layers/d3d11/CompositorD3D11.h b/gfx/layers/d3d11/CompositorD3D11.h index 86510912e28b..f2a00292eef0 100644 --- a/gfx/layers/d3d11/CompositorD3D11.h +++ b/gfx/layers/d3d11/CompositorD3D11.h @@ -27,6 +27,8 @@ struct VertexShaderConstants gfx::Rect textureCoords; gfx::Rect layerQuad; gfx::Rect maskQuad; + float vrEyeToSourceUVScale[2]; + float vrEyeToSourceUVOffset[2]; }; struct PixelShaderConstants @@ -94,6 +96,13 @@ public: gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform) MOZ_OVERRIDE; + /* Helper for when the primary effect is VR_DISTORTION */ + void DrawVRDistortion(const gfx::Rect &aRect, + const gfx::Rect &aClipRect, + const EffectChain &aEffectChain, + gfx::Float aOpacity, + const gfx::Matrix4x4 &aTransform); + /** * Start a new frame. If aClipRectIn is null, sets *aClipRectOut to the * screen dimensions. diff --git a/gfx/layers/d3d11/CompositorD3D11VR.fx b/gfx/layers/d3d11/CompositorD3D11VR.fx new file mode 100644 index 000000000000..9a129ebc5517 --- /dev/null +++ b/gfx/layers/d3d11/CompositorD3D11VR.fx @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* These constants should match mozilla:gfx::VRDistortionConstants */ +float4 VREyeToSource : register(vs, c0); +float4 VRDestinationScaleAndOffset : register(vs, c1); + +/* This is the input undistorted texture */ +Texture2D Texture : register(ps, t0); + +/* This maps to mozilla::gfx::VRDistortionVertex in gfxVR.h. + * It's shared amongst all of the different rendering types; + * some might not be in use for a particular distortion effect. + */ +struct VS_VR_INPUT { + float2 vPosition : POSITION; + float2 vTexCoord0 : TEXCOORD0; + float2 vTexCoord1 : TEXCOORD1; + float2 vTexCoord2 : TEXCOORD2; + float4 vGenericAttribs : COLOR0; +}; + +struct VS_VR_OUTPUT { + float4 vPosition : SV_Position; + float3 vTexCoord0 : TEXCOORD0; + float3 vTexCoord1 : TEXCOORD1; + float3 vTexCoord2 : TEXCOORD2; + float4 vGenericAttribs : COLOR; +}; + +SamplerState Linear +{ + Filter = MIN_MAG_MIP_LINEAR; + AddressU = Clamp; + AddressV = Clamp; +}; + +VS_VR_OUTPUT OculusVRDistortionVS(const VS_VR_INPUT aVertex) +{ + VS_VR_OUTPUT res; + + float2 tc0 = VREyeToSource.xy * aVertex.vTexCoord0 + VREyeToSource.zw; + float2 tc1 = VREyeToSource.xy * aVertex.vTexCoord1 + VREyeToSource.zw; + float2 tc2 = VREyeToSource.xy * aVertex.vTexCoord2 + VREyeToSource.zw; + + //res.vPosition.xy = aVertex.vPosition.xy; + res.vPosition.xy = aVertex.vPosition.xy * VRDestinationScaleAndOffset.zw + VRDestinationScaleAndOffset.xy; + res.vPosition.zw = float2(0.5, 1.0); + + res.vTexCoord0 = float3(tc0, 1); + res.vTexCoord1 = float3(tc1, 1); + res.vTexCoord2 = float3(tc2, 1); + + res.vGenericAttribs = aVertex.vGenericAttribs; + + return res; +} + +float4 OculusVRDistortionPS(const VS_VR_OUTPUT aVertex) : SV_Target +{ + float resR = Texture.Sample(Linear, aVertex.vTexCoord0.xy).r; + float resG = Texture.Sample(Linear, aVertex.vTexCoord1.xy).g; + float resB = Texture.Sample(Linear, aVertex.vTexCoord2.xy).b; + + return float4(resR * aVertex.vGenericAttribs.r, + resG * aVertex.vGenericAttribs.r, + resB * aVertex.vGenericAttribs.r, + 1.0); +} From 883e1dee4c91cc3b2f87cd913fea680537339c11 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 17 Dec 2014 11:47:06 -0500 Subject: [PATCH 004/183] Bug 1036602 - rename d3d11 .fx files to .hlsl; r=bas From 0117494b71e0b9ea01d8b552523529cf305ab919 Mon Sep 17 00:00:00 2001 --- gfx/layers/d3d11/CompositorD3D11.fx | 279 -------------------------------- gfx/layers/d3d11/CompositorD3D11.hlsl | 279 ++++++++++++++++++++++++++++++++ gfx/layers/d3d11/CompositorD3D11VR.fx | 71 -------- gfx/layers/d3d11/CompositorD3D11VR.hlsl | 71 ++++++++ gfx/layers/d3d11/genshaders.sh | 28 ++-- 5 files changed, 364 insertions(+), 364 deletions(-) delete mode 100644 gfx/layers/d3d11/CompositorD3D11.fx create mode 100644 gfx/layers/d3d11/CompositorD3D11.hlsl delete mode 100644 gfx/layers/d3d11/CompositorD3D11VR.fx create mode 100644 gfx/layers/d3d11/CompositorD3D11VR.hlsl --- ...ompositorD3D11.fx => CompositorD3D11.hlsl} | 0 ...sitorD3D11VR.fx => CompositorD3D11VR.hlsl} | 0 gfx/layers/d3d11/genshaders.sh | 28 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) rename gfx/layers/d3d11/{CompositorD3D11.fx => CompositorD3D11.hlsl} (100%) rename gfx/layers/d3d11/{CompositorD3D11VR.fx => CompositorD3D11VR.hlsl} (100%) diff --git a/gfx/layers/d3d11/CompositorD3D11.fx b/gfx/layers/d3d11/CompositorD3D11.hlsl similarity index 100% rename from gfx/layers/d3d11/CompositorD3D11.fx rename to gfx/layers/d3d11/CompositorD3D11.hlsl diff --git a/gfx/layers/d3d11/CompositorD3D11VR.fx b/gfx/layers/d3d11/CompositorD3D11VR.hlsl similarity index 100% rename from gfx/layers/d3d11/CompositorD3D11VR.fx rename to gfx/layers/d3d11/CompositorD3D11VR.hlsl diff --git a/gfx/layers/d3d11/genshaders.sh b/gfx/layers/d3d11/genshaders.sh index 9a69bae542fb..edc66703b21b 100644 --- a/gfx/layers/d3d11/genshaders.sh +++ b/gfx/layers/d3d11/genshaders.sh @@ -4,32 +4,32 @@ tempfile=tmpShaderHeader rm CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ELayerQuadVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadVS +fxc CompositorD3D11.hlsl -ELayerQuadVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadVS cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ESolidColorShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShader +fxc CompositorD3D11.hlsl -ESolidColorShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShader cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ERGBShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShader +fxc CompositorD3D11.hlsl -ERGBShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShader cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ERGBAShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShader +fxc CompositorD3D11.hlsl -ERGBAShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShader cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -EComponentAlphaShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnComponentAlphaShader +fxc CompositorD3D11.hlsl -EComponentAlphaShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnComponentAlphaShader cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -EYCbCrShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShader +fxc CompositorD3D11.hlsl -EYCbCrShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShader cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ELayerQuadMaskVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMaskVS +fxc CompositorD3D11.hlsl -ELayerQuadMaskVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMaskVS cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ELayerQuadMask3DVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMask3DVS +fxc CompositorD3D11.hlsl -ELayerQuadMask3DVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMask3DVS cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ESolidColorShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShaderMask +fxc CompositorD3D11.hlsl -ESolidColorShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShaderMask cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ERGBShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShaderMask +fxc CompositorD3D11.hlsl -ERGBShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShaderMask cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ERGBAShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask +fxc CompositorD3D11.hlsl -ERGBAShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -ERGBAShaderMask3D -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask3D +fxc CompositorD3D11.hlsl -ERGBAShaderMask3D -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask3D cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -EYCbCrShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShaderMask +fxc CompositorD3D11.hlsl -EYCbCrShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShaderMask cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.fx -EComponentAlphaShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnComponentAlphaShaderMask +fxc CompositorD3D11.hlsl -EComponentAlphaShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnComponentAlphaShaderMask cat $tempfile >> CompositorD3D11Shaders.h rm $tempfile From 8cf3cb0f2dec85768570e1603ff8a1ba6fd8d694 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 9 Jul 2014 12:27:38 -0700 Subject: [PATCH 005/183] Bug 1036602 - Fix up D3D11 genshaders.sh script; r=bas From 42aa031e5b36efe5603525c7967557fec7e09ec5 Mon Sep 17 00:00:00 2001 --- gfx/layers/d3d11/genshaders.sh | 74 +++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 29 deletions(-) --- gfx/layers/d3d11/genshaders.sh | 74 +++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/gfx/layers/d3d11/genshaders.sh b/gfx/layers/d3d11/genshaders.sh index edc66703b21b..f479ba7c0378 100644 --- a/gfx/layers/d3d11/genshaders.sh +++ b/gfx/layers/d3d11/genshaders.sh @@ -3,33 +3,49 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. tempfile=tmpShaderHeader -rm CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ELayerQuadVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadVS -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ESolidColorShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShader -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ERGBShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShader -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ERGBAShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShader -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -EComponentAlphaShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnComponentAlphaShader -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -EYCbCrShader -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShader -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ELayerQuadMaskVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMaskVS -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ELayerQuadMask3DVS -nologo -Tvs_4_0_level_9_3 -Fh$tempfile -VnLayerQuadMask3DVS -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ESolidColorShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnSolidColorShaderMask -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ERGBShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBShaderMask -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ERGBAShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -ERGBAShaderMask3D -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnRGBAShaderMask3D -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -EYCbCrShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnYCbCrShaderMask -cat $tempfile >> CompositorD3D11Shaders.h -fxc CompositorD3D11.hlsl -EComponentAlphaShaderMask -Tps_4_0_level_9_3 -nologo -Fh$tempfile -VnComponentAlphaShaderMask -cat $tempfile >> CompositorD3D11Shaders.h + +FXC_DEBUG_FLAGS="-Zi -Fd shaders.pdb" +FXC_FLAGS="" + +# If DEBUG is in the environment, then rebuild with debug info +if [ "$DEBUG" != "" ] ; then + FXC_FLAGS="$FXC_DEBUG_FLAGS" +fi + +makeShaderVS() { + fxc -nologo $FXC_FLAGS -Tvs_4_0_level_9_3 $SRC -E$1 -Vn$1 -Fh$tempfile + cat $tempfile >> $DEST +} + +makeShaderPS() { + fxc -nologo $FXC_FLAGS -Tps_4_0_level_9_3 $SRC -E$1 -Vn$1 -Fh$tempfile + cat $tempfile >> $DEST +} + +SRC=CompositorD3D11.hlsl +DEST=CompositorD3D11Shaders.h + +rm -f $DEST +makeShaderVS LayerQuadVS +makeShaderPS SolidColorShader +makeShaderPS RGBShader +makeShaderPS RGBAShader +makeShaderPS ComponentAlphaShader +makeShaderPS YCbCrShader +makeShaderVS LayerQuadMaskVS +makeShaderVS LayerQuadMask3DVS +makeShaderPS SolidColorShaderMask +makeShaderPS RGBShaderMask +makeShaderPS RGBAShaderMask +makeShaderPS RGBAShaderMask3D +makeShaderPS YCbCrShaderMask +makeShaderPS ComponentAlphaShaderMask + +SRC=CompositorD3D11VR.hlsl +DEST=CompositorD3D11ShadersVR.h + +rm -f $DEST +makeShaderVS OculusVRDistortionVS +makeShaderPS OculusVRDistortionPS + rm $tempfile From 18fcfec1c785b1055eca9b0766014d6d36ac0c81 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 9 Jul 2014 12:28:05 -0700 Subject: [PATCH 006/183] Bug 1036602 - Regenerate D3D11 shaders; r=Bas From 11ab35cf793e6a2a0342b4e1a761a6f4cc394ff5 Mon Sep 17 00:00:00 2001 --- gfx/layers/d3d11/CompositorD3D11Shaders.h | 282 ++++++------ gfx/layers/d3d11/CompositorD3D11ShadersVR.h | 638 ++++++++++++++++++++++++++++ 2 files changed, 786 insertions(+), 134 deletions(-) create mode 100644 gfx/layers/d3d11/CompositorD3D11ShadersVR.h --- gfx/layers/d3d11/CompositorD3D11Shaders.h | 282 +++++---- gfx/layers/d3d11/CompositorD3D11ShadersVR.h | 638 ++++++++++++++++++++ 2 files changed, 786 insertions(+), 134 deletions(-) create mode 100644 gfx/layers/d3d11/CompositorD3D11ShadersVR.h diff --git a/gfx/layers/d3d11/CompositorD3D11Shaders.h b/gfx/layers/d3d11/CompositorD3D11Shaders.h index 18b99663296b..f6379c7f4ccb 100644 --- a/gfx/layers/d3d11/CompositorD3D11Shaders.h +++ b/gfx/layers/d3d11/CompositorD3D11Shaders.h @@ -1,8 +1,9 @@ #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -103,10 +104,10 @@ ret const BYTE LayerQuadVS[] = { - 68, 88, 66, 67, 200, 251, - 64, 251, 166, 240, 101, 137, - 191, 140, 75, 217, 9, 168, - 61, 163, 1, 0, 0, 0, + 68, 88, 66, 67, 67, 61, + 27, 151, 57, 33, 48, 19, + 55, 6, 95, 77, 254, 163, + 118, 237, 1, 0, 0, 0, 180, 6, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 152, 1, 0, 0, 160, 3, @@ -261,7 +262,7 @@ const BYTE LayerQuadVS[] = 65, 84, 116, 0, 0, 0, 13, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, - 3, 0, 0, 0, 12, 0, + 3, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, @@ -271,7 +272,7 @@ const BYTE LayerQuadVS[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -362,10 +363,10 @@ const BYTE LayerQuadVS[] = 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 54, - 46, 51, 46, 57, 54, 48, - 48, 46, 49, 54, 51, 56, - 52, 0, 171, 171, 73, 83, + 105, 108, 101, 114, 32, 57, + 46, 51, 48, 46, 57, 50, + 48, 48, 46, 50, 48, 53, + 52, 54, 0, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, @@ -392,9 +393,10 @@ const BYTE LayerQuadVS[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -458,10 +460,10 @@ ret const BYTE SolidColorShader[] = { - 68, 88, 66, 67, 30, 148, - 104, 202, 165, 39, 58, 182, - 100, 205, 95, 195, 52, 137, - 197, 241, 1, 0, 0, 0, + 68, 88, 66, 67, 182, 98, + 102, 100, 187, 218, 19, 40, + 99, 74, 29, 228, 47, 107, + 160, 122, 1, 0, 0, 0, 224, 3, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 132, 0, 0, 0, 204, 0, @@ -506,7 +508,7 @@ const BYTE SolidColorShader[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -597,9 +599,9 @@ const BYTE SolidColorShader[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, @@ -627,9 +629,10 @@ const BYTE SolidColorShader[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -713,10 +716,10 @@ ret const BYTE RGBShader[] = { - 68, 88, 66, 67, 239, 198, - 87, 206, 69, 92, 245, 30, - 125, 195, 239, 77, 37, 241, - 175, 187, 1, 0, 0, 0, + 68, 88, 66, 67, 195, 54, + 227, 44, 79, 159, 121, 69, + 60, 252, 145, 90, 151, 241, + 175, 162, 1, 0, 0, 0, 232, 4, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 204, 0, 0, 0, 136, 1, @@ -792,7 +795,7 @@ const BYTE RGBShader[] = 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -896,9 +899,9 @@ const BYTE RGBShader[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, @@ -926,9 +929,10 @@ const BYTE RGBShader[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -1010,10 +1014,10 @@ ret const BYTE RGBAShader[] = { - 68, 88, 66, 67, 230, 59, - 90, 23, 60, 77, 18, 113, - 14, 129, 183, 152, 233, 55, - 111, 42, 1, 0, 0, 0, + 68, 88, 66, 67, 124, 18, + 8, 218, 34, 168, 20, 218, + 144, 232, 183, 104, 152, 211, + 5, 26, 1, 0, 0, 0, 196, 4, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 192, 0, 0, 0, 100, 1, @@ -1083,7 +1087,7 @@ const BYTE RGBAShader[] = 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1187,9 +1191,9 @@ const BYTE RGBAShader[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, @@ -1217,9 +1221,10 @@ const BYTE RGBAShader[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -1319,10 +1324,10 @@ ret const BYTE ComponentAlphaShader[] = { - 68, 88, 66, 67, 186, 162, - 72, 42, 69, 36, 160, 68, - 108, 121, 216, 238, 108, 37, - 6, 145, 1, 0, 0, 0, + 68, 88, 66, 67, 152, 37, + 117, 77, 87, 153, 20, 62, + 92, 142, 77, 134, 246, 203, + 174, 59, 1, 0, 0, 0, 68, 6, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 64, 1, 0, 0, 160, 2, @@ -1445,7 +1450,7 @@ const BYTE ComponentAlphaShader[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1556,9 +1561,9 @@ const BYTE ComponentAlphaShader[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, @@ -1590,9 +1595,10 @@ const BYTE ComponentAlphaShader[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -1708,10 +1714,10 @@ ret const BYTE YCbCrShader[] = { - 68, 88, 66, 67, 181, 118, - 100, 53, 248, 120, 136, 92, - 59, 190, 18, 201, 139, 224, - 32, 141, 1, 0, 0, 0, + 68, 88, 66, 67, 26, 187, + 43, 127, 28, 135, 212, 40, + 57, 230, 160, 198, 151, 242, + 106, 110, 1, 0, 0, 0, 212, 7, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 220, 1, 0, 0, 44, 4, @@ -1890,7 +1896,7 @@ const BYTE YCbCrShader[] = 0, 0, 15, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 10, 0, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1900,7 +1906,7 @@ const BYTE YCbCrShader[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2016,9 +2022,9 @@ const BYTE YCbCrShader[] = 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 50, 48, + 53, 52, 54, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, @@ -2045,9 +2051,10 @@ const BYTE YCbCrShader[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -2158,10 +2165,10 @@ ret const BYTE LayerQuadMaskVS[] = { - 68, 88, 66, 67, 223, 251, - 10, 17, 13, 90, 47, 25, - 119, 198, 20, 157, 124, 193, - 251, 234, 1, 0, 0, 0, + 68, 88, 66, 67, 229, 18, + 238, 182, 176, 120, 118, 84, + 74, 135, 103, 188, 146, 51, + 229, 207, 1, 0, 0, 0, 120, 7, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 224, 1, 0, 0, 76, 4, @@ -2345,7 +2352,7 @@ const BYTE LayerQuadMaskVS[] = 116, 0, 0, 0, 16, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 4, 0, - 0, 0, 14, 0, 0, 0, + 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2355,7 +2362,7 @@ const BYTE LayerQuadMaskVS[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2446,10 +2453,10 @@ const BYTE LayerQuadMaskVS[] = 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, - 101, 114, 32, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 50, 48, 53, 52, 54, + 0, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, @@ -2480,9 +2487,10 @@ const BYTE LayerQuadMaskVS[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -2597,10 +2605,10 @@ ret const BYTE LayerQuadMask3DVS[] = { - 68, 88, 66, 67, 151, 141, - 11, 11, 111, 244, 17, 242, - 119, 116, 248, 53, 235, 192, - 38, 193, 1, 0, 0, 0, + 68, 88, 66, 67, 81, 198, + 45, 88, 207, 133, 27, 66, + 4, 235, 107, 238, 69, 93, + 43, 232, 1, 0, 0, 0, 204, 7, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 24, 2, 0, 0, 160, 4, @@ -2798,7 +2806,7 @@ const BYTE LayerQuadMask3DVS[] = 116, 0, 0, 0, 17, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 0, - 0, 0, 15, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2808,7 +2816,7 @@ const BYTE LayerQuadMask3DVS[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -2899,10 +2907,10 @@ const BYTE LayerQuadMask3DVS[] = 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, - 101, 114, 32, 54, 46, 51, - 46, 57, 54, 48, 48, 46, - 49, 54, 51, 56, 52, 0, - 171, 171, 73, 83, 71, 78, + 101, 114, 32, 57, 46, 51, + 48, 46, 57, 50, 48, 48, + 46, 50, 48, 53, 52, 54, + 0, 171, 73, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, @@ -2933,9 +2941,10 @@ const BYTE LayerQuadMask3DVS[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -3019,10 +3028,10 @@ ret const BYTE SolidColorShaderMask[] = { - 68, 88, 66, 67, 236, 109, - 19, 151, 23, 187, 157, 205, - 112, 188, 91, 187, 108, 106, - 138, 14, 1, 0, 0, 0, + 68, 88, 66, 67, 110, 173, + 179, 170, 121, 56, 16, 38, + 131, 202, 191, 200, 149, 158, + 191, 136, 1, 0, 0, 0, 232, 4, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 204, 0, 0, 0, 112, 1, @@ -3094,7 +3103,7 @@ const BYTE SolidColorShaderMask[] = 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3198,9 +3207,9 @@ const BYTE SolidColorShaderMask[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, @@ -3232,9 +3241,10 @@ const BYTE SolidColorShaderMask[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -3329,10 +3339,10 @@ ret const BYTE RGBShaderMask[] = { - 68, 88, 66, 67, 30, 30, - 87, 58, 114, 156, 251, 151, - 29, 94, 34, 100, 228, 250, - 37, 251, 1, 0, 0, 0, + 68, 88, 66, 67, 90, 156, + 108, 215, 2, 184, 95, 225, + 139, 102, 23, 57, 234, 197, + 48, 52, 1, 0, 0, 0, 192, 5, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 8, 1, 0, 0, 32, 2, @@ -3433,7 +3443,7 @@ const BYTE RGBShaderMask[] = 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3544,9 +3554,9 @@ const BYTE RGBShaderMask[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, @@ -3578,9 +3588,10 @@ const BYTE RGBShaderMask[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -3673,10 +3684,10 @@ ret const BYTE RGBAShaderMask[] = { - 68, 88, 66, 67, 188, 13, - 191, 168, 231, 201, 42, 209, - 88, 243, 29, 35, 226, 31, - 145, 20, 1, 0, 0, 0, + 68, 88, 66, 67, 106, 15, + 51, 47, 230, 18, 55, 40, + 97, 21, 143, 67, 32, 99, + 176, 32, 1, 0, 0, 0, 156, 5, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 252, 0, 0, 0, 252, 1, @@ -3771,7 +3782,7 @@ const BYTE RGBAShaderMask[] = 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -3882,9 +3893,9 @@ const BYTE RGBAShaderMask[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, @@ -3916,9 +3927,10 @@ const BYTE RGBAShaderMask[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -4016,10 +4028,10 @@ ret const BYTE RGBAShaderMask3D[] = { - 68, 88, 66, 67, 113, 141, - 78, 23, 128, 223, 235, 10, - 0, 97, 49, 111, 47, 53, - 229, 55, 1, 0, 0, 0, + 68, 88, 66, 67, 176, 186, + 72, 64, 199, 228, 205, 219, + 97, 152, 199, 132, 157, 124, + 226, 212, 1, 0, 0, 0, 24, 6, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 24, 1, 0, 0, 64, 2, @@ -4126,7 +4138,7 @@ const BYTE RGBAShaderMask3D[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4246,9 +4258,9 @@ const BYTE RGBAShaderMask3D[] = 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 50, 48, + 53, 52, 54, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, @@ -4279,9 +4291,10 @@ const BYTE RGBAShaderMask3D[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -4408,10 +4421,10 @@ ret const BYTE YCbCrShaderMask[] = { - 68, 88, 66, 67, 103, 162, - 223, 236, 236, 142, 143, 151, - 73, 154, 187, 112, 81, 114, - 229, 251, 1, 0, 0, 0, + 68, 88, 66, 67, 115, 10, + 33, 43, 108, 217, 72, 92, + 140, 65, 97, 68, 194, 221, + 95, 25, 1, 0, 0, 0, 168, 8, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 24, 2, 0, 0, 196, 4, @@ -4615,7 +4628,7 @@ const BYTE YCbCrShaderMask[] = 116, 0, 0, 0, 17, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, - 0, 0, 11, 0, 0, 0, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4625,7 +4638,7 @@ const BYTE YCbCrShaderMask[] = 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -4747,9 +4760,9 @@ const BYTE YCbCrShaderMask[] = 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, - 114, 32, 54, 46, 51, 46, - 57, 54, 48, 48, 46, 49, - 54, 51, 56, 52, 0, 171, + 114, 32, 57, 46, 51, 48, + 46, 57, 50, 48, 48, 46, + 50, 48, 53, 52, 54, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, @@ -4781,9 +4794,10 @@ const BYTE YCbCrShaderMask[] = }; #if 0 // -// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384 +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 // // +/// // Buffer Definitions: // // cbuffer $Globals @@ -4894,10 +4908,10 @@ ret const BYTE ComponentAlphaShaderMask[] = { - 68, 88, 66, 67, 245, 71, - 211, 223, 156, 101, 223, 204, - 145, 138, 53, 12, 16, 220, - 106, 83, 1, 0, 0, 0, + 68, 88, 66, 67, 66, 175, + 106, 103, 136, 76, 200, 80, + 95, 179, 74, 140, 138, 144, + 12, 21, 1, 0, 0, 0, 20, 7, 0, 0, 6, 0, 0, 0, 56, 0, 0, 0, 124, 1, 0, 0, 52, 3, @@ -5044,7 +5058,7 @@ const BYTE ComponentAlphaShaderMask[] = 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -5162,9 +5176,9 @@ const BYTE ComponentAlphaShaderMask[] = 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, - 54, 46, 51, 46, 57, 54, - 48, 48, 46, 49, 54, 51, - 56, 52, 0, 171, 73, 83, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 50, 48, + 53, 52, 54, 0, 73, 83, 71, 78, 104, 0, 0, 0, 3, 0, 0, 0, 8, 0, 0, 0, 80, 0, 0, 0, diff --git a/gfx/layers/d3d11/CompositorD3D11ShadersVR.h b/gfx/layers/d3d11/CompositorD3D11ShadersVR.h new file mode 100644 index 000000000000..ade0666127cf --- /dev/null +++ b/gfx/layers/d3d11/CompositorD3D11ShadersVR.h @@ -0,0 +1,638 @@ +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 +// +// +/// +// Buffer Definitions: +// +// cbuffer $Globals +// { +// +// float4 VREyeToSource; // Offset: 0 Size: 16 +// float4 VRDestinationScaleAndOffset;// Offset: 16 Size: 16 +// +// } +// +// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// $Globals cbuffer NA NA 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// POSITION 0 xy 0 NONE float xy +// TEXCOORD 0 xy 1 NONE float xy +// TEXCOORD 1 xy 2 NONE float xy +// TEXCOORD 2 xy 3 NONE float xy +// COLOR 0 xyzw 4 NONE float xyzw +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float xyzw +// TEXCOORD 0 xyz 1 NONE float xyz +// TEXCOORD 1 xyz 2 NONE float xyz +// TEXCOORD 2 xyz 3 NONE float xyz +// COLOR 0 xyzw 4 NONE float xyzw +// +// +// Constant buffer to DX9 shader constant mappings: +// +// Target Reg Buffer Start Reg # of Regs Data Conversion +// ---------- ------- --------- --------- ---------------------- +// c1 cb0 0 2 ( FLT, FLT, FLT, FLT) +// +// +// Runtime generated constant mappings: +// +// Target Reg Constant Description +// ---------- -------------------------------------------------- +// c0 Vertex Shader position offset +// +// +// Level9 shader bytecode: +// + vs_2_x + def c3, 0.5, 1, 0, 0 + dcl_texcoord v0 + dcl_texcoord1 v1 + dcl_texcoord2 v2 + dcl_texcoord3 v3 + dcl_texcoord4 v4 + mad oT0.xy, c1, v1, c1.zwzw + mad oT1.xy, c1, v2, c1.zwzw + mad oT2.xy, c1, v3, c1.zwzw + mad r0.xy, v0, c2.zwzw, c2 + add oPos.xy, r0, c0 + mov oPos.zw, c3.xyxy + mov oT0.z, c3.y + mov oT1.z, c3.y + mov oT2.z, c3.y + mov oT3, v4 + +// approximately 10 instruction slots used +vs_4_0 +dcl_constantbuffer cb0[2], immediateIndexed +dcl_input v0.xy +dcl_input v1.xy +dcl_input v2.xy +dcl_input v3.xy +dcl_input v4.xyzw +dcl_output_siv o0.xyzw, position +dcl_output o1.xyz +dcl_output o2.xyz +dcl_output o3.xyz +dcl_output o4.xyzw +mad o0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx +mov o0.zw, l(0,0,0.500000,1.000000) +mad o1.xy, cb0[0].xyxx, v1.xyxx, cb0[0].zwzz +mov o1.z, l(1.000000) +mad o2.xy, cb0[0].xyxx, v2.xyxx, cb0[0].zwzz +mov o2.z, l(1.000000) +mad o3.xy, cb0[0].xyxx, v3.xyxx, cb0[0].zwzz +mov o3.z, l(1.000000) +mov o4.xyzw, v4.xyzw +ret +// Approximately 10 instruction slots used +#endif + +const BYTE OculusVRDistortionVS[] = +{ + 68, 88, 66, 67, 146, 215, + 61, 238, 94, 6, 58, 25, + 65, 203, 120, 251, 26, 22, + 109, 4, 1, 0, 0, 0, + 244, 5, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 108, 1, 0, 0, 44, 3, + 0, 0, 168, 3, 0, 0, + 176, 4, 0, 0, 80, 5, + 0, 0, 65, 111, 110, 57, + 44, 1, 0, 0, 44, 1, + 0, 0, 0, 2, 254, 255, + 248, 0, 0, 0, 52, 0, + 0, 0, 1, 0, 36, 0, + 0, 0, 48, 0, 0, 0, + 48, 0, 0, 0, 36, 0, + 1, 0, 48, 0, 0, 0, + 0, 0, 2, 0, 1, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 254, 255, + 81, 0, 0, 5, 3, 0, + 15, 160, 0, 0, 0, 63, + 0, 0, 128, 63, 0, 0, + 0, 0, 0, 0, 0, 0, + 31, 0, 0, 2, 5, 0, + 0, 128, 0, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 1, 128, 1, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 2, 128, 2, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 3, 128, 3, 0, 15, 144, + 31, 0, 0, 2, 5, 0, + 4, 128, 4, 0, 15, 144, + 4, 0, 0, 4, 0, 0, + 3, 224, 1, 0, 228, 160, + 1, 0, 228, 144, 1, 0, + 238, 160, 4, 0, 0, 4, + 1, 0, 3, 224, 1, 0, + 228, 160, 2, 0, 228, 144, + 1, 0, 238, 160, 4, 0, + 0, 4, 2, 0, 3, 224, + 1, 0, 228, 160, 3, 0, + 228, 144, 1, 0, 238, 160, + 4, 0, 0, 4, 0, 0, + 3, 128, 0, 0, 228, 144, + 2, 0, 238, 160, 2, 0, + 228, 160, 2, 0, 0, 3, + 0, 0, 3, 192, 0, 0, + 228, 128, 0, 0, 228, 160, + 1, 0, 0, 2, 0, 0, + 12, 192, 3, 0, 68, 160, + 1, 0, 0, 2, 0, 0, + 4, 224, 3, 0, 85, 160, + 1, 0, 0, 2, 1, 0, + 4, 224, 3, 0, 85, 160, + 1, 0, 0, 2, 2, 0, + 4, 224, 3, 0, 85, 160, + 1, 0, 0, 2, 3, 0, + 15, 224, 4, 0, 228, 144, + 255, 255, 0, 0, 83, 72, + 68, 82, 184, 1, 0, 0, + 64, 0, 1, 0, 110, 0, + 0, 0, 89, 0, 0, 4, + 70, 142, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 0, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 2, 0, 0, 0, + 95, 0, 0, 3, 50, 16, + 16, 0, 3, 0, 0, 0, + 95, 0, 0, 3, 242, 16, + 16, 0, 4, 0, 0, 0, + 103, 0, 0, 4, 242, 32, + 16, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 114, 32, 16, 0, + 1, 0, 0, 0, 101, 0, + 0, 3, 114, 32, 16, 0, + 2, 0, 0, 0, 101, 0, + 0, 3, 114, 32, 16, 0, + 3, 0, 0, 0, 101, 0, + 0, 3, 242, 32, 16, 0, + 4, 0, 0, 0, 50, 0, + 0, 11, 50, 32, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 0, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 70, 128, 32, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 54, 0, 0, 8, 194, 32, + 16, 0, 0, 0, 0, 0, + 2, 64, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 63, 0, 0, + 128, 63, 50, 0, 0, 11, + 50, 32, 16, 0, 1, 0, + 0, 0, 70, 128, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 230, 138, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 54, 0, + 0, 5, 66, 32, 16, 0, + 1, 0, 0, 0, 1, 64, + 0, 0, 0, 0, 128, 63, + 50, 0, 0, 11, 50, 32, + 16, 0, 2, 0, 0, 0, + 70, 128, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, + 0, 0, 230, 138, 32, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, + 66, 32, 16, 0, 2, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 50, 0, + 0, 11, 50, 32, 16, 0, + 3, 0, 0, 0, 70, 128, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 3, 0, 0, 0, + 230, 138, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 54, 0, 0, 5, 66, 32, + 16, 0, 3, 0, 0, 0, + 1, 64, 0, 0, 0, 0, + 128, 63, 54, 0, 0, 5, + 242, 32, 16, 0, 4, 0, + 0, 0, 70, 30, 16, 0, + 4, 0, 0, 0, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 82, 68, 69, 70, 0, 1, + 0, 0, 1, 0, 0, 0, + 72, 0, 0, 0, 1, 0, + 0, 0, 28, 0, 0, 0, + 0, 4, 254, 255, 0, 1, + 0, 0, 204, 0, 0, 0, + 60, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 36, 71, 108, 111, + 98, 97, 108, 115, 0, 171, + 171, 171, 60, 0, 0, 0, + 2, 0, 0, 0, 96, 0, + 0, 0, 32, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 144, 0, 0, 0, + 0, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 160, 0, 0, 0, 0, 0, + 0, 0, 176, 0, 0, 0, + 16, 0, 0, 0, 16, 0, + 0, 0, 2, 0, 0, 0, + 160, 0, 0, 0, 0, 0, + 0, 0, 86, 82, 69, 121, + 101, 84, 111, 83, 111, 117, + 114, 99, 101, 0, 171, 171, + 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 86, 82, + 68, 101, 115, 116, 105, 110, + 97, 116, 105, 111, 110, 83, + 99, 97, 108, 101, 65, 110, + 100, 79, 102, 102, 115, 101, + 116, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, + 40, 82, 41, 32, 72, 76, + 83, 76, 32, 83, 104, 97, + 100, 101, 114, 32, 67, 111, + 109, 112, 105, 108, 101, 114, + 32, 57, 46, 51, 48, 46, + 57, 50, 48, 48, 46, 50, + 48, 53, 52, 54, 0, 171, + 73, 83, 71, 78, 152, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 128, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 3, 3, 0, 0, 137, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 3, 3, 0, 0, 137, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 3, 3, 0, 0, 137, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, + 3, 3, 0, 0, 146, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, + 15, 15, 0, 0, 80, 79, + 83, 73, 84, 73, 79, 78, + 0, 84, 69, 88, 67, 79, + 79, 82, 68, 0, 67, 79, + 76, 79, 82, 0, 79, 83, + 71, 78, 156, 0, 0, 0, + 5, 0, 0, 0, 8, 0, + 0, 0, 128, 0, 0, 0, + 0, 0, 0, 0, 1, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 15, 0, + 0, 0, 140, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 1, 0, 0, 0, 7, 8, + 0, 0, 140, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 2, 0, 0, 0, 7, 8, + 0, 0, 140, 0, 0, 0, + 2, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 3, 0, 0, 0, 7, 8, + 0, 0, 149, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, + 4, 0, 0, 0, 15, 0, + 0, 0, 83, 86, 95, 80, + 111, 115, 105, 116, 105, 111, + 110, 0, 84, 69, 88, 67, + 79, 79, 82, 68, 0, 67, + 79, 76, 79, 82, 0, 171 +}; +#if 0 +// +// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546 +// +// +/// +// Resource Bindings: +// +// Name Type Format Dim Slot Elements +// ------------------------------ ---------- ------- ----------- ---- -------- +// Linear sampler NA NA 0 1 +// Texture texture float4 2d 0 1 +// +// +// +// Input signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Position 0 xyzw 0 POS float +// TEXCOORD 0 xyz 1 NONE float xy +// TEXCOORD 1 xyz 2 NONE float xy +// TEXCOORD 2 xyz 3 NONE float xy +// COLOR 0 xyzw 4 NONE float x +// +// +// Output signature: +// +// Name Index Mask Register SysValue Format Used +// -------------------- ----- ------ -------- -------- ------- ------ +// SV_Target 0 xyzw 0 TARGET float xyzw +// +// +// Sampler/Resource to DX9 shader sampler mappings: +// +// Target Sampler Source Sampler Source Resource +// -------------- --------------- ---------------- +// s0 s0 t0 +// +// +// Level9 shader bytecode: +// + ps_2_x + def c0, 1, 0, 0, 0 + dcl t0.xyz + dcl t1.xyz + dcl t2.xyz + dcl t3 + dcl_2d s0 + texld r0, t1, s0 + texld r1, t0, s0 + mul r1.x, r1.x, t3.x + mul r1.y, r0.y, t3.x + texld r0, t2, s0 + mul r1.z, r0.z, t3.x + mov r1.w, c0.x + mov oC0, r1 + +// approximately 8 instruction slots used (3 texture, 5 arithmetic) +ps_4_0 +dcl_sampler s0, mode_default +dcl_resource_texture2d (float,float,float,float) t0 +dcl_input_ps linear v1.xy +dcl_input_ps linear v2.xy +dcl_input_ps linear v3.xy +dcl_input_ps linear v4.x +dcl_output o0.xyzw +dcl_temps 1 +sample r0.xyzw, v1.xyxx, t0.xyzw, s0 +mul o0.x, r0.x, v4.x +sample r0.xyzw, v2.xyxx, t0.xyzw, s0 +mul o0.y, r0.y, v4.x +sample r0.xyzw, v3.xyxx, t0.xyzw, s0 +mul o0.z, r0.z, v4.x +mov o0.w, l(1.000000) +ret +// Approximately 8 instruction slots used +#endif + +const BYTE OculusVRDistortionPS[] = +{ + 68, 88, 66, 67, 150, 176, + 84, 101, 196, 27, 87, 110, + 226, 144, 161, 15, 69, 81, + 48, 158, 1, 0, 0, 0, + 128, 4, 0, 0, 6, 0, + 0, 0, 56, 0, 0, 0, + 60, 1, 0, 0, 132, 2, + 0, 0, 0, 3, 0, 0, + 168, 3, 0, 0, 76, 4, + 0, 0, 65, 111, 110, 57, + 252, 0, 0, 0, 252, 0, + 0, 0, 0, 2, 255, 255, + 212, 0, 0, 0, 40, 0, + 0, 0, 0, 0, 40, 0, + 0, 0, 40, 0, 0, 0, + 40, 0, 1, 0, 36, 0, + 0, 0, 40, 0, 0, 0, + 0, 0, 1, 2, 255, 255, + 81, 0, 0, 5, 0, 0, + 15, 160, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 31, 0, 0, 2, 0, 0, + 0, 128, 0, 0, 7, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 1, 0, 7, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 2, 0, 7, 176, + 31, 0, 0, 2, 0, 0, + 0, 128, 3, 0, 15, 176, + 31, 0, 0, 2, 0, 0, + 0, 144, 0, 8, 15, 160, + 66, 0, 0, 3, 0, 0, + 15, 128, 1, 0, 228, 176, + 0, 8, 228, 160, 66, 0, + 0, 3, 1, 0, 15, 128, + 0, 0, 228, 176, 0, 8, + 228, 160, 5, 0, 0, 3, + 1, 0, 1, 128, 1, 0, + 0, 128, 3, 0, 0, 176, + 5, 0, 0, 3, 1, 0, + 2, 128, 0, 0, 85, 128, + 3, 0, 0, 176, 66, 0, + 0, 3, 0, 0, 15, 128, + 2, 0, 228, 176, 0, 8, + 228, 160, 5, 0, 0, 3, + 1, 0, 4, 128, 0, 0, + 170, 128, 3, 0, 0, 176, + 1, 0, 0, 2, 1, 0, + 8, 128, 0, 0, 0, 160, + 1, 0, 0, 2, 0, 8, + 15, 128, 1, 0, 228, 128, + 255, 255, 0, 0, 83, 72, + 68, 82, 64, 1, 0, 0, + 64, 0, 0, 0, 80, 0, + 0, 0, 90, 0, 0, 3, + 0, 96, 16, 0, 0, 0, + 0, 0, 88, 24, 0, 4, + 0, 112, 16, 0, 0, 0, + 0, 0, 85, 85, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 1, 0, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 2, 0, 0, 0, + 98, 16, 0, 3, 50, 16, + 16, 0, 3, 0, 0, 0, + 98, 16, 0, 3, 18, 16, + 16, 0, 4, 0, 0, 0, + 101, 0, 0, 3, 242, 32, + 16, 0, 0, 0, 0, 0, + 104, 0, 0, 2, 1, 0, + 0, 0, 69, 0, 0, 9, + 242, 0, 16, 0, 0, 0, + 0, 0, 70, 16, 16, 0, + 1, 0, 0, 0, 70, 126, + 16, 0, 0, 0, 0, 0, + 0, 96, 16, 0, 0, 0, + 0, 0, 56, 0, 0, 7, + 18, 32, 16, 0, 0, 0, + 0, 0, 10, 0, 16, 0, + 0, 0, 0, 0, 10, 16, + 16, 0, 4, 0, 0, 0, + 69, 0, 0, 9, 242, 0, + 16, 0, 0, 0, 0, 0, + 70, 16, 16, 0, 2, 0, + 0, 0, 70, 126, 16, 0, + 0, 0, 0, 0, 0, 96, + 16, 0, 0, 0, 0, 0, + 56, 0, 0, 7, 34, 32, + 16, 0, 0, 0, 0, 0, + 26, 0, 16, 0, 0, 0, + 0, 0, 10, 16, 16, 0, + 4, 0, 0, 0, 69, 0, + 0, 9, 242, 0, 16, 0, + 0, 0, 0, 0, 70, 16, + 16, 0, 3, 0, 0, 0, + 70, 126, 16, 0, 0, 0, + 0, 0, 0, 96, 16, 0, + 0, 0, 0, 0, 56, 0, + 0, 7, 66, 32, 16, 0, + 0, 0, 0, 0, 42, 0, + 16, 0, 0, 0, 0, 0, + 10, 16, 16, 0, 4, 0, + 0, 0, 54, 0, 0, 5, + 130, 32, 16, 0, 0, 0, + 0, 0, 1, 64, 0, 0, + 0, 0, 128, 63, 62, 0, + 0, 1, 83, 84, 65, 84, + 116, 0, 0, 0, 8, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 5, 0, + 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 82, 68, 69, 70, 160, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, + 0, 0, 28, 0, 0, 0, + 0, 4, 255, 255, 0, 1, + 0, 0, 107, 0, 0, 0, + 92, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, + 0, 0, 99, 0, 0, 0, + 2, 0, 0, 0, 5, 0, + 0, 0, 4, 0, 0, 0, + 255, 255, 255, 255, 0, 0, + 0, 0, 1, 0, 0, 0, + 13, 0, 0, 0, 76, 105, + 110, 101, 97, 114, 0, 84, + 101, 120, 116, 117, 114, 101, + 0, 77, 105, 99, 114, 111, + 115, 111, 102, 116, 32, 40, + 82, 41, 32, 72, 76, 83, + 76, 32, 83, 104, 97, 100, + 101, 114, 32, 67, 111, 109, + 112, 105, 108, 101, 114, 32, + 57, 46, 51, 48, 46, 57, + 50, 48, 48, 46, 50, 48, + 53, 52, 54, 0, 171, 171, + 73, 83, 71, 78, 156, 0, + 0, 0, 5, 0, 0, 0, + 8, 0, 0, 0, 128, 0, + 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, + 0, 0, 0, 0, 0, 0, + 15, 0, 0, 0, 140, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, + 7, 3, 0, 0, 140, 0, + 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 2, 0, 0, 0, + 7, 3, 0, 0, 140, 0, + 0, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 3, 0, 0, 0, + 7, 3, 0, 0, 149, 0, + 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3, 0, + 0, 0, 4, 0, 0, 0, + 15, 1, 0, 0, 83, 86, + 95, 80, 111, 115, 105, 116, + 105, 111, 110, 0, 84, 69, + 88, 67, 79, 79, 82, 68, + 0, 67, 79, 76, 79, 82, + 0, 171, 79, 83, 71, 78, + 44, 0, 0, 0, 1, 0, + 0, 0, 8, 0, 0, 0, + 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + 3, 0, 0, 0, 0, 0, + 0, 0, 15, 0, 0, 0, + 83, 86, 95, 84, 97, 114, + 103, 101, 116, 0, 171, 171 +}; From e80e04cd172b33d28a8aca1ed3608043987dda6e Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Wed, 9 Jul 2014 12:28:27 -0700 Subject: [PATCH 007/183] Bug 1036602 - Add GL support for VR rendering; r=BenWa From aec0bd50768482fe516111010bad2e57f01ede36 Mon Sep 17 00:00:00 2001 --- gfx/layers/moz.build | 1 + gfx/layers/opengl/CompositingRenderTargetOGL.h | 4 + gfx/layers/opengl/CompositorOGL.cpp | 14 ++ gfx/layers/opengl/CompositorOGL.h | 38 +++ gfx/layers/opengl/CompositorOGLVR.cpp | 326 +++++++++++++++++++++++++ 5 files changed, 383 insertions(+) create mode 100644 gfx/layers/opengl/CompositorOGLVR.cpp --- gfx/layers/moz.build | 1 + .../opengl/CompositingRenderTargetOGL.h | 4 + gfx/layers/opengl/CompositorOGL.cpp | 14 + gfx/layers/opengl/CompositorOGL.h | 38 ++ gfx/layers/opengl/CompositorOGLVR.cpp | 326 ++++++++++++++++++ 5 files changed, 383 insertions(+) create mode 100644 gfx/layers/opengl/CompositorOGLVR.cpp diff --git a/gfx/layers/moz.build b/gfx/layers/moz.build index f326c9e72b0b..5d3437237d84 100644 --- a/gfx/layers/moz.build +++ b/gfx/layers/moz.build @@ -317,6 +317,7 @@ UNIFIED_SOURCES += [ 'LayerSorter.cpp', 'opengl/CompositingRenderTargetOGL.cpp', 'opengl/CompositorOGL.cpp', + 'opengl/CompositorOGLVR.cpp', 'opengl/GLBlitTextureImageHelper.cpp', 'opengl/OGLShaderProgram.cpp', 'opengl/TextureClientOGL.cpp', diff --git a/gfx/layers/opengl/CompositingRenderTargetOGL.h b/gfx/layers/opengl/CompositingRenderTargetOGL.h index 0cb5f14498e0..46430df554fd 100644 --- a/gfx/layers/opengl/CompositingRenderTargetOGL.h +++ b/gfx/layers/opengl/CompositingRenderTargetOGL.h @@ -149,6 +149,10 @@ public: virtual TemporaryRef Dump(Compositor* aCompositor); #endif + const gfx::IntSize& GetInitSize() const { + return mInitParams.mSize; + } + private: /** * Actually do the initialisation. Note that we leave our FBO bound, and so diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 6dde2bc3a053..121c42bc942e 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -175,6 +175,8 @@ CompositorOGL::CleanupResources() mQuadVBO = 0; } + DestroyVR(ctx); + mGLContext->MakeCurrent(); mBlitTextureImageHelper = nullptr; @@ -384,6 +386,13 @@ CompositorOGL::Initialize() console->LogStringMessage(msg.get()); } + mVR.mInitialized = false; + if (gfxPrefs::VREnabled()) { + if (!InitializeVR()) { + NS_WARNING("Failed to initialize VR in CompositorOGL"); + } + } + reporter.SetSuccessful(); return true; } @@ -889,6 +898,11 @@ CompositorOGL::DrawQuad(const Rect& aRect, MOZ_ASSERT(mFrameInProgress, "frame not started"); MOZ_ASSERT(mCurrentRenderTarget, "No destination"); + if (aEffectChain.mPrimaryEffect->mType == EffectTypes::VR_DISTORTION) { + DrawVRDistortion(aRect, aClipRect, aEffectChain, aOpacity, aTransform); + return; + } + Rect clipRect = aClipRect; // aClipRect is in destination coordinate space (after all // transforms and offsets have been applied) so if our diff --git a/gfx/layers/opengl/CompositorOGL.h b/gfx/layers/opengl/CompositorOGL.h index 6cef4f62ade7..372c1b9dabe0 100644 --- a/gfx/layers/opengl/CompositorOGL.h +++ b/gfx/layers/opengl/CompositorOGL.h @@ -35,6 +35,7 @@ #ifdef MOZ_WIDGET_GONK #include #endif +#include "gfxVR.h" class nsIWidget; @@ -153,6 +154,32 @@ protected: nsTArray mUnusedTextures; }; +struct CompositorOGLVRObjects { + bool mInitialized; + + gfx::VRHMDConfiguration mConfiguration; + + GLuint mDistortionVertices[2]; + GLuint mDistortionIndices[2]; + GLuint mDistortionIndexCount[2]; + + GLint mAPosition; + GLint mATexCoord0; + GLint mATexCoord1; + GLint mATexCoord2; + GLint mAGenericAttribs; + + // The program here implements distortion rendering for VR devices + // (in this case Oculus only). We'll need to extend this to support + // other device types in the future. + + // 0 = TEXTURE_2D, 1 = TEXTURE_RECTANGLE for source + GLuint mDistortionProgram[2]; + GLint mUTexture[2]; + GLint mUVREyeToSource[2]; + GLint mUVRDestionatinScaleAndOffset[2]; +}; + // If you want to make this class not MOZ_FINAL, first remove calls to virtual // methods (Destroy) that are made in the destructor. class CompositorOGL MOZ_FINAL : public Compositor @@ -283,6 +310,15 @@ private: return gfx::ToIntSize(mWidgetSize); } + bool InitializeVR(); + void DestroyVR(GLContext *gl); + + void DrawVRDistortion(const gfx::Rect& aRect, + const gfx::Rect& aClipRect, + const EffectChain& aEffectChain, + gfx::Float aOpacity, + const gfx::Matrix4x4& aTransform); + /** Widget associated with this compositor */ nsIWidget *mWidget; nsIntSize mWidgetSize; @@ -409,6 +445,8 @@ private: FenceHandle mReleaseFenceHandle; ShaderProgramOGL *mCurrentProgram; + + CompositorOGLVRObjects mVR; }; } diff --git a/gfx/layers/opengl/CompositorOGLVR.cpp b/gfx/layers/opengl/CompositorOGLVR.cpp new file mode 100644 index 000000000000..3022e7e342c1 --- /dev/null +++ b/gfx/layers/opengl/CompositorOGLVR.cpp @@ -0,0 +1,326 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CompositorOGL.h" +#include // for ostringstream +#include // for size_t +#include // for uint32_t, uint8_t +#include // for free, malloc +#include "mozilla/layers/LayerManagerComposite.h" // for LayerComposite, etc +#include "mozilla/layers/Effects.h" // for EffectChain, TexturedEffect, etc +#include "mozilla/layers/CompositingRenderTargetOGL.h" +#include "mozilla/layers/TextureHost.h" // for TextureSource, etc +#include "mozilla/layers/TextureHostOGL.h" // for TextureSourceOGL, etc +#include "GLContextProvider.h" // for GLContextProvider +#include "GLContext.h" // for GLContext +#include "GLUploadHelpers.h" +#include "Layers.h" // for WriteSnapshotToDumpFile +#include "LayerScope.h" // for LayerScope +#include "gfx2DGlue.h" // for ThebesFilter +#include "gfx3DMatrix.h" // for gfx3DMatrix +#include "gfxCrashReporterUtils.h" // for ScopedGfxFeatureReporter +#include "gfxMatrix.h" // for gfxMatrix +#include "GraphicsFilter.h" // for GraphicsFilter +#include "gfxPlatform.h" // for gfxPlatform +#include "gfxPrefs.h" // for gfxPrefs +#include "gfxRect.h" // for gfxRect +#include "gfxUtils.h" // for NextPowerOfTwo, gfxUtils, etc +#include "gfxVR.h" + +namespace mozilla { + +using namespace std; +using namespace gfx; + +namespace layers { + +using namespace mozilla::gl; + +bool +CompositorOGL::InitializeVR() +{ + gl()->fGenBuffers(2, mVR.mDistortionVertices); + gl()->fGenBuffers(2, mVR.mDistortionIndices); + + // these are explicitly bound later + mVR.mAPosition = 0; + mVR.mATexCoord0 = 1; + mVR.mATexCoord1 = 2; + mVR.mATexCoord2 = 3; + mVR.mAGenericAttribs = 4; + + ostringstream vs; + + vs << "uniform vec4 uVREyeToSource;\n"; + vs << "uniform vec4 uVRDestinationScaleAndOffset;\n"; + vs << "attribute vec2 aPosition;\n"; + vs << "attribute vec2 aTexCoord0;\n"; + vs << "attribute vec2 aTexCoord1;\n"; + vs << "attribute vec2 aTexCoord2;\n"; + vs << "attribute vec4 aGenericAttribs;\n"; + vs << "varying vec2 vTexCoord0;\n"; + vs << "varying vec2 vTexCoord1;\n"; + vs << "varying vec2 vTexCoord2;\n"; + vs << "varying vec4 vGenericAttribs;\n"; + vs << "void main() {\n"; + vs << " gl_Position = vec4(aPosition.xy * uVRDestinationScaleAndOffset.zw + uVRDestinationScaleAndOffset.xy, 0.5, 1.0);\n"; + vs << " vTexCoord0 = uVREyeToSource.xy * aTexCoord0 + uVREyeToSource.zw;\n"; + vs << " vTexCoord1 = uVREyeToSource.xy * aTexCoord1 + uVREyeToSource.zw;\n"; + vs << " vTexCoord2 = uVREyeToSource.xy * aTexCoord2 + uVREyeToSource.zw;\n"; + vs << " vTexCoord0.y = 1.0 - vTexCoord0.y;\n"; + vs << " vTexCoord1.y = 1.0 - vTexCoord1.y;\n"; + vs << " vTexCoord2.y = 1.0 - vTexCoord2.y;\n"; + vs << " vGenericAttribs = aGenericAttribs;\n"; + vs << "}\n"; + + std::string vsSrcString(vs.str()); + const char *vsSrc = vsSrcString.c_str(); + + for (int programIndex = 0; programIndex < 2; programIndex++) { + GLenum textureTarget = programIndex == 0 ? LOCAL_GL_TEXTURE_2D : LOCAL_GL_TEXTURE_RECTANGLE; + + const char *sampler2D = "sampler2D"; + const char *texture2D = "texture2D"; + + ostringstream fs; + + if (textureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) { + fs << "#extension GL_ARB_texture_rectangle : require\n"; + sampler2D = "sampler2DRect"; + texture2D = "texture2DRect"; + } + + if (gl()->IsGLES()) { + fs << "precision highp float;\n"; + } + + fs << "uniform " << sampler2D << " uTexture;\n"; + + fs << "varying vec2 vTexCoord0;\n"; + fs << "varying vec2 vTexCoord1;\n"; + fs << "varying vec2 vTexCoord2;\n"; + fs << "varying vec4 vGenericAttribs;\n"; + fs << "void main() {\n"; + fs << " float resR = " << texture2D << "(uTexture, vTexCoord0.xy).r;\n"; + fs << " float resG = " << texture2D << "(uTexture, vTexCoord1.xy).g;\n"; + fs << " float resB = " << texture2D << "(uTexture, vTexCoord2.xy).b;\n"; + fs << " gl_FragColor = vec4(resR * vGenericAttribs.r, resG * vGenericAttribs.r, resB * vGenericAttribs.r, 1.0);\n"; + fs << "}\n"; + + std::string fsSrcString(fs.str()); + const char *fsSrc = fsSrcString.c_str(); + + GLint status; +#ifdef DEBUG + GLint length; + nsCString logStr; +#endif + + GLuint shaders[2]; + shaders[0] = gl()->fCreateShader(LOCAL_GL_VERTEX_SHADER); + shaders[1] = gl()->fCreateShader(LOCAL_GL_FRAGMENT_SHADER); + + GLint shaderLen[2] = { (GLint) strlen(vsSrc), (GLint) strlen(fsSrc) }; + gl()->fShaderSource(shaders[0], 1, &vsSrc, &shaderLen[0]); + gl()->fShaderSource(shaders[1], 1, &fsSrc, &shaderLen[1]); + + for (int k = 0; k < 2; ++k) { + gl()->fCompileShader(shaders[k]); + gl()->fGetShaderiv(shaders[k], LOCAL_GL_COMPILE_STATUS, &status); + if (!status) { + NS_WARNING("VR GL shader failed to compile!"); + +#ifdef DEBUG + gl()->fGetShaderiv(shaders[k], LOCAL_GL_INFO_LOG_LENGTH, &length); + logStr.SetLength(length); + gl()->fGetShaderInfoLog(shaders[k], length, &length, logStr.BeginWriting()); + printf_stderr("GL %s shader failed to compile:\n%s\n", k == 0 ? "vertex" : "fragment", logStr.BeginReading()); +#endif + + gl()->fDeleteShader(shaders[0]); + gl()->fDeleteShader(shaders[1]); + + return false; + } + } + + GLuint prog = gl()->fCreateProgram(); + gl()->fAttachShader(prog, shaders[0]); + gl()->fAttachShader(prog, shaders[1]); + + gl()->fBindAttribLocation(prog, mVR.mAPosition, "aPosition"); + gl()->fBindAttribLocation(prog, mVR.mATexCoord0, "aTexCoord0"); + gl()->fBindAttribLocation(prog, mVR.mATexCoord1, "aTexCoord1"); + gl()->fBindAttribLocation(prog, mVR.mATexCoord2, "aTexCoord2"); + gl()->fBindAttribLocation(prog, mVR.mAGenericAttribs, "aGenericAttribs"); + + gl()->fLinkProgram(prog); + + gl()->fGetProgramiv(prog, LOCAL_GL_LINK_STATUS, &status); + if (!status) { + NS_WARNING("VR GL program failed to link!"); + +#ifdef DEBUG + gl()->fGetProgramiv(prog, LOCAL_GL_INFO_LOG_LENGTH, &length); + logStr.SetLength(length); + gl()->fGetProgramInfoLog(prog, length, &length, logStr.BeginWriting()); + printf_stderr("GL shader failed to link:\n%s\n", logStr.BeginReading()); +#endif + + gl()->fDeleteProgram(prog); + gl()->fDeleteShader(shaders[0]); + gl()->fDeleteShader(shaders[1]); + + return false; + } + + mVR.mUTexture[programIndex] = gl()->fGetUniformLocation(prog, "uTexture"); + mVR.mUVREyeToSource[programIndex] = gl()->fGetUniformLocation(prog, "uVREyeToSource"); + mVR.mUVRDestionatinScaleAndOffset[programIndex] = gl()->fGetUniformLocation(prog, "uVRDestinationScaleAndOffset"); + + mVR.mDistortionProgram[programIndex] = prog; + + gl()->fDeleteShader(shaders[0]); + gl()->fDeleteShader(shaders[1]); + } + + mVR.mInitialized = true; + return true; +} + +void +CompositorOGL::DestroyVR(GLContext *gl) +{ + if (!mVR.mInitialized) + return; + + gl->fDeleteBuffers(2, mVR.mDistortionVertices); + gl->fDeleteBuffers(2, mVR.mDistortionIndices); + gl->fDeleteProgram(mVR.mDistortionProgram[0]); + gl->fDeleteProgram(mVR.mDistortionProgram[1]); + + mVR.mInitialized = false; +} + +void +CompositorOGL::DrawVRDistortion(const gfx::Rect& aRect, + const gfx::Rect& aClipRect, + const EffectChain& aEffectChain, + gfx::Float aOpacity, + const gfx::Matrix4x4& aTransform) +{ + MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EffectTypes::VR_DISTORTION); + MOZ_ASSERT(mVR.mInitialized); + + if (aEffectChain.mSecondaryEffects[EffectTypes::MASK] || + aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) + { + NS_WARNING("DrawVRDistortion: ignoring secondary effect!"); + } + + EffectVRDistortion* vrEffect = + static_cast(aEffectChain.mPrimaryEffect.get()); + + GLenum textureTarget = LOCAL_GL_TEXTURE_2D; + if (vrEffect->mRenderTarget) + textureTarget = mFBOTextureTarget; + + RefPtr surface = + static_cast(vrEffect->mRenderTarget.get()); + + gfx::IntSize size = surface->GetInitSize(); // XXX source->GetSize() + + VRHMDInfo* hmdInfo = vrEffect->mHMD; + VRDistortionConstants shaderConstants; + + if (hmdInfo->GetConfiguration() != mVR.mConfiguration) { + for (uint32_t eye = 0; eye < 2; eye++) { + const gfx::VRDistortionMesh& mesh = hmdInfo->GetDistortionMesh(eye); + gl()->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVR.mDistortionVertices[eye]); + gl()->fBufferData(LOCAL_GL_ARRAY_BUFFER, + mesh.mVertices.Length() * sizeof(gfx::VRDistortionVertex), + mesh.mVertices.Elements(), + LOCAL_GL_STATIC_DRAW); + + gl()->fBindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mVR.mDistortionIndices[eye]); + gl()->fBufferData(LOCAL_GL_ELEMENT_ARRAY_BUFFER, + mesh.mIndices.Length() * sizeof(uint16_t), + mesh.mIndices.Elements(), + LOCAL_GL_STATIC_DRAW); + + mVR.mDistortionIndexCount[eye] = mesh.mIndices.Length(); + } + + mVR.mConfiguration = hmdInfo->GetConfiguration(); + } + + int programIndex = textureTarget == LOCAL_GL_TEXTURE_2D ? 0 : 1; + + gl()->fScissor(aClipRect.x, FlipY(aClipRect.y + aClipRect.height), + aClipRect.width, aClipRect.height); + + // Clear out the entire area that we want to render; this ensures that + // the layer will be opaque, even though the mesh geometry we'll be + // drawing below won't cover the full rectangle. + gl()->fClearColor(0.0, 0.0, 0.0, 1.0); + gl()->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT); + + gl()->fUseProgram(mVR.mDistortionProgram[programIndex]); + + gl()->fEnableVertexAttribArray(mVR.mAPosition); + gl()->fEnableVertexAttribArray(mVR.mATexCoord0); + gl()->fEnableVertexAttribArray(mVR.mATexCoord1); + gl()->fEnableVertexAttribArray(mVR.mATexCoord2); + gl()->fEnableVertexAttribArray(mVR.mAGenericAttribs); + + surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget); + gl()->fUniform1i(mVR.mUTexture[programIndex], 0); + + gfx::IntSize vpSizeInt = mCurrentRenderTarget->GetInitSize(); + gfx::Size vpSize(vpSizeInt.width, vpSizeInt.height); + + for (uint32_t eye = 0; eye < 2; eye++) { + gfx::IntRect eyeViewport; + eyeViewport.x = eye * size.width / 2; + eyeViewport.y = 0; + eyeViewport.width = size.width / 2; + eyeViewport.height = size.height; + + hmdInfo->FillDistortionConstants(eye, + size, eyeViewport, + vpSize, aRect, + shaderConstants); + + gl()->fUniform4fv(mVR.mUVRDestionatinScaleAndOffset[programIndex], 1, shaderConstants.destinationScaleAndOffset); + gl()->fUniform4fv(mVR.mUVREyeToSource[programIndex], 1, shaderConstants.eyeToSourceScaleAndOffset); + + gl()->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVR.mDistortionVertices[eye]); + + gl()->fVertexAttribPointer(mVR.mAPosition, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), + (void*) offsetof(gfx::VRDistortionVertex, pos)); + gl()->fVertexAttribPointer(mVR.mATexCoord0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), + (void*) offsetof(gfx::VRDistortionVertex, texR)); + gl()->fVertexAttribPointer(mVR.mATexCoord1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), + (void*) offsetof(gfx::VRDistortionVertex, texG)); + gl()->fVertexAttribPointer(mVR.mATexCoord2, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), + (void*) offsetof(gfx::VRDistortionVertex, texB)); + gl()->fVertexAttribPointer(mVR.mAGenericAttribs, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), + (void*) offsetof(gfx::VRDistortionVertex, genericAttribs)); + + gl()->fBindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mVR.mDistortionIndices[eye]); + gl()->fDrawElements(LOCAL_GL_TRIANGLES, mVR.mDistortionIndexCount[eye], LOCAL_GL_UNSIGNED_SHORT, 0); + } + + // Not clear if I should disable all of this; but going to do it and hope that + // any later code will enable what it needs. + gl()->fDisableVertexAttribArray(mVR.mAPosition); + gl()->fDisableVertexAttribArray(mVR.mATexCoord0); + gl()->fDisableVertexAttribArray(mVR.mATexCoord1); + gl()->fDisableVertexAttribArray(mVR.mATexCoord2); + gl()->fDisableVertexAttribArray(mVR.mAGenericAttribs); +} + +} +} From 82c98fdc63b67168497f8cc342666a416fc216d1 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Thu, 18 Dec 2014 00:18:35 -0500 Subject: [PATCH 008/183] Bug 1113242 - Load Oculus VR support libs from location specified in prefs From d4d1705a879295f9530da436fa437b1452c1768e Mon Sep 17 00:00:00 2001 --- gfx/thebes/gfxVR.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) --- gfx/thebes/gfxVR.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gfx/thebes/gfxVR.cpp b/gfx/thebes/gfxVR.cpp index a73466c5f158..27907a5e0230 100644 --- a/gfx/thebes/gfxVR.cpp +++ b/gfx/thebes/gfxVR.cpp @@ -10,6 +10,7 @@ #include "prenv.h" #include "gfxPrefs.h" #include "gfxVR.h" +#include "mozilla/Preferences.h" #include "ovr_capi_dynamic.h" @@ -76,12 +77,19 @@ InitializeOculusCAPI() if (!ovrlib) { const char *libName = OVR_LIB_NAME; + // If the pref is present, we override libName + nsAdoptingCString prefLibName = Preferences::GetCString("dom.vr.ovr_lib_path"); + if (prefLibName && prefLibName.get()) { + libName = prefLibName.get(); + } + + // If the env var is present, we override libName if (PR_GetEnv("OVR_LIB_NAME")) { libName = PR_GetEnv("OVR_LIB_NAME"); } if (!libName) { - printf_stderr("Don't know how to find Oculus VR library; missing OVR_LIB_NAME\n"); + printf_stderr("Don't know how to find Oculus VR library; missing dom.vr.ovr_lib_path or OVR_LIB_NAME\n"); return false; } From b59e740e248324239285e3a9aa3d834088209621 Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Thu, 18 Dec 2014 14:58:09 -0500 Subject: [PATCH 009/183] Bug 1113242 - followup; fix missing namespace - CLOSED TREE --HG-- extra : amend_source : 150f66d2444e56f30562265236080835fe1ffc58 --- gfx/thebes/gfxVR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/thebes/gfxVR.cpp b/gfx/thebes/gfxVR.cpp index 27907a5e0230..c402c1b3f1f0 100644 --- a/gfx/thebes/gfxVR.cpp +++ b/gfx/thebes/gfxVR.cpp @@ -78,7 +78,7 @@ InitializeOculusCAPI() const char *libName = OVR_LIB_NAME; // If the pref is present, we override libName - nsAdoptingCString prefLibName = Preferences::GetCString("dom.vr.ovr_lib_path"); + nsAdoptingCString prefLibName = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path"); if (prefLibName && prefLibName.get()) { libName = prefLibName.get(); } From 6f4182dd43a5ce0eb7e2abf3d1b3614ea08a558b Mon Sep 17 00:00:00 2001 From: Vladimir Vukicevic Date: Thu, 18 Dec 2014 15:08:45 -0500 Subject: [PATCH 010/183] Bug 1113242 - followup; fix missing include, just in case - CLOSED TREE --- gfx/thebes/gfxVR.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/thebes/gfxVR.cpp b/gfx/thebes/gfxVR.cpp index c402c1b3f1f0..a750cbf3f04b 100644 --- a/gfx/thebes/gfxVR.cpp +++ b/gfx/thebes/gfxVR.cpp @@ -10,6 +10,7 @@ #include "prenv.h" #include "gfxPrefs.h" #include "gfxVR.h" +#include "nsString.h" #include "mozilla/Preferences.h" #include "ovr_capi_dynamic.h" From 8a94c3960bb6d6220db5c82d7d714e3e643fb307 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 18 Dec 2014 15:26:05 -0500 Subject: [PATCH 011/183] Backed out changeset f0d4cb5f206c (bug 1112827) for Mulet permacrashing. --- ipc/ipdl/ipdl/lower.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index 031b15e14ed1..3bb885b11d6e 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -1329,15 +1329,7 @@ with some new IPDL/C++ nodes that are tuned for C++ codegen.""" # fully-qualified name. e.g. |Foo| rather than |a::b::Foo|. self.typedefs = [ ] self.typedefSet = set([ Typedef(Type('mozilla::ipc::ActorHandle'), - 'ActorHandle'), - Typedef(Type('base::ProcessId'), - 'ProcessId'), - Typedef(Type('mozilla::ipc::ProtocolId'), - 'ProtocolId'), - Typedef(Type('mozilla::ipc::Transport'), - 'Transport'), - Typedef(Type('mozilla::ipc::TransportDescriptor'), - 'TransportDescriptor') ]) + 'ActorHandle') ]) self.protocolName = None def visitTranslationUnit(self, tu): @@ -2795,6 +2787,14 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): self.cls.addstmt(typedef) for typedef in self.includedActorTypedefs: self.cls.addstmt(typedef) + # XXX these don't really fit in the other lists; just include + # them here for now + self.cls.addstmts([ + Typedef(Type('base::ProcessId'), 'ProcessId'), + Typedef(Type('mozilla::ipc::ProtocolId'), 'ProtocolId'), + Typedef(Type('mozilla::ipc::Transport'), 'Transport'), + Typedef(Type('mozilla::ipc::TransportDescriptor'), 'TransportDescriptor') + ]) self.cls.addstmt(Whitespace.NL) From b791aba21ceecbcc25f57e64a619bf63de2eba03 Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 18 Dec 2014 15:25:15 -0500 Subject: [PATCH 012/183] Bug 867348 - Part 1: Add an analysis that catches calls to certain functions involving arithmetic expressions; r=jrmuizel --HG-- extra : rebase_source : d89b16b9ab591479400a3e5e89b217a67319669d --- build/clang-plugin/clang-plugin.cpp | 83 +++++++++++++++++++ .../tests/TestNoArithmeticExprInArgument.cpp | 32 +++++++ build/clang-plugin/tests/moz.build | 1 + 3 files changed, 116 insertions(+) create mode 100644 build/clang-plugin/tests/TestNoArithmeticExprInArgument.cpp diff --git a/build/clang-plugin/clang-plugin.cpp b/build/clang-plugin/clang-plugin.cpp index f28c9fecbdc2..c75ce62f3490 100644 --- a/build/clang-plugin/clang-plugin.cpp +++ b/build/clang-plugin/clang-plugin.cpp @@ -329,6 +329,49 @@ AST_MATCHER(QualType, nonheapClassAggregate) { AST_MATCHER(FunctionDecl, heapAllocator) { return MozChecker::hasCustomAnnotation(&Node, "moz_heap_allocator"); } + +/// This matcher will match any declaration that is marked as not accepting +/// arithmetic expressions in its arguments. +AST_MATCHER(Decl, noArithmeticExprInArgs) { + return MozChecker::hasCustomAnnotation(&Node, "moz_no_arith_expr_in_arg"); +} + +/// This matcher will match all arithmetic binary operators. +AST_MATCHER(BinaryOperator, binaryArithmeticOperator) { + BinaryOperatorKind opcode = Node.getOpcode(); + return opcode == BO_Mul || + opcode == BO_Div || + opcode == BO_Rem || + opcode == BO_Add || + opcode == BO_Sub || + opcode == BO_Shl || + opcode == BO_Shr || + opcode == BO_And || + opcode == BO_Xor || + opcode == BO_Or || + opcode == BO_MulAssign || + opcode == BO_DivAssign || + opcode == BO_RemAssign || + opcode == BO_AddAssign || + opcode == BO_SubAssign || + opcode == BO_ShlAssign || + opcode == BO_ShrAssign || + opcode == BO_AndAssign || + opcode == BO_XorAssign || + opcode == BO_OrAssign; +} + +/// This matcher will match all arithmetic unary operators. +AST_MATCHER(UnaryOperator, unaryArithmeticOperator) { + UnaryOperatorKind opcode = Node.getOpcode(); + return opcode == UO_PostInc || + opcode == UO_PostDec || + opcode == UO_PreInc || + opcode == UO_PreDec || + opcode == UO_Plus || + opcode == UO_Minus || + opcode == UO_Not; +} } } @@ -367,6 +410,33 @@ DiagnosticsMatcher::DiagnosticsMatcher() { astMatcher.addMatcher(callExpr(callee(functionDecl(allOf(heapAllocator(), returns(pointerType(pointee(stackClassAggregate()))))))).bind("node"), &stackClassChecker); + + astMatcher.addMatcher(callExpr(allOf(hasDeclaration(noArithmeticExprInArgs()), + anyOf( + hasDescendant(binaryOperator(allOf(binaryArithmeticOperator(), + hasLHS(hasDescendant(declRefExpr())), + hasRHS(hasDescendant(declRefExpr())) + )).bind("node")), + hasDescendant(unaryOperator(allOf(unaryArithmeticOperator(), + hasUnaryOperand(allOf(hasType(builtinType()), + anyOf(hasDescendant(declRefExpr()), declRefExpr()))) + )).bind("node")) + ) + )).bind("call"), + &arithmeticArgChecker); + astMatcher.addMatcher(constructExpr(allOf(hasDeclaration(noArithmeticExprInArgs()), + anyOf( + hasDescendant(binaryOperator(allOf(binaryArithmeticOperator(), + hasLHS(hasDescendant(declRefExpr())), + hasRHS(hasDescendant(declRefExpr())) + )).bind("node")), + hasDescendant(unaryOperator(allOf(unaryArithmeticOperator(), + hasUnaryOperand(allOf(hasType(builtinType()), + anyOf(hasDescendant(declRefExpr()), declRefExpr()))) + )).bind("node")) + ) + )).bind("call"), + &arithmeticArgChecker); } void DiagnosticsMatcher::StackClassChecker::run( @@ -472,6 +542,19 @@ void DiagnosticsMatcher::NonHeapClassChecker::noteInferred(QualType T, noteInferred(cast(cause)->getType(), Diag); } +void DiagnosticsMatcher::ArithmeticArgChecker::run( + const MatchFinder::MatchResult &Result) { + DiagnosticsEngine &Diag = Result.Context->getDiagnostics(); + unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID( + DiagnosticIDs::Error, "cannot pass an arithmetic expression of built-in types to %0"); + const Expr *expr = Result.Nodes.getNodeAs("node"); + if (const CallExpr *call = Result.Nodes.getNodeAs("call")) { + Diag.Report(expr->getLocStart(), errorID) << call->getDirectCallee(); + } else if (const CXXConstructExpr *ctr = Result.Nodes.getNodeAs("call")) { + Diag.Report(expr->getLocStart(), errorID) << ctr->getConstructor(); + } +} + class MozCheckAction : public PluginASTAction { public: ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI, StringRef fileName) override { diff --git a/build/clang-plugin/tests/TestNoArithmeticExprInArgument.cpp b/build/clang-plugin/tests/TestNoArithmeticExprInArgument.cpp new file mode 100644 index 000000000000..96f46c2ff41d --- /dev/null +++ b/build/clang-plugin/tests/TestNoArithmeticExprInArgument.cpp @@ -0,0 +1,32 @@ +#define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg"))) + +struct X { + explicit X(int) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT; + void baz(int) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT; +}; + +int operator+(int, X); +int operator+(X, int); +int operator++(X); + +void badArithmeticsInArgs() { + int a; + typedef int myint; + myint b; + X goodObj1(a); + goodObj1.baz(b); + X badObj1(a + b); // expected-error{{cannot pass an arithmetic expression of built-in types to 'X'}} + X badObj2 = X(a ? 0 : ++a); // expected-error{{cannot pass an arithmetic expression of built-in types to 'X'}} + X badObj3(~a); // expected-error{{cannot pass an arithmetic expression of built-in types to 'X'}} + badObj1.baz(a - 1 - b); // expected-error{{cannot pass an arithmetic expression of built-in types to 'baz'}} + badObj1.baz(++a); // expected-error{{cannot pass an arithmetic expression of built-in types to 'baz'}} + badObj1.baz(a++); // expected-error{{cannot pass an arithmetic expression of built-in types to 'baz'}} + badObj1.baz(a || b); + badObj1.baz(a + goodObj1); + badObj1.baz(goodObj1 + a); + badObj1.baz(++goodObj1); + badObj1.baz(-1); + badObj1.baz(-1.0); + badObj1.baz(1 + 2); + badObj1.baz(1 << (sizeof(int)/2)); +} diff --git a/build/clang-plugin/tests/moz.build b/build/clang-plugin/tests/moz.build index 4066642f13e5..d2c78a93638c 100644 --- a/build/clang-plugin/tests/moz.build +++ b/build/clang-plugin/tests/moz.build @@ -8,6 +8,7 @@ SOURCES += [ 'TestBadImplicitConversionCtor.cpp', 'TestCustomHeap.cpp', 'TestMustOverride.cpp', + 'TestNoArithmeticExprInArgument.cpp', 'TestNonHeapClass.cpp', 'TestStackClass.cpp', ] From 2e80a8882067ba7b037d8ede36ad213de326246a Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Thu, 18 Dec 2014 15:27:05 -0500 Subject: [PATCH 013/183] Bug 867348 - Part 2: Apply MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT to CheckedInt's constructor; r=jrmuizel Note that the analysis currently just looks at the AST subtree of the function call site and is therefore unable to correctly deal with cases such as the last two hunks of the change to OggCodecState.cpp. Fixing the analysis to deal with that would be very difficult, so we currently adjust the code so that it compiles. The first hunk in that file though is a real bug that this analysis found. --HG-- extra : rebase_source : b44bb6d90d95551d860e0b5a1afcf2bb35cde084 --- dom/media/ogg/OggCodecState.cpp | 8 +++++--- mfbt/Attributes.h | 4 ++++ mfbt/CheckedInt.h | 3 ++- mfbt/tests/TestCheckedInt.cpp | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/dom/media/ogg/OggCodecState.cpp b/dom/media/ogg/OggCodecState.cpp index 58871bc8af7d..acba322a0500 100644 --- a/dom/media/ogg/OggCodecState.cpp +++ b/dom/media/ogg/OggCodecState.cpp @@ -936,7 +936,7 @@ int64_t OpusState::Time(int aPreSkip, int64_t aGranulepos) return -1; // Ogg Opus always runs at a granule rate of 48 kHz. - CheckedInt64 t = CheckedInt64(aGranulepos - aPreSkip) * USECS_PER_S; + CheckedInt64 t = (CheckedInt64(aGranulepos) - aPreSkip) * USECS_PER_S; return t.isValid() ? t.value() / 48000 : -1; } @@ -1197,7 +1197,8 @@ bool SkeletonState::DecodeIndex(ogg_packet* aPacket) } // Extract the start time. - CheckedInt64 t = CheckedInt64(LittleEndian::readInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S; + int64_t timeRawInt = LittleEndian::readInt64(p + INDEX_FIRST_NUMER_OFFSET); + CheckedInt64 t = CheckedInt64(timeRawInt) * USECS_PER_S; if (!t.isValid()) { return (mActive = false); } else { @@ -1205,7 +1206,8 @@ bool SkeletonState::DecodeIndex(ogg_packet* aPacket) } // Extract the end time. - t = LittleEndian::readInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S; + timeRawInt = LittleEndian::readInt64(p + INDEX_LAST_NUMER_OFFSET); + t = CheckedInt64(timeRawInt) * USECS_PER_S; if (!t.isValid()) { return (mActive = false); } else { diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index fa190af92f78..4e52fe659c92 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -502,12 +502,15 @@ * are disallowed by default unless they are marked as MOZ_IMPLICIT. This * attribute must be used for constructors which intend to provide implicit * conversions. + * MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT: Applies to functions. Makes it a compile + * time error to path arithmetic expressions on variables to the function. */ #ifdef MOZ_CLANG_PLUGIN # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) # define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) # define MOZ_IMPLICIT __attribute__((annotate("moz_implicit"))) +# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg"))) /* * It turns out that clang doesn't like void func() __attribute__ {} without a * warning, so use pragmas to disable the warning. This code won't work on GCC @@ -523,6 +526,7 @@ # define MOZ_STACK_CLASS /* nothing */ # define MOZ_NONHEAP_CLASS /* nothing */ # define MOZ_IMPLICIT /* nothing */ +# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT /* nothing */ # define MOZ_HEAP_ALLOCATOR /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ diff --git a/mfbt/CheckedInt.h b/mfbt/CheckedInt.h index e4f08992038b..bed71a430922 100644 --- a/mfbt/CheckedInt.h +++ b/mfbt/CheckedInt.h @@ -11,6 +11,7 @@ #include #include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" #include "mozilla/IntegerTypeTraits.h" namespace mozilla { @@ -525,7 +526,7 @@ public: * argument is valid. */ template - CheckedInt(U aValue) + CheckedInt(U aValue) MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT : mValue(T(aValue)), mIsValid(detail::IsInRange(aValue)) { diff --git a/mfbt/tests/TestCheckedInt.cpp b/mfbt/tests/TestCheckedInt.cpp index cca1821746c0..7ded8e350a39 100644 --- a/mfbt/tests/TestCheckedInt.cpp +++ b/mfbt/tests/TestCheckedInt.cpp @@ -521,7 +521,7 @@ void test() : sizeof(T) >= sizeof(U)); \ } #define VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(U) \ - VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,U,+0) \ + VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,U,+zero) \ VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE2(U,CheckedInt,.toChecked()) VERIFY_CONSTRUCTION_FROM_INTEGER_TYPE(int8_t) From d74cb4fa0576b99f9fd274a789fb3ec3e3547adc Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 18 Dec 2014 13:32:45 -0500 Subject: [PATCH 014/183] Bug 1112476 - Support dumping texture data on the ClientLayerManager. r=mstange --HG-- extra : rebase_source : 5d5cf3372993ca4af78e12236fc64836a56eff4b --- gfx/layers/TiledLayerBuffer.h | 34 ++++++++++++++++ gfx/layers/client/ClientPaintedLayer.cpp | 11 +++++ gfx/layers/client/ClientPaintedLayer.h | 4 +- gfx/layers/client/ClientTiledPaintedLayer.cpp | 12 ++++++ gfx/layers/client/ClientTiledPaintedLayer.h | 2 + gfx/layers/client/CompositableClient.cpp | 14 +++++++ gfx/layers/client/CompositableClient.h | 1 + gfx/layers/client/ContentClient.cpp | 23 +++++++++++ gfx/layers/client/ContentClient.h | 9 +++++ gfx/layers/client/TextureClient.cpp | 40 +++++++++++++++++++ gfx/layers/client/TextureClient.h | 6 +++ gfx/layers/client/TiledContentClient.cpp | 22 ++++++++++ gfx/layers/client/TiledContentClient.h | 11 +++++ gfx/layers/composite/TiledContentHost.cpp | 33 +-------------- gfx/layers/composite/TiledContentHost.h | 5 +++ .../opengl/MacIOSurfaceTextureClientOGL.cpp | 6 +++ .../opengl/MacIOSurfaceTextureClientOGL.h | 2 + 17 files changed, 202 insertions(+), 33 deletions(-) diff --git a/gfx/layers/TiledLayerBuffer.h b/gfx/layers/TiledLayerBuffer.h index 7bf1f918cba8..9b1a42e9c4c0 100644 --- a/gfx/layers/TiledLayerBuffer.h +++ b/gfx/layers/TiledLayerBuffer.h @@ -176,6 +176,8 @@ public: Iterator TilesBegin() { return mRetainedTiles.Elements(); } Iterator TilesEnd() { return mRetainedTiles.Elements() + mRetainedTiles.Length(); } + void Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml); + protected: // The implementor should call Update() to change // the new valid region. This implementation will call @@ -307,6 +309,38 @@ TiledLayerBuffer::RemoveTile(int x, int y, Tile& aRemovedTile) return false; } +template void +TiledLayerBuffer::Dump(std::stringstream& aStream, + const char* aPrefix, + bool aDumpHtml) +{ + nsIntRect visibleRect = GetValidRegion().GetBounds(); + gfx::IntSize scaledTileSize = GetScaledTileSize(); + for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { + int32_t tileStartX = GetTileStart(x, scaledTileSize.width); + int32_t w = scaledTileSize.width - tileStartX; + + for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { + int32_t tileStartY = GetTileStart(y, scaledTileSize.height); + Tile tileTexture = + GetTile(nsIntPoint(RoundDownToTileEdge(x, scaledTileSize.width), + RoundDownToTileEdge(y, scaledTileSize.height))); + int32_t h = scaledTileSize.height - tileStartY; + + aStream << "\n" << aPrefix << "Tile (x=" << + RoundDownToTileEdge(x, scaledTileSize.width) << ", y=" << + RoundDownToTileEdge(y, scaledTileSize.height) << "): "; + if (tileTexture != AsDerived().GetPlaceholderTile()) { + tileTexture.DumpTexture(aStream); + } else { + aStream << "empty tile"; + } + y += h; + } + x += w; + } +} + template void TiledLayerBuffer::Update(const nsIntRegion& aNewValidRegion, const nsIntRegion& aPaintRegion) diff --git a/gfx/layers/client/ClientPaintedLayer.cpp b/gfx/layers/client/ClientPaintedLayer.cpp index f9c980eee535..7096f5f3be2d 100644 --- a/gfx/layers/client/ClientPaintedLayer.cpp +++ b/gfx/layers/client/ClientPaintedLayer.cpp @@ -176,6 +176,17 @@ ClientLayerManager::CreatePaintedLayerWithHint(PaintedLayerCreationHint aHint) } } +void +ClientPaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + PaintedLayer::PrintInfo(aStream, aPrefix); + if (mContentClient) { + aStream << "\n"; + nsAutoCString pfx(aPrefix); + pfx += " "; + mContentClient->PrintInfo(aStream, pfx.get()); + } +} } } diff --git a/gfx/layers/client/ClientPaintedLayer.h b/gfx/layers/client/ClientPaintedLayer.h index 449ee3dfbcc1..288c33740e21 100644 --- a/gfx/layers/client/ClientPaintedLayer.h +++ b/gfx/layers/client/ClientPaintedLayer.h @@ -108,7 +108,9 @@ public: protected: void PaintThebes(); - + + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) MOZ_OVERRIDE; + void DestroyBackBuffer() { mContentClient = nullptr; diff --git a/gfx/layers/client/ClientTiledPaintedLayer.cpp b/gfx/layers/client/ClientTiledPaintedLayer.cpp index c71b769f2270..5452d8e81397 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.cpp +++ b/gfx/layers/client/ClientTiledPaintedLayer.cpp @@ -470,5 +470,17 @@ ClientTiledPaintedLayer::RenderLayer() EndPaint(); } +void +ClientTiledPaintedLayer::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + PaintedLayer::PrintInfo(aStream, aPrefix); + if (mContentClient) { + aStream << "\n"; + nsAutoCString pfx(aPrefix); + pfx += " "; + mContentClient->PrintInfo(aStream, pfx.get()); + } +} + } // mozilla } // layers diff --git a/gfx/layers/client/ClientTiledPaintedLayer.h b/gfx/layers/client/ClientTiledPaintedLayer.h index 6648a5e4fbe8..37b3674305e8 100644 --- a/gfx/layers/client/ClientTiledPaintedLayer.h +++ b/gfx/layers/client/ClientTiledPaintedLayer.h @@ -47,6 +47,8 @@ public: protected: ~ClientTiledPaintedLayer(); + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) MOZ_OVERRIDE; + public: // Override name to distinguish it from ClientPaintedLayer in layer dumps virtual const char* Name() const { return "TiledPaintedLayer"; } diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 94ee01bd0ff8..66fef80f0e88 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -16,6 +16,7 @@ #include "mozilla/layers/TextureD3D11.h" #include "mozilla/layers/TextureD3D9.h" #endif +#include "gfxUtils.h" namespace mozilla { namespace layers { @@ -258,5 +259,18 @@ CompositableClient::GetTextureClientRecycler() return mTextureClientRecycler; } +void +CompositableClient::DumpTextureClient(std::stringstream& aStream, TextureClient* aTexture) +{ + if (!aTexture) { + return; + } + RefPtr dSurf = aTexture->GetAsSurface(); + if (!dSurf) { + return; + } + aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/client/CompositableClient.h b/gfx/layers/client/CompositableClient.h index 0c51e3f726b1..63c8f457f473 100644 --- a/gfx/layers/client/CompositableClient.h +++ b/gfx/layers/client/CompositableClient.h @@ -232,6 +232,7 @@ public: TextureClientRecycleAllocator* GetTextureClientRecycler(); + static void DumpTextureClient(std::stringstream& aStream, TextureClient* aTexture); protected: CompositableChild* mCompositableChild; CompositableForwarder* mForwarder; diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 0c7c9f941267..62298d81ffe4 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -118,6 +118,20 @@ ContentClient::EndPaint(nsTArray* aReadbackUpdates) OnTransaction(); } +void +ContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("ContentClient (0x%p)", this).get(); + + if (profiler_feature_active("displaylistdump")) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + Dump(aStream, pfx.get(), false); + } +} + // We pass a null pointer for the ContentClient Forwarder argument, which means // this client will not have a ContentHost on the other side. ContentClientBasic::ContentClientBasic() @@ -401,6 +415,15 @@ ContentClientRemoteBuffer::SwapBuffers(const nsIntRegion& aFrontUpdatedRegion) mFrontAndBackBufferDiffer = true; } +void +ContentClientRemoteBuffer::Dump(std::stringstream& aStream, + const char* aPrefix, + bool aDumpHtml) +{ + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + CompositableClient::DumpTextureClient(aStream, mTextureClient); +} + void ContentClientDoubleBuffered::DestroyFrontBuffer() { diff --git a/gfx/layers/client/ContentClient.h b/gfx/layers/client/ContentClient.h index bd597e6843c1..dec05a882d1f 100644 --- a/gfx/layers/client/ContentClient.h +++ b/gfx/layers/client/ContentClient.h @@ -89,6 +89,11 @@ public: virtual ~ContentClient() {} + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + + virtual void Dump(std::stringstream& aStream, + const char* aPrefix="", + bool aDumpHtml=false) {}; virtual void Clear() = 0; virtual RotatedContentBuffer::PaintState BeginPaintBuffer(PaintedLayer* aLayer, @@ -208,6 +213,10 @@ public: mTextureClientOnWhite = nullptr; } + virtual void Dump(std::stringstream& aStream, + const char* aPrefix="", + bool aDumpHtml=false) MOZ_OVERRIDE; + virtual PaintState BeginPaintBuffer(PaintedLayer* aLayer, uint32_t aFlags) MOZ_OVERRIDE { diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index fdb22befca6b..793ef3514119 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -22,6 +22,10 @@ #include "mozilla/layers/PTextureChild.h" #include "SharedSurface.h" #include "GLContext.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" // for CreateDataSourceSurfaceByCloning +#include "nsPrintfCString.h" // for nsPrintfCString +#include "LayersLogging.h" // for AppendToString +#include "gfxUtils.h" // for gfxUtils::GetAsLZ4Base64Str #ifdef XP_WIN #include "mozilla/layers/TextureD3D9.h" @@ -572,6 +576,28 @@ TextureClient::ShouldDeallocateInDestructor() const return !IsSharedWithCompositor() || (GetFlags() & TextureFlags::DEALLOCATE_CLIENT); } +void +TextureClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("TextureClient (0x%p)", this).get(); + AppendToString(aStream, GetSize(), " [size=", "]"); + AppendToString(aStream, GetFormat(), " [format=", "]"); + AppendToString(aStream, mFlags, " [flags=", "]"); + +#ifdef MOZ_DUMP_PAINTING + if (gfxPrefs::LayersDumpTexture() || profiler_feature_active("layersdump")) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + aStream << "\n" << pfx.get() << "Surface: "; + RefPtr dSurf = GetAsSurface(); + if (dSurf) { + aStream << gfxUtils::GetAsLZ4Base64Str(dSurf).get(); + } + } +#endif +} bool ShmemTextureClient::ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor) { @@ -866,6 +892,20 @@ BufferTextureClient::GetLockedData() const return serializer.GetData(); } +TemporaryRef +BufferTextureClient::GetAsSurface() +{ + ImageDataSerializer serializer(GetBuffer(), GetBufferSize()); + MOZ_ASSERT(serializer.IsValid()); + + RefPtr wrappingSurf = + gfx::Factory::CreateWrappingDataSourceSurface(serializer.GetData(), + serializer.GetStride(), + serializer.GetSize(), + serializer.GetFormat()); + return gfx::CreateDataSourceSurfaceByCloning(wrappingSurf); +} + //////////////////////////////////////////////////////////////////////// // SharedSurfaceTextureClient diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 4ac737d53ec4..bb520c8c217f 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -281,6 +281,10 @@ public: return gfx::SurfaceFormat::UNKNOWN; } + virtual TemporaryRef GetAsSurface() { return nullptr; } + + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + /** * Copies a rectangle from this texture client to a position in aTarget. * It is assumed that the necessary locks are in place; so this should at @@ -584,6 +588,8 @@ public: gfx::IntSize aCbCrSize, StereoMode aStereoMode) MOZ_OVERRIDE; + virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE; + virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; } // XXX - Bug 908196 - Make Allocate(uint32_t) and GetBufferSize() protected. diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 3af084784893..2795f2d7a5d9 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -1598,5 +1598,27 @@ ClientTiledLayerBuffer::ProgressiveUpdate(nsIntRegion& aValidRegion, return isBufferChanged; } +void +TiledContentClient::PrintInfo(std::stringstream& aStream, const char* aPrefix) +{ + aStream << aPrefix; + aStream << nsPrintfCString("TiledContentClient (0x%p)", this).get(); + + if (profiler_feature_active("displaylistdump")) { + nsAutoCString pfx(aPrefix); + pfx += " "; + + Dump(aStream, pfx.get(), false); + } +} + +void +TiledContentClient::Dump(std::stringstream& aStream, + const char* aPrefix, + bool aDumpHtml) +{ + mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml); +} + } } diff --git a/gfx/layers/client/TiledContentClient.h b/gfx/layers/client/TiledContentClient.h index 4a68dd973ced..303fca780f38 100644 --- a/gfx/layers/client/TiledContentClient.h +++ b/gfx/layers/client/TiledContentClient.h @@ -218,6 +218,11 @@ struct TileClient */ void Flip(); + void DumpTexture(std::stringstream& aStream) { + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + CompositableClient::DumpTextureClient(aStream, mFrontBuffer); + } + /** * Returns an unlocked TextureClient that can be used for writing new * data to the tile. This may flip the front-buffer to the back-buffer if @@ -527,6 +532,12 @@ protected: mLowPrecisionTiledBuffer.Release(); } + virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix); + + virtual void Dump(std::stringstream& aStream, + const char* aPrefix="", + bool aDumpHtml=false); + public: virtual TextureInfo GetTextureInfo() const MOZ_OVERRIDE { diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index 9b53ef21b576..164a61284b0f 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -642,38 +642,7 @@ TiledContentHost::Dump(std::stringstream& aStream, const char* aPrefix, bool aDumpHtml) { - nsIntRect visibleRect = mTiledBuffer.GetValidRegion().GetBounds(); - gfx::IntSize scaledTileSize = mTiledBuffer.GetScaledTileSize(); - for (int32_t x = visibleRect.x; x < visibleRect.x + visibleRect.width;) { - int32_t tileStartX = mTiledBuffer.GetTileStart(x, scaledTileSize.width); - int32_t w = scaledTileSize.width - tileStartX; - if (x + w > visibleRect.x + visibleRect.width) { - w = visibleRect.x + visibleRect.width - x; - } - - for (int32_t y = visibleRect.y; y < visibleRect.y + visibleRect.height;) { - int32_t tileStartY = mTiledBuffer.GetTileStart(y, scaledTileSize.height); - TileHost tileTexture = mTiledBuffer. - GetTile(nsIntPoint(mTiledBuffer.RoundDownToTileEdge(x, scaledTileSize.width), - mTiledBuffer.RoundDownToTileEdge(y, scaledTileSize.height))); - int32_t h = scaledTileSize.height - tileStartY; - if (y + h > visibleRect.y + visibleRect.height) { - h = visibleRect.y + visibleRect.height - y; - } - - aStream << "\n" << aPrefix << "Tile (x=" << - mTiledBuffer.RoundDownToTileEdge(x, scaledTileSize.width) << ", y=" << - mTiledBuffer.RoundDownToTileEdge(y, scaledTileSize.height) << "): "; - if (tileTexture != mTiledBuffer.GetPlaceholderTile()) { - DumpTextureHost(aStream, tileTexture.mTextureHost); - // TODO We should combine the OnWhite/OnBlack here an just output a single image. - } else { - aStream << "empty tile"; - } - y += h; - } - x += w; - } + mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml); } } // namespace diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index 229d07e355f1..c7f0d495cf57 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -106,6 +106,11 @@ public: } } + void DumpTexture(std::stringstream& aStream) { + // TODO We should combine the OnWhite/OnBlack here an just output a single image. + CompositableHost::DumpTextureHost(aStream, mTextureHost); + } + RefPtr mSharedLock; CompositableTextureHostRef mTextureHost; CompositableTextureHostRef mTextureHostOnWhite; diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp index 1b784f44d761..cdf9601f1bd1 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp @@ -65,5 +65,11 @@ MacIOSurfaceTextureClientOGL::GetSize() const return gfx::IntSize(mSurface->GetDevicePixelWidth(), mSurface->GetDevicePixelHeight()); } +TemporaryRef +MacIOSurfaceTextureClientOGL::GetAsSurface() +{ + RefPtr surf = mSurface->GetAsSurface(); + return surf->GetDataSurface(); +} } } diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h index b7353464337a..e423ffc95995 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h @@ -36,6 +36,8 @@ public: virtual bool HasInternalBuffer() const MOZ_OVERRIDE { return false; } + virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE; + // This TextureClient should not be used in a context where we use CreateSimilar // (ex. component alpha) because the underlying texture data is always created by // an external producer. From 0003ef72d01c7c45f9620b975178efada7b06e69 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 18 Dec 2014 13:32:51 -0500 Subject: [PATCH 015/183] Bug 1112483 - Add the layer bounds in the DisplayList dump. r=mattwoodrow --HG-- extra : rebase_source : cb6d1329dc507607ef57bcd26d825dde052121ea --- layout/base/nsLayoutDebugger.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index b53dc3f4cab0..3f873f001361 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -149,6 +149,9 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, #endif bool snap; nsRect rect = aItem->GetBounds(aBuilder, &snap); + nsRect layerRect = rect - + nsLayoutUtils::GetAnimatedGeometryRootFor(aItem, aBuilder, nullptr)-> + GetOffsetToCrossDoc(aItem->ReferenceFrame()); nscolor color; nsRect vis = aItem->GetVisibleRect(); nsRect component = aItem->GetComponentAlphaBounds(aBuilder); @@ -161,10 +164,11 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, string.AppendInt((uint64_t)aItem); aStream << nsPrintfCString("", string.BeginReading()); } - aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s", + aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s", aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(fName).get(), (aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""), rect.x, rect.y, rect.width, rect.height, + layerRect.x, layerRect.y, layerRect.width, layerRect.height, vis.x, vis.y, vis.width, vis.height, component.x, component.y, component.width, component.height, clip.ToString().get(), From 22355f0c17a51e29f1e9072c36419a1538ac64e7 Mon Sep 17 00:00:00 2001 From: Benoit Girard Date: Thu, 18 Dec 2014 13:32:53 -0500 Subject: [PATCH 016/183] Bug 1112756 - Pass display list and layers data directly to the profiler. r=mstange --HG-- extra : rebase_source : 5c7295e80105b0db43651553c1b901836571cbbb --- .../composite/LayerManagerComposite.cpp | 6 +++++- gfx/thebes/gfxUtils.cpp | 2 +- layout/base/nsLayoutUtils.cpp | 21 +++++++++++++++---- tools/profiler/GeckoProfiler.h | 3 +++ tools/profiler/GeckoProfilerFunc.h | 2 ++ tools/profiler/GeckoProfilerImpl.h | 12 +++++++++++ tools/profiler/platform.cpp | 6 +++--- 7 files changed, 43 insertions(+), 9 deletions(-) diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index a48f547ebf66..634a8a272099 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -627,8 +627,12 @@ LayerManagerComposite::Render() LayerScopeAutoFrame frame(PR_Now()); // Dump to console - if (gfxPrefs::LayersDump() || profiler_feature_active("layersdump")) { + if (gfxPrefs::LayersDump()) { this->Dump(); + } else if (profiler_feature_active("layersdump")) { + std::stringstream ss; + Dump(ss); + profiler_log(ss.str().c_str()); } // Dump to LayerScope Viewer diff --git a/gfx/thebes/gfxUtils.cpp b/gfx/thebes/gfxUtils.cpp index 6e5a1dc1bb8f..9dd8ee262dc0 100644 --- a/gfx/thebes/gfxUtils.cpp +++ b/gfx/thebes/gfxUtils.cpp @@ -1443,7 +1443,7 @@ static bool sDumpPaintList = getenv("MOZ_DUMP_PAINT_LIST") != 0; /* static */ bool gfxUtils::DumpPaintList() { - return sDumpPaintList || gfxPrefs::LayoutDumpDisplayList() || profiler_feature_active("displaylistdump"); + return sDumpPaintList || gfxPrefs::LayoutDumpDisplayList(); } bool gfxUtils::sDumpPainting = getenv("MOZ_DUMP_PAINT") != 0; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index b74a921fbed0..1b5c24acad5b 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -3106,8 +3106,11 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram #ifdef MOZ_DUMP_PAINTING FILE* savedDumpFile = gfxUtils::sDumpPaintFile; + bool profilerNeedsDisplayList = profiler_feature_active("displaylistdump"); + bool consoleNeedsDisplayList = gfxUtils::DumpPaintList() || gfxUtils::sDumpPainting; + UniquePtr ss = MakeUnique(); - if (gfxUtils::DumpPaintList() || gfxUtils::sDumpPainting) { + if (consoleNeedsDisplayList || profilerNeedsDisplayList) { if (gfxUtils::sDumpPaintingToFile) { nsCString string("dump-"); string.AppendInt(gPaintCount); @@ -3127,7 +3130,12 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram } else { // Flush stream now to avoid reordering dump output relative to // messages dumped by PaintRoot below. - fprint_stderr(gfxUtils::sDumpPaintFile, *ss); + if (profilerNeedsDisplayList && !consoleNeedsDisplayList) { + profiler_log(ss->str().c_str()); + } else { + // Send to the console which will send to the profiler if required. + fprint_stderr(gfxUtils::sDumpPaintFile, *ss); + } ss = MakeUnique(); } } @@ -3171,7 +3179,7 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram paintStart); #ifdef MOZ_DUMP_PAINTING - if (gfxUtils::DumpPaintList() || gfxUtils::sDumpPainting) { + if (consoleNeedsDisplayList || profilerNeedsDisplayList) { if (gfxUtils::sDumpPaintingToFile) { *ss << ""; } @@ -3187,7 +3195,12 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram *ss << ""; } - fprint_stderr(gfxUtils::sDumpPaintFile, *ss); + if (profilerNeedsDisplayList && !consoleNeedsDisplayList) { + profiler_log(ss->str().c_str()); + } else { + // Send to the console which will send to the profiler if required. + fprint_stderr(gfxUtils::sDumpPaintFile, *ss); + } if (gfxUtils::sDumpPaintingToFile) { fclose(gfxUtils::sDumpPaintFile); diff --git a/tools/profiler/GeckoProfiler.h b/tools/profiler/GeckoProfiler.h index 64767f113730..f567ab933c75 100644 --- a/tools/profiler/GeckoProfiler.h +++ b/tools/profiler/GeckoProfiler.h @@ -201,6 +201,9 @@ static inline double profiler_time(const mozilla::TimeStamp& aTime) { return 0; static inline bool profiler_in_privacy_mode() { return false; } +static inline void profiler_log(const char *str) {} +static inline void profiler_log(const char *fmt, va_list args) {} + #else #include "GeckoProfilerImpl.h" diff --git a/tools/profiler/GeckoProfilerFunc.h b/tools/profiler/GeckoProfilerFunc.h index 9fb7619def4e..bdea46fe2c5e 100644 --- a/tools/profiler/GeckoProfilerFunc.h +++ b/tools/profiler/GeckoProfilerFunc.h @@ -97,5 +97,7 @@ void mozilla_sampler_tracing(const char* aCategory, const char* aInfo, ProfilerBacktrace* aCause, TracingMetadata aMetaData); +void mozilla_sampler_log(const char *fmt, va_list args); + #endif diff --git a/tools/profiler/GeckoProfilerImpl.h b/tools/profiler/GeckoProfilerImpl.h index 84cd06a5128b..2bca7432271e 100644 --- a/tools/profiler/GeckoProfilerImpl.h +++ b/tools/profiler/GeckoProfilerImpl.h @@ -460,4 +460,16 @@ inline void mozilla_sampler_call_exit(void *aHandle) void mozilla_sampler_add_marker(const char *aMarker, ProfilerMarkerPayload *aPayload); +static inline +void profiler_log(const char *str) +{ + profiler_tracing("log", str, TRACING_EVENT); +} + +static inline +void profiler_log(const char *fmt, va_list args) +{ + mozilla_sampler_log(fmt, args); +} + #endif /* ndef TOOLS_SPS_SAMPLER_H_ */ diff --git a/tools/profiler/platform.cpp b/tools/profiler/platform.cpp index 6d3d977ddd9b..22ec7334bdec 100644 --- a/tools/profiler/platform.cpp +++ b/tools/profiler/platform.cpp @@ -491,8 +491,8 @@ bool is_main_thread_name(const char* aName) { #define VARARGS_ASSIGN(foo, bar) (foo) = (bar) #endif -static void -profiler_log(const char *fmt, va_list args) +void +mozilla_sampler_log(const char *fmt, va_list args) { if (profiler_is_active()) { // nsAutoCString AppendPrintf would be nicer but @@ -561,7 +561,7 @@ void mozilla_sampler_init(void* stackTop) // platform specific initialization OS::Startup(); - set_stderr_callback(profiler_log); + set_stderr_callback(mozilla_sampler_log); // We can't open pref so we use an environment variable // to know if we should trigger the profiler on startup From e9f1d90071550a9e879fc0ec0e7fbc07da458d97 Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 18 Dec 2014 12:39:30 -0800 Subject: [PATCH 017/183] Bug 1112925 - Don't re-enter JS with a pending exception in CheckForPendingException. r=terrence --- js/xpconnect/src/XPCWrappedJSClass.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index ac4f843b8e83..1474aec1302f 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -704,15 +704,6 @@ nsXPCWrappedJSClass::CleanupPointerTypeObject(const nsXPTType& type, } } -class AutoClearPendingException -{ -public: - explicit AutoClearPendingException(JSContext *cx) : mCx(cx) { } - ~AutoClearPendingException() { JS_ClearPendingException(mCx); } -private: - JSContext* mCx; -}; - nsresult nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx, const char * aPropertyName, @@ -748,7 +739,10 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx, } } - AutoClearPendingException acpe(cx); + // Clear the pending exception now, because xpc_exception might be JS- + // implemented, so invoking methods on it might re-enter JS, which we can't + // do with an exception on the stack. + JS_ClearPendingException(cx); if (xpc_exception) { nsresult e_result; @@ -793,6 +787,10 @@ nsXPCWrappedJSClass::CheckForException(XPCCallContext & ccx, // error if it came from a JS exception. if (reportable && is_js_exception) { + // Note that we cleared the exception above, so we need to set it again, + // just so that we can tell the JS engine to pass it back to us via the + // error reporting callback. This is all very dumb. + JS_SetPendingException(cx, js_exception); reportable = !JS_ReportPendingException(cx); } From 682a5b2f5c9f644b746b7a47a86abc52c820501c Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 18 Dec 2014 12:44:42 -0800 Subject: [PATCH 018/183] Bug 1110546 - Allow null as the principal argument for the sandbox constructor. r=gabor --- js/xpconnect/src/Sandbox.cpp | 4 ++++ js/xpconnect/tests/unit/test_bug1110546.js | 5 +++++ js/xpconnect/tests/unit/xpcshell.ini | 1 + 3 files changed, 10 insertions(+) create mode 100644 js/xpconnect/tests/unit/test_bug1110546.js diff --git a/js/xpconnect/src/Sandbox.cpp b/js/xpconnect/src/Sandbox.cpp index 926897822e29..793377416cb5 100644 --- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -1415,6 +1415,10 @@ nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrappe } else { ok = GetPrincipalOrSOP(cx, obj, getter_AddRefs(prinOrSop)); } + } else if (args[0].isNull()) { + // Null means that we just pass prinOrSop = nullptr, and get an + // nsNullPrincipal. + ok = true; } if (!ok) diff --git a/js/xpconnect/tests/unit/test_bug1110546.js b/js/xpconnect/tests/unit/test_bug1110546.js new file mode 100644 index 000000000000..02687296d68e --- /dev/null +++ b/js/xpconnect/tests/unit/test_bug1110546.js @@ -0,0 +1,5 @@ +const Cu = Components.utils; +function run_test() { + var sb = new Cu.Sandbox(null); + do_check_true(Cu.getObjectPrincipal(sb).isNullPrincipal); +} diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini index 0c4b4bf0f7bb..8569221d9a97 100644 --- a/js/xpconnect/tests/unit/xpcshell.ini +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -53,6 +53,7 @@ support-files = [test_bug1034262.js] [test_bug1082450.js] [test_bug1081990.js] +[test_bug1110546.js] [test_bug_442086.js] [test_file.js] [test_blob.js] From a23d2bdf73ef806210e9f0ec28d4e77080929bed Mon Sep 17 00:00:00 2001 From: Chris Pearce Date: Fri, 19 Dec 2014 09:54:34 +1300 Subject: [PATCH 019/183] Bug 1109457 - Add persistent session to our ClearKey CDM. r=edwin --- dom/media/gmp/gmp-api/gmp-storage.h | 1 + dom/media/test/eme.js | 21 +- dom/media/test/mochitest.ini | 2 + .../test/test_eme_persistent_sessions.html | 156 ++ .../0.1/ClearKeyDecryptionManager.cpp | 229 +- .../0.1/ClearKeyDecryptionManager.h | 15 +- .../gmp-clearkey/0.1/ClearKeyPersistence.cpp | 236 ++ media/gmp-clearkey/0.1/ClearKeyPersistence.h | 39 + media/gmp-clearkey/0.1/ClearKeySession.cpp | 19 +- media/gmp-clearkey/0.1/ClearKeySession.h | 23 +- media/gmp-clearkey/0.1/ClearKeyStorage.cpp | 174 ++ media/gmp-clearkey/0.1/ClearKeyStorage.h | 36 + media/gmp-clearkey/0.1/ClearKeyUtils.cpp | 45 +- media/gmp-clearkey/0.1/ClearKeyUtils.h | 17 +- media/gmp-clearkey/0.1/RefCounted.h | 34 + .../0.1/gmp-task-utils-generated.h | 1898 +++++++++++++++++ media/gmp-clearkey/0.1/gmp-task-utils.h | 37 + media/gmp-clearkey/0.1/moz.build | 2 + 18 files changed, 2915 insertions(+), 69 deletions(-) create mode 100644 dom/media/test/test_eme_persistent_sessions.html create mode 100644 media/gmp-clearkey/0.1/ClearKeyPersistence.cpp create mode 100644 media/gmp-clearkey/0.1/ClearKeyPersistence.h create mode 100644 media/gmp-clearkey/0.1/ClearKeyStorage.cpp create mode 100644 media/gmp-clearkey/0.1/ClearKeyStorage.h create mode 100644 media/gmp-clearkey/0.1/RefCounted.h create mode 100644 media/gmp-clearkey/0.1/gmp-task-utils-generated.h create mode 100644 media/gmp-clearkey/0.1/gmp-task-utils.h diff --git a/dom/media/gmp/gmp-api/gmp-storage.h b/dom/media/gmp/gmp-api/gmp-storage.h index c070c01245c8..43ad12b01a4e 100644 --- a/dom/media/gmp/gmp-api/gmp-storage.h +++ b/dom/media/gmp/gmp-api/gmp-storage.h @@ -118,6 +118,7 @@ class GMPRecordClient { class GMPRecordIterator { public: // Retrieve the name for the current record. + // aOutName is null terminated at character at index (*aOutNameLength). // Returns GMPNoErr if successful, or GMPEndOfEnumeration if iteration has // reached the end. virtual GMPErr GetName(const char ** aOutName, uint32_t * aOutNameLength) = 0; diff --git a/dom/media/test/eme.js b/dom/media/test/eme.js index c98b20d39de2..bdec0decfd4b 100644 --- a/dom/media/test/eme.js +++ b/dom/media/test/eme.js @@ -3,9 +3,12 @@ const KEYSYSTEM_TYPE = "org.w3.clearkey"; function bail(message) { return function(err) { + if (err) { + message += "; " + String(err) + } ok(false, message); if (err) { - info(err); + info(String(err)); } SimpleTest.finish(); } @@ -70,13 +73,13 @@ function Log(token, msg) { info(TimeStamp(token) + " " + msg); } -function UpdateSessionFunc(test, token) { +function UpdateSessionFunc(test, token, sessionType) { return function(ev) { var msgStr = ArrayBufferToString(ev.message); var msg = JSON.parse(msgStr); Log(token, "got message from CDM: " + msgStr); - is(msg.type, test.sessionType, TimeStamp(token) + " key session type should match"); + is(msg.type, sessionType, TimeStamp(token) + " key session type should match"); ok(msg.kids, TimeStamp(token) + " message event should contain key ID array"); var outKeys = []; @@ -211,24 +214,24 @@ function SetupEME(test, token, params) .then(function(keySystemAccess) { return keySystemAccess.createMediaKeys(); }, bail(token + " Failed to request key system access.")) - + .then(function(mediaKeys) { Log(token, "created MediaKeys object ok"); mediaKeys.sessions = []; return v.setMediaKeys(mediaKeys); }, bail("failed to create MediaKeys object")) - + .then(function() { Log(token, "set MediaKeys on element bool mIsForSVGAElement; - // Child frame construction items. - FrameConstructionItemList mChildItems; - - // ContentInfo list for children that have yet to have - // FrameConstructionItem objects created for them. This exists because - // AddFrameConstructionItemsInternal needs a valid frame, but in the case - // that nsIAnonymousContentCreator::CreateAnonymousContent returns items - // that have their own children (so we have a tree of ContentInfo objects - // rather than a flat list) we don't yet have a frame to provide to - // AddFrameConstructionItemsInternal in order to create the items for the - // grandchildren. That prevents FrameConstructionItems from being created - // for these grandchildren (and any descendants that they may have), - // otherwise they could have been added to the mChildItems member of their - // parent FrameConstructionItem. As it is, the grandchildren ContentInfo - // list has to be stored in this mAnonChildren member in order to delay - // construction of the FrameConstructionItems for the grandchildren until - // a frame has been created for their parent item. - nsTArray mAnonChildren; - private: FrameConstructionItem(const FrameConstructionItem& aOther) MOZ_DELETE; /* not implemented */ }; From c7fe36c3692ae2c042f2166018562ee114444881 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Dec 2014 14:15:18 -0800 Subject: [PATCH 068/183] Bug 1113010 (part 2) - Shrink FrameConstructionItem by using bitfields. r=dholbert. This reduces its size from 168 bytes to 160 bytes on 64-bit platforms. --HG-- extra : rebase_source : de9bb482ccbdb85efa79f82083fa8f35bb629078 --- layout/base/nsCSSFrameConstructor.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index d6a5b740cdc2..5de8869f9f76 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -1128,39 +1128,39 @@ private: int32_t mNameSpaceID; // Whether optimizations to skip constructing textframes around // this content need to be suppressed. - bool mSuppressWhiteSpaceOptimizations; + bool mSuppressWhiteSpaceOptimizations:1; // Whether this is a text content item. - bool mIsText; + bool mIsText:1; // Whether this is a generated content container. // If it is, mContent is a strong pointer. - bool mIsGeneratedContent; + bool mIsGeneratedContent:1; // Whether this is an item for nsIAnonymousContentCreator content. - bool mIsAnonymousContentCreatorContent; + bool mIsAnonymousContentCreatorContent:1; // Whether this is an item for the root popupgroup. - bool mIsRootPopupgroup; + bool mIsRootPopupgroup:1; // Whether construction from this item will create only frames that are // IsInlineOutside() in the principal child list. This is not precise, but // conservative: if true the frames will really be inline, whereas if false // they might still all be inline. - bool mIsAllInline; + bool mIsAllInline:1; // Whether construction from this item will create only frames that are // IsBlockOutside() in the principal child list. This is not precise, but // conservative: if true the frames will really be blocks, whereas if false // they might still be blocks (and in particular, out-of-flows that didn't // find a containing block). - bool mIsBlock; + bool mIsBlock:1; // Whether construction from this item will give leading and trailing // inline frames. This is equal to mIsAllInline, except for inline frame // items, where it's always true, whereas mIsAllInline might be false due // to {ib} splits. - bool mHasInlineEnds; + bool mHasInlineEnds:1; // Whether construction from this item will create a popup that needs to // go into the global popup items. - bool mIsPopup; + bool mIsPopup:1; // Whether this item should be treated as a line participant - bool mIsLineParticipant; + bool mIsLineParticipant:1; // Whether this item is for an SVG element - bool mIsForSVGAElement; + bool mIsForSVGAElement:1; private: FrameConstructionItem(const FrameConstructionItem& aOther) MOZ_DELETE; /* not implemented */ From ddd94333b7372211457eb50e34e07f7b960dd816 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Fri, 19 Dec 2014 14:32:34 +1100 Subject: [PATCH 069/183] Bug 649145 - Store properties on nsCSSCompressedDataBlocks in declaration order. r=dbaron --- layout/style/Declaration.h | 3 +- layout/style/nsCSSDataBlock.cpp | 66 ++++++++++++++++++++++----------- layout/style/nsCSSDataBlock.h | 6 ++- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/layout/style/Declaration.h b/layout/style/Declaration.h index da79d8171739..99e419371d83 100644 --- a/layout/style/Declaration.h +++ b/layout/style/Declaration.h @@ -146,7 +146,8 @@ public: NS_ABORT_IF_FALSE(!mData, "oops"); NS_ABORT_IF_FALSE(!mImportantData, "oops"); aExpandedData->Compress(getter_Transfers(mData), - getter_Transfers(mImportantData)); + getter_Transfers(mImportantData), + mOrder); aExpandedData->AssertInitialState(); } diff --git a/layout/style/nsCSSDataBlock.cpp b/layout/style/nsCSSDataBlock.cpp index bc6f3ab60f93..2191bf513a37 100644 --- a/layout/style/nsCSSDataBlock.cpp +++ b/layout/style/nsCSSDataBlock.cpp @@ -395,7 +395,8 @@ nsCSSExpandedDataBlock::ComputeNumProps(uint32_t* aNumPropsNormal, void nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, - nsCSSCompressedDataBlock **aImportantBlock) + nsCSSCompressedDataBlock **aImportantBlock, + const nsTArray& aOrder) { nsAutoPtr result_normal, result_important; uint32_t i_normal = 0, i_important = 0; @@ -418,29 +419,29 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, * corresponding to the stored data in the expanded block, and then * clearing the data in the expanded block. */ - for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; ++iHigh) { - if (!mPropertiesSet.HasPropertyInChunk(iHigh)) + for (size_t i = 0; i < aOrder.Length(); i++) { + nsCSSProperty iProp = static_cast(aOrder[i]); + if (iProp >= eCSSProperty_COUNT) { + // a custom property continue; - for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; ++iLow) { - if (!mPropertiesSet.HasPropertyAt(iHigh, iLow)) - continue; - nsCSSProperty iProp = nsCSSPropertySet::CSSPropertyAt(iHigh, iLow); - NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range"); - bool important = - mPropertiesImportant.HasPropertyAt(iHigh, iLow); - nsCSSCompressedDataBlock *result = - important ? result_important : result_normal; - uint32_t* ip = important ? &i_important : &i_normal; - nsCSSValue* val = PropertyAt(iProp); - NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, - "Null value while compressing"); - result->SetPropertyAtIndex(*ip, iProp); - result->RawCopyValueToIndex(*ip, val); - new (val) nsCSSValue(); - (*ip)++; - result->mStyleBits |= - nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]); } + NS_ABORT_IF_FALSE(mPropertiesSet.HasProperty(iProp), + "aOrder identifies a property not in the expanded " + "data block"); + NS_ABORT_IF_FALSE(!nsCSSProps::IsShorthand(iProp), "out of range"); + bool important = mPropertiesImportant.HasProperty(iProp); + nsCSSCompressedDataBlock *result = + important ? result_important : result_normal; + uint32_t* ip = important ? &i_important : &i_normal; + nsCSSValue* val = PropertyAt(iProp); + NS_ABORT_IF_FALSE(val->GetUnit() != eCSSUnit_Null, + "Null value while compressing"); + result->SetPropertyAtIndex(*ip, iProp); + result->RawCopyValueToIndex(*ip, val); + new (val) nsCSSValue(); + (*ip)++; + result->mStyleBits |= + nsCachedStyleData::GetBitForSID(nsCSSProps::kSIDTable[iProp]); } NS_ABORT_IF_FALSE(numPropsNormal == i_normal, "bad numProps"); @@ -449,6 +450,27 @@ nsCSSExpandedDataBlock::Compress(nsCSSCompressedDataBlock **aNormalBlock, NS_ABORT_IF_FALSE(numPropsImportant == i_important, "bad numProps"); } +#ifdef DEBUG + { + // assert that we didn't have any other properties on this expanded data + // block that we didn't find in aOrder + uint32_t numPropsInSet = 0; + for (size_t iHigh = 0; iHigh < nsCSSPropertySet::kChunkCount; iHigh++) { + if (!mPropertiesSet.HasPropertyInChunk(iHigh)) { + continue; + } + for (size_t iLow = 0; iLow < nsCSSPropertySet::kBitsInChunk; iLow++) { + if (mPropertiesSet.HasPropertyAt(iHigh, iLow)) { + numPropsInSet++; + } + } + } + NS_ABORT_IF_FALSE(numPropsNormal + numPropsImportant == numPropsInSet, + "aOrder missing properties from the expanded data " + "block"); + } +#endif + ClearSets(); AssertInitialState(); *aNormalBlock = result_normal.forget(); diff --git a/layout/style/nsCSSDataBlock.h b/layout/style/nsCSSDataBlock.h index 5417840c2fad..e09692d10d55 100644 --- a/layout/style/nsCSSDataBlock.h +++ b/layout/style/nsCSSDataBlock.h @@ -207,9 +207,13 @@ public: * an important block will only be allocated if there are * !important properties in the expanded block; otherwise * |*aImportantBlock| will be set to null. + * + * aOrder is an array of nsCSSProperty values specifying the order + * to store values in the two data blocks. */ void Compress(nsCSSCompressedDataBlock **aNormalBlock, - nsCSSCompressedDataBlock **aImportantBlock); + nsCSSCompressedDataBlock **aImportantBlock, + const nsTArray& aOrder); /** * Copy a value into this expanded block. This does NOT destroy From f789afa81c1e527ebc9c7565f6f27aedb20391e9 Mon Sep 17 00:00:00 2001 From: Seth Fowler Date: Thu, 18 Dec 2014 19:50:56 -0800 Subject: [PATCH 070/183] Bug 1111041 - Detect PR_GetPhysicalMemorySize failure in SurfaceCache. r=dholbert --- image/src/SurfaceCache.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/image/src/SurfaceCache.cpp b/image/src/SurfaceCache.cpp index 56c4979c8160..6034d534b888 100644 --- a/image/src/SurfaceCache.cpp +++ b/image/src/SurfaceCache.cpp @@ -10,6 +10,7 @@ #include "SurfaceCache.h" #include +#include "mozilla/Assertions.h" #include "mozilla/Attributes.h" // for MOZ_THIS_IN_INITIALIZER_LIST #include "mozilla/DebugOnly.h" #include "mozilla/Likely.h" @@ -752,7 +753,12 @@ SurfaceCache::Initialize() max(gfxPrefs::ImageMemSurfaceCacheSizeFactor(), 1u); // Compute the size of the surface cache. - uint64_t proposedSize = PR_GetPhysicalMemorySize() / surfaceCacheSizeFactor; + uint64_t memorySize = PR_GetPhysicalMemorySize(); + if (memorySize == 0) { + MOZ_ASSERT_UNREACHABLE("PR_GetPhysicalMemorySize not implemented here"); + memorySize = 256 * 1024 * 1024; // Fall back to 256MB. + } + uint64_t proposedSize = memorySize / surfaceCacheSizeFactor; uint64_t surfaceCacheSizeBytes = min(proposedSize, surfaceCacheMaxSizeKB * 1024); uint32_t finalSurfaceCacheSizeBytes = min(surfaceCacheSizeBytes, uint64_t(UINT32_MAX)); From 097e391f9bebf866b685842ecadff5393a36b818 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Thu, 18 Dec 2014 12:17:53 -0800 Subject: [PATCH 071/183] Bug 1113210 - Suppress -Wunused-function clang warning about AtkSocketAccessible.cpp's gobject RTTI macros. r=tbsaunde --- accessible/atk/moz.build | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/accessible/atk/moz.build b/accessible/atk/moz.build index f5abe301fd55..9b945da81a41 100644 --- a/accessible/atk/moz.build +++ b/accessible/atk/moz.build @@ -52,4 +52,8 @@ if CONFIG['MOZ_ENABLE_DBUS']: include('/ipc/chromium/chromium-config.mozbuild') +if CONFIG['CLANG_CXX']: + # Suppress clang warning about unused function from gobject's RTTI macros. + CXXFLAGS += ['-Wno-unused-function'] + FAIL_ON_WARNINGS = True From 0f26945357e72138a9fbbdae0550738ef862defd Mon Sep 17 00:00:00 2001 From: Jordan Lund Date: Thu, 18 Dec 2014 20:58:50 -0800 Subject: [PATCH 072/183] Bug 1073772 - Releng work for two ARMv7 APKs - nonuni mozconfig fix for api 11, r=rnewman --- .../android/config/mozconfigs/android-api-11/debug-nonunified | 2 +- .../android/config/mozconfigs/android-api-11/nightly-nonunified | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/android/config/mozconfigs/android-api-11/debug-nonunified b/mobile/android/config/mozconfigs/android-api-11/debug-nonunified index 4aee2b10df03..13f7d49cc831 100644 --- a/mobile/android/config/mozconfigs/android-api-11/debug-nonunified +++ b/mobile/android/config/mozconfigs/android-api-11/debug-nonunified @@ -1,4 +1,4 @@ -. "$topsrcdir/mobile/android/config/mozconfigs/android-api-10/debug" +. "$topsrcdir/mobile/android/config/mozconfigs/android-api-11/debug" ac_add_options --disable-unified-compilation diff --git a/mobile/android/config/mozconfigs/android-api-11/nightly-nonunified b/mobile/android/config/mozconfigs/android-api-11/nightly-nonunified index d4f72ea8a3e1..8229a4d5ab13 100644 --- a/mobile/android/config/mozconfigs/android-api-11/nightly-nonunified +++ b/mobile/android/config/mozconfigs/android-api-11/nightly-nonunified @@ -1,4 +1,4 @@ -. "$topsrcdir/mobile/android/config/mozconfigs/android-api-10/nightly" +. "$topsrcdir/mobile/android/config/mozconfigs/android-api-11/nightly" ac_add_options --disable-unified-compilation From 53da6fb716f40bbb2f0b3b69cdaf16c2536056a7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Dec 2014 18:59:53 -0800 Subject: [PATCH 073/183] Bug 1112968 - dmd.py: Tweak the --alloc-fns list for better effect on Windows. r=mccr8. --HG-- extra : rebase_source : 3dc8a09f9a22bf234406c0ff89d7b4050c7908e7 --- memory/replace/dmd/dmd.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/memory/replace/dmd/dmd.py b/memory/replace/dmd/dmd.py index 4a48a7c319ec..8ce6fb85033a 100755 --- a/memory/replace/dmd/dmd.py +++ b/memory/replace/dmd/dmd.py @@ -37,6 +37,8 @@ allocatorFns = [ 'memalign', 'operator new(', 'operator new[](', + 'NS_Alloc', + 'NS_Realloc', 'g_slice_alloc', # This one necessary to fully filter some sequences of allocation functions # that happen in practice. Note that ??? entries that follow non-allocation From dee00140c084a355fb5bc399d138eb6e26e823ac Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Dec 2014 21:23:28 -0800 Subject: [PATCH 074/183] Bug 1113037 - Use stack allocation in DrawTargetCairo::FillGlyphs() in the common case. r=mattwoodrow. --HG-- extra : rebase_source : f6270322664121cec3c82a7448c80963df6b0e5f --- gfx/2d/DrawTargetCairo.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/gfx/2d/DrawTargetCairo.cpp b/gfx/2d/DrawTargetCairo.cpp index b9586c52092f..61dc9da1616d 100644 --- a/gfx/2d/DrawTargetCairo.cpp +++ b/gfx/2d/DrawTargetCairo.cpp @@ -12,6 +12,7 @@ #include "BorrowedContext.h" #include "FilterNodeSoftware.h" #include "mozilla/Scoped.h" +#include "mozilla/Vector.h" #include "cairo.h" #include "cairo-tee.h" @@ -1148,8 +1149,16 @@ DrawTargetCairo::FillGlyphs(ScaledFont *aFont, cairo_set_antialias(mContext, GfxAntialiasToCairoAntialias(aOptions.mAntialiasMode)); - // Convert our GlyphBuffer into an array of Cairo glyphs. - std::vector glyphs(aBuffer.mNumGlyphs); + // Convert our GlyphBuffer into a vector of Cairo glyphs. This code can + // execute millions of times in short periods, so we want to avoid heap + // allocation whenever possible. So we use an inline vector capacity of 1024 + // bytes (the maximum allowed by mozilla::Vector), which gives an inline + // length of 1024 / 24 = 42 elements, which is enough to typically avoid heap + // allocation in ~99% of cases. + Vector glyphs; + if (!glyphs.resizeUninitialized(aBuffer.mNumGlyphs)) { + MOZ_CRASH("glyphs allocation failed"); + } for (uint32_t i = 0; i < aBuffer.mNumGlyphs; ++i) { glyphs[i].index = aBuffer.mGlyphs[i].mIndex; glyphs[i].x = aBuffer.mGlyphs[i].mPosition.x; From d5ae4983a3a47c8889b3caab98e78d8fae85f579 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 18 Dec 2014 21:23:30 -0800 Subject: [PATCH 075/183] Bug 1113037 - Use stack allocation in DrawTargetCG::FillGlyphs() in the common case. r=mattwoodrow. When viewing about:memory in verbose mode this reduces the number of heap allocations by over 10%. --HG-- extra : rebase_source : 954962295dcd90d66d0e02f782998884de879f17 --- gfx/2d/DrawTargetCG.cpp | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/gfx/2d/DrawTargetCG.cpp b/gfx/2d/DrawTargetCG.cpp index d0e4ba404e75..761f28eb43ba 100644 --- a/gfx/2d/DrawTargetCG.cpp +++ b/gfx/2d/DrawTargetCG.cpp @@ -2,6 +2,7 @@ * 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 "BorrowedContext.h" #include "DataSurfaceHelpers.h" #include "DrawTargetCG.h" @@ -15,8 +16,9 @@ #include "MacIOSurface.h" #include "FilterNodeSoftware.h" #include "mozilla/Assertions.h" -#include "mozilla/Types.h" // for decltype #include "mozilla/FloatingPoint.h" +#include "mozilla/Types.h" // for decltype +#include "mozilla/Vector.h" using namespace std; @@ -1343,11 +1345,16 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa ScaledFontMac* macFont = static_cast(aFont); - //XXX: we should use a stack vector here when we have a class like that - std::vector glyphs; - std::vector positions; - glyphs.resize(aBuffer.mNumGlyphs); - positions.resize(aBuffer.mNumGlyphs); + // This code can execute millions of times in short periods, so we want to + // avoid heap allocation whenever possible. So we use an inline vector + // capacity of 64 elements, which is enough to typically avoid heap + // allocation in ~99% of cases. + Vector glyphs; + Vector positions; + if (!glyphs.resizeUninitialized(aBuffer.mNumGlyphs) || + !positions.resizeUninitialized(aBuffer.mNumGlyphs)) { + MOZ_CRASH("glyphs/positions allocation failed"); + } // Handle the flip CGContextScaleCTM(cg, 1, -1); @@ -1370,19 +1377,19 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) { CGRect *bboxes = new CGRect[aBuffer.mNumGlyphs]; CTFontGetBoundingRectsForGlyphs(macFont->mCTFont, kCTFontDefaultOrientation, - &glyphs.front(), bboxes, aBuffer.mNumGlyphs); - extents = ComputeGlyphsExtents(bboxes, &positions.front(), aBuffer.mNumGlyphs, 1.0f); - ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, &glyphs.front(), - &positions.front(), aBuffer.mNumGlyphs, cg); + glyphs.begin(), bboxes, aBuffer.mNumGlyphs); + extents = ComputeGlyphsExtents(bboxes, positions.begin(), aBuffer.mNumGlyphs, 1.0f); + ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, glyphs.begin(), + positions.begin(), aBuffer.mNumGlyphs, cg); delete[] bboxes; } else { CGRect *bboxes = new CGRect[aBuffer.mNumGlyphs]; - CGFontGetGlyphBBoxes(macFont->mFont, &glyphs.front(), aBuffer.mNumGlyphs, bboxes); - extents = ComputeGlyphsExtents(bboxes, &positions.front(), aBuffer.mNumGlyphs, macFont->mSize); + CGFontGetGlyphBBoxes(macFont->mFont, glyphs.begin(), aBuffer.mNumGlyphs, bboxes); + extents = ComputeGlyphsExtents(bboxes, positions.begin(), aBuffer.mNumGlyphs, macFont->mSize); CGContextSetFont(cg, macFont->mFont); CGContextSetFontSize(cg, macFont->mSize); - CGContextShowGlyphsAtPositions(cg, &glyphs.front(), &positions.front(), + CGContextShowGlyphsAtPositions(cg, glyphs.begin(), positions.begin(), aBuffer.mNumGlyphs); delete[] bboxes; } @@ -1394,13 +1401,13 @@ DrawTargetCG::FillGlyphs(ScaledFont *aFont, const GlyphBuffer &aBuffer, const Pa CGContextSetTextDrawingMode(cg, kCGTextFill); SetFillFromPattern(cg, mColorSpace, aPattern); if (ScaledFontMac::CTFontDrawGlyphsPtr != nullptr) { - ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, &glyphs.front(), - &positions.front(), + ScaledFontMac::CTFontDrawGlyphsPtr(macFont->mCTFont, glyphs.begin(), + positions.begin(), aBuffer.mNumGlyphs, cg); } else { CGContextSetFont(cg, macFont->mFont); CGContextSetFontSize(cg, macFont->mSize); - CGContextShowGlyphsAtPositions(cg, &glyphs.front(), &positions.front(), + CGContextShowGlyphsAtPositions(cg, glyphs.begin(), positions.begin(), aBuffer.mNumGlyphs); } } From a6dc11c7e31063a4b7f77cb3aeb3a60bcd22952e Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Thu, 18 Dec 2014 22:26:52 -0800 Subject: [PATCH 076/183] Bug 1113282 - Check during async TrackBuffer decoder initialization to make sure we haven't been shut down. r=cajbir --- dom/media/mediasource/MediaSourceReader.cpp | 1 + dom/media/mediasource/TrackBuffer.cpp | 38 +++++++++++++++++---- dom/media/mediasource/TrackBuffer.h | 1 + 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index 0818e9f9d8f5..58815262cf6a 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -327,6 +327,7 @@ MediaSourceReader::Shutdown() void MediaSourceReader::ContinueShutdown() { + ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (mTrackBuffers.Length()) { mTrackBuffers[0]->Shutdown()->Then(GetTaskQueue(), __func__, this, &MediaSourceReader::ContinueShutdown, diff --git a/dom/media/mediasource/TrackBuffer.cpp b/dom/media/mediasource/TrackBuffer.cpp index d8ec425aef9a..a1ed3ce53ea2 100644 --- a/dom/media/mediasource/TrackBuffer.cpp +++ b/dom/media/mediasource/TrackBuffer.cpp @@ -39,12 +39,14 @@ TrackBuffer::TrackBuffer(MediaSourceDecoder* aParentDecoder, const nsACString& a : mParentDecoder(aParentDecoder) , mType(aType) , mLastStartTimestamp(0) + , mShutdown(false) { MOZ_COUNT_CTOR(TrackBuffer); mParser = ContainerParser::CreateForMIMEType(aType); mTaskQueue = new MediaTaskQueue(GetMediaDecodeThreadPool()); aParentDecoder->AddTrackBuffer(this); mDecoderPerSegment = Preferences::GetBool("media.mediasource.decoder-per-segment", false); + MSE_DEBUG("TrackBuffer(%p) created for parent decoder %p", this, aParentDecoder); } TrackBuffer::~TrackBuffer() @@ -101,6 +103,9 @@ private: nsRefPtr TrackBuffer::Shutdown() { + mParentDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); + mShutdown = true; + MOZ_ASSERT(mShutdownPromise.IsEmpty()); nsRefPtr p = mShutdownPromise.Ensure(__func__); @@ -370,23 +375,42 @@ TrackBuffer::QueueInitializeDecoder(SourceBufferDecoder* aDecoder) void TrackBuffer::InitializeDecoder(SourceBufferDecoder* aDecoder) { - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - - // ReadMetadata may block the thread waiting on data, so it must not be - // called with the monitor held. + // ReadMetadata may block the thread waiting on data, so we must be able + // to leave the monitor while we call it. For the rest of this function + // we want to hold the monitor though, since we run on a different task queue + // from the reader and interact heavily with it. mParentDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); + // We may be shut down at any time by the reader on another thread. So we need + // to check for this each time we acquire the monitor. If that happens, we + // need to abort immediately, because the reader has forgotten about us, and + // important pieces of our state (like mTaskQueue) have also been torn down. + if (mShutdown) { + MSE_DEBUG("TrackBuffer(%p) was shut down. Aborting initialization.", this); + return; + } + + MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); MediaDecoderReader* reader = aDecoder->GetReader(); MSE_DEBUG("TrackBuffer(%p): Initializing subdecoder %p reader %p", this, aDecoder, reader); MediaInfo mi; nsAutoPtr tags; // TODO: Handle metadata. - nsresult rv = reader->ReadMetadata(&mi, getter_Transfers(tags)); + nsresult rv; + { + ReentrantMonitorAutoExit mon(mParentDecoder->GetReentrantMonitor()); + rv = reader->ReadMetadata(&mi, getter_Transfers(tags)); + } + reader->SetIdle(); + if (mShutdown) { + MSE_DEBUG("TrackBuffer(%p) was shut down while reading metadata. Aborting initialization.", this); + return; + } if (NS_SUCCEEDED(rv) && reader->IsWaitingOnCDMResource()) { - ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); mWaitingDecoders.AppendElement(aDecoder); return; } @@ -442,7 +466,7 @@ TrackBuffer::ValidateTrackFormats(const MediaInfo& aInfo) bool TrackBuffer::RegisterDecoder(SourceBufferDecoder* aDecoder) { - ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); + mParentDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); const MediaInfo& info = aDecoder->GetReader()->GetMediaInfo(); // Initialize the track info since this is the first decoder. if (mInitializedDecoders.IsEmpty()) { diff --git a/dom/media/mediasource/TrackBuffer.h b/dom/media/mediasource/TrackBuffer.h index b7f416efd4e0..ecb40daff8b1 100644 --- a/dom/media/mediasource/TrackBuffer.h +++ b/dom/media/mediasource/TrackBuffer.h @@ -163,6 +163,7 @@ private: void ContinueShutdown(); MediaPromiseHolder mShutdownPromise; bool mDecoderPerSegment; + bool mShutdown; }; } // namespace mozilla From fa9389fcece52a5dacba63d301f4f24ecf74bea7 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Thu, 18 Dec 2014 17:06:08 -0800 Subject: [PATCH 077/183] Bug 1113308 - Further fixes for Windows builds via autospider.sh, r=terrence --HG-- extra : rebase_source : c18239800e95ec9837fdf5334675abe9744cd2ed --- js/src/devtools/automation/winbuildenv.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/src/devtools/automation/winbuildenv.sh b/js/src/devtools/automation/winbuildenv.sh index d3e7daebaa97..78030a9b8983 100644 --- a/js/src/devtools/automation/winbuildenv.sh +++ b/js/src/devtools/automation/winbuildenv.sh @@ -10,7 +10,7 @@ topsrcdir="$SOURCE" # When running on a developer machine, several variables will already # have the right settings and we will need to keep them since the # Windows mozconfigs overwrite them. -export OLD_INCLUDE="$INCLUDE" +export OLD_INCLUDE=$(IFS=';'; for d in $INCLUDE; do ( cd "$d" && echo -n $(pwd): ); done) export OLD_LIB=$(IFS=';'; for d in $LIB; do ( cd "$d" && echo -n $(pwd): ); done) export OLD_LIBPATH=$(IFS=';'; for d in $LIBPATH; do ( cd "$d" && echo -n $(pwd): ); done) @@ -46,6 +46,6 @@ fi # # Note that the mozconfig will use msys-style paths and OLD_INCLUDE will use # Windows-style paths, but perl and cl.exe both seem ok with either. -export INCLUDE="$(perl -le 'print join ":", grep { -d $_ } split(":", $ENV{INCLUDE}),split(";", $ENV{OLD_INCLUDE})')" +export INCLUDE="$(perl -le 'print join ":", grep { -d $_ } split(":", $ENV{INCLUDE}),split(":", $ENV{OLD_INCLUDE})')" export LIB="$(perl -le 'print join ":", grep { -d $_ } split(":", $ENV{LIB}),split(":", $ENV{OLD_LIB})')" export LIBPATH="$(perl -le 'print join ":", grep { -d $_ } split(":", $ENV{LIBPATH}),split(":", $ENV{OLD_LIBPATH})')" From 2faecc65b476081fe9077c6acab8e55f0a789692 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Tue, 16 Dec 2014 19:42:45 -0800 Subject: [PATCH 078/183] Bug 1113031 - Replace deprecated expression closures in about:sessionrestore with real functions. r=ttaubert --- .../sessionstore/content/aboutSessionRestore.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/browser/components/sessionstore/content/aboutSessionRestore.js b/browser/components/sessionstore/content/aboutSessionRestore.js index 3cdaa1981635..bc9aea8aee52 100644 --- a/browser/components/sessionstore/content/aboutSessionRestore.js +++ b/browser/components/sessionstore/content/aboutSessionRestore.js @@ -124,7 +124,7 @@ function restoreSession() { if (gTreeData[t].checked === 0) // this window will be restored partially gStateObject.windows[ix].tabs = - gStateObject.windows[ix].tabs.filter(function(aTabData, aIx) + gStateObject.windows[ix].tabs.filter((aTabData, aIx) => gTreeData[t].tabs[aIx].checked); else if (!gTreeData[t].checked) // this window won't be restored at all @@ -218,12 +218,14 @@ function getBrowserWindow() { } function toggleRowChecked(aIx) { + function isChecked(aItem) { + return aItem.checked; + } + var item = gTreeData[aIx]; item.checked = !item.checked; treeView.treeBox.invalidateRow(aIx); - function isChecked(aItem) aItem.checked; - if (treeView.isContainer(aIx)) { // (un)check all tabs of this window as well for (let tab of item.tabs) { From 2451d54e60948139d5b68bc9d516e8ef3f92bc30 Mon Sep 17 00:00:00 2001 From: Chris Peterson Date: Tue, 16 Dec 2014 19:14:12 -0800 Subject: [PATCH 079/183] Bug 1113032 - Replace deprecated expression closures in about:newtab with real functions. r=ttaubert --- browser/base/content/newtab/cells.js | 2 +- browser/base/content/newtab/drag.js | 8 ++++---- browser/base/content/newtab/drop.js | 2 +- browser/base/content/newtab/grid.js | 10 +++++----- browser/base/content/newtab/sites.js | 8 ++++---- 5 files changed, 15 insertions(+), 15 deletions(-) diff --git a/browser/base/content/newtab/cells.js b/browser/base/content/newtab/cells.js index 23cbd23bfdbc..47d4ef52d7d8 100644 --- a/browser/base/content/newtab/cells.js +++ b/browser/base/content/newtab/cells.js @@ -29,7 +29,7 @@ Cell.prototype = { /** * The cell's DOM node. */ - get node() this._node, + get node() { return this._node; }, /** * The cell's offset in the grid. diff --git a/browser/base/content/newtab/drag.js b/browser/base/content/newtab/drag.js index dfbe8199a95c..8f0bf674ee92 100644 --- a/browser/base/content/newtab/drag.js +++ b/browser/base/content/newtab/drag.js @@ -18,15 +18,15 @@ let gDrag = { * The site that is dragged. */ _draggedSite: null, - get draggedSite() this._draggedSite, + get draggedSite() { return this._draggedSite; }, /** * The cell width/height at the point the drag started. */ _cellWidth: null, _cellHeight: null, - get cellWidth() this._cellWidth, - get cellHeight() this._cellHeight, + get cellWidth() { return this._cellWidth; }, + get cellHeight() { return this._cellHeight; }, /** * Start a new drag operation. @@ -146,6 +146,6 @@ let gDrag = { // After the 'dragstart' event has been processed we can remove the // temporary drag element from the DOM. - setTimeout(function () scrollbox.removeChild(dragElement), 0); + setTimeout(() => scrollbox.removeChild(dragElement), 0); } }; diff --git a/browser/base/content/newtab/drop.js b/browser/base/content/newtab/drop.js index 7363396e81e4..d7bf30506881 100644 --- a/browser/base/content/newtab/drop.js +++ b/browser/base/content/newtab/drop.js @@ -73,7 +73,7 @@ let gDrop = { }); // Re-pin all shifted pinned cells. - pinnedSites.forEach(function (aSite) aSite.pin(sites.indexOf(aSite)), this); + pinnedSites.forEach(aSite => aSite.pin(sites.indexOf(aSite))); }, /** diff --git a/browser/base/content/newtab/grid.js b/browser/base/content/newtab/grid.js index 74b63d2d52e0..bdf9ab54aa92 100644 --- a/browser/base/content/newtab/grid.js +++ b/browser/base/content/newtab/grid.js @@ -18,7 +18,7 @@ let gGrid = { * The DOM node of the grid. */ _node: null, - get node() this._node, + get node() { return this._node; }, /** * The cached DOM fragment for sites. @@ -29,18 +29,18 @@ let gGrid = { * All cells contained in the grid. */ _cells: [], - get cells() this._cells, + get cells() { return this._cells; }, /** * All sites contained in the grid's cells. Sites may be empty. */ - get sites() [for (cell of this.cells) cell.site], + get sites() { return [for (cell of this.cells) cell.site]; }, // Tells whether the grid has already been initialized. - get ready() !!this._ready, + get ready() { return !!this._ready; }, // Returns whether the page has finished loading yet. - get isDocumentLoaded() document.readyState == "complete", + get isDocumentLoaded() { return document.readyState == "complete"; }, /** * Initializes the grid. diff --git a/browser/base/content/newtab/sites.js b/browser/base/content/newtab/sites.js index d7ba6124d3f7..9ee9f62d9979 100644 --- a/browser/base/content/newtab/sites.js +++ b/browser/base/content/newtab/sites.js @@ -22,22 +22,22 @@ Site.prototype = { /** * The site's DOM node. */ - get node() this._node, + get node() { return this._node; }, /** * The site's link. */ - get link() this._link, + get link() { return this._link; }, /** * The url of the site's link. */ - get url() this.link.url, + get url() { return this.link.url; }, /** * The title of the site's link. */ - get title() this.link.title, + get title() { return this.link.title; }, /** * The site's parent cell. From 449657cc1a1f2aaec70de09780dd91df078a7bd6 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Mon, 6 Oct 2014 16:45:14 +0100 Subject: [PATCH 080/183] Bug 1065366 - Implement ServiceWorkerGlobalScope update(), r=nsm --HG-- extra : rebase_source : abdca619a27b46693ead93a6f468a40b2eeab2cf --- .../base/nsIServiceWorkerManager.idl | 7 ++- dom/workers/ServiceWorkerManager.cpp | 62 +++++++++++++------ dom/workers/ServiceWorkerManager.h | 7 +-- dom/workers/WorkerScope.cpp | 41 ++++++++++++ dom/workers/WorkerScope.h | 5 +- 5 files changed, 93 insertions(+), 29 deletions(-) diff --git a/dom/interfaces/base/nsIServiceWorkerManager.idl b/dom/interfaces/base/nsIServiceWorkerManager.idl index 22616d20249f..f0aa315177fb 100644 --- a/dom/interfaces/base/nsIServiceWorkerManager.idl +++ b/dom/interfaces/base/nsIServiceWorkerManager.idl @@ -17,7 +17,7 @@ interface nsIServiceWorkerUnregisterCallback : nsISupports [noscript] void UnregisterFailed(); }; -[builtinclass, uuid(79ad5b57-d65d-46d3-b5e9-32d27e16052d)] +[builtinclass, uuid(78fdfe7c-0e2c-4157-ac6e-3952b61df36a)] interface nsIServiceWorkerManager : nsISupports { /** @@ -83,6 +83,11 @@ interface nsIServiceWorkerManager : nsISupports */ [noscript] nsISupports GetDocumentController(in nsIDOMWindow aWindow); + /* + * This implements the update algorithm. + */ + void update(in DOMString aScope); + // Testing DOMString getScopeForUrl(in DOMString path); }; diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index d68137104ab4..a0ff04d39849 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -259,7 +259,6 @@ class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports { nsRefPtr mRegistration; nsCString mScriptSpec; - nsCOMPtr mWindow; bool mAborted; @@ -268,12 +267,10 @@ class ServiceWorkerUpdateInstance MOZ_FINAL : public nsISupports public: NS_DECL_ISUPPORTS - ServiceWorkerUpdateInstance(ServiceWorkerRegistrationInfo *aRegistration, - nsPIDOMWindow* aWindow) + explicit ServiceWorkerUpdateInstance(ServiceWorkerRegistrationInfo *aRegistration) : mRegistration(aRegistration), // Capture the current script spec in case register() gets called. mScriptSpec(aRegistration->mScriptSpec), - mWindow(aWindow), mAborted(false) { AssertIsOnMainThread(); @@ -300,10 +297,8 @@ public: MOZ_ASSERT(swm); nsRefPtr serviceWorker; - nsresult rv = swm->CreateServiceWorkerForWindow(mWindow, - mScriptSpec, - mRegistration->mScope, - getter_AddRefs(serviceWorker)); + nsresult rv = swm->CreateServiceWorker(mScriptSpec, mRegistration->mScope, + getter_AddRefs(serviceWorker)); if (NS_WARN_IF(NS_FAILED(rv))) { swm->RejectUpdatePromiseObservers(mRegistration, rv); return; @@ -332,7 +327,7 @@ public: nsRefPtr swm = ServiceWorkerManager::GetInstance(); MOZ_ASSERT(swm); - swm->FinishFetch(mRegistration, mWindow); + swm->FinishFetch(mRegistration); } }; @@ -477,7 +472,7 @@ public: registration->mScriptSpec = spec; - rv = swm->Update(registration, mWindow); + rv = swm->Update(registration); MOZ_ASSERT(registration->HasUpdatePromise()); // We append this register() call's promise after calling Update() because @@ -950,9 +945,8 @@ ServiceWorkerManager::RejectUpdatePromiseObservers(ServiceWorkerRegistrationInfo * Update() does not return the Promise that the spec says it should. Callers * may access the registration's (new) Promise after calling this method. */ -NS_IMETHODIMP -ServiceWorkerManager::Update(ServiceWorkerRegistrationInfo* aRegistration, - nsPIDOMWindow* aWindow) +nsresult +ServiceWorkerManager::Update(ServiceWorkerRegistrationInfo* aRegistration) { if (aRegistration->HasUpdatePromise()) { NS_WARNING("Already had a UpdatePromise. Aborting that one!"); @@ -977,7 +971,7 @@ ServiceWorkerManager::Update(ServiceWorkerRegistrationInfo* aRegistration, // FIXME(nsm): Bug 931249. Force cache update if > 1 day. aRegistration->mUpdateInstance = - new ServiceWorkerUpdateInstance(aRegistration, aWindow); + new ServiceWorkerUpdateInstance(aRegistration); aRegistration->mUpdateInstance->Update(); return NS_OK; @@ -1101,8 +1095,7 @@ ServiceWorkerManager::ResolveRegisterPromises(ServiceWorkerRegistrationInfo* aRe // Must NS_Free() aString void -ServiceWorkerManager::FinishFetch(ServiceWorkerRegistrationInfo* aRegistration, - nsPIDOMWindow* aWindow) +ServiceWorkerManager::FinishFetch(ServiceWorkerRegistrationInfo* aRegistration) { AssertIsOnMainThread(); @@ -1117,10 +1110,9 @@ ServiceWorkerManager::FinishFetch(ServiceWorkerRegistrationInfo* aRegistration, // We have skipped Steps 3-8.3 of the Update algorithm here! nsRefPtr worker; - nsresult rv = CreateServiceWorkerForWindow(aWindow, - aRegistration->mScriptSpec, - aRegistration->mScope, - getter_AddRefs(worker)); + nsresult rv = CreateServiceWorker(aRegistration->mScriptSpec, + aRegistration->mScope, + getter_AddRefs(worker)); if (NS_WARN_IF(NS_FAILED(rv))) { RejectUpdatePromiseObservers(aRegistration, rv); @@ -2164,6 +2156,36 @@ ServiceWorkerManager::InvalidateServiceWorkerRegistrationWorker(ServiceWorkerReg } } +NS_IMETHODIMP +ServiceWorkerManager::Update(const nsAString& aScope) +{ + NS_ConvertUTF16toUTF8 scope(aScope); + + nsRefPtr domainInfo = + GetDomainInfo(scope); + if (NS_WARN_IF(!domainInfo)) { + return NS_OK; + } + + nsRefPtr registration; + domainInfo->mServiceWorkerRegistrationInfos.Get(scope, + getter_AddRefs(registration)); + if (NS_WARN_IF(!registration)) { + return NS_OK; + } + + if (registration->mPendingUninstall) { + return NS_OK; + } + + if (registration->mInstallingWorker) { + return NS_OK; + } + + Update(registration); + return NS_OK; +} + namespace { class MOZ_STACK_CLASS FilterRegistrationData diff --git a/dom/workers/ServiceWorkerManager.h b/dom/workers/ServiceWorkerManager.h index f58b24ecdecb..5c8a448c77c6 100644 --- a/dom/workers/ServiceWorkerManager.h +++ b/dom/workers/ServiceWorkerManager.h @@ -297,8 +297,7 @@ public: const ErrorEventInit& aErrorDesc); void - FinishFetch(ServiceWorkerRegistrationInfo* aRegistration, - nsPIDOMWindow* aWindow); + FinishFetch(ServiceWorkerRegistrationInfo* aRegistration); void FinishInstall(ServiceWorkerRegistrationInfo* aRegistration); @@ -331,8 +330,8 @@ private: void AbortCurrentUpdate(ServiceWorkerRegistrationInfo* aRegistration); - NS_IMETHOD - Update(ServiceWorkerRegistrationInfo* aRegistration, nsPIDOMWindow* aWindow); + nsresult + Update(ServiceWorkerRegistrationInfo* aRegistration); void Install(ServiceWorkerRegistrationInfo* aRegistration, diff --git a/dom/workers/WorkerScope.cpp b/dom/workers/WorkerScope.cpp index ae09764e01d3..93eedceebb22 100644 --- a/dom/workers/WorkerScope.cpp +++ b/dom/workers/WorkerScope.cpp @@ -639,4 +639,45 @@ ServiceWorkerGlobalScope::Unregister(ErrorResult& aRv) return promise.forget(); } +namespace { + +class UpdateRunnable MOZ_FINAL : public nsRunnable +{ + nsString mScope; + +public: + explicit UpdateRunnable(const nsAString& aScope) + : mScope(aScope) + { } + + NS_IMETHODIMP + Run() + { + AssertIsOnMainThread(); + + nsresult rv; + nsCOMPtr swm = + do_GetService(SERVICEWORKERMANAGER_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return NS_OK; + } + + swm->Update(mScope); + return NS_OK; + } +}; + +} //anonymous namespace + +void +ServiceWorkerGlobalScope::Update() +{ + mWorkerPrivate->AssertIsOnWorkerThread(); + MOZ_ASSERT(mWorkerPrivate->IsServiceWorker()); + + nsRefPtr runnable = + new UpdateRunnable(mScope); + NS_DispatchToMainThread(runnable); +} + END_WORKERS_NAMESPACE diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h index cfeec7de7a86..72d981aa0896 100644 --- a/dom/workers/WorkerScope.h +++ b/dom/workers/WorkerScope.h @@ -210,10 +210,7 @@ public: } void - Update() - { - // FIXME(nsm): Bug 982728 - } + Update(); already_AddRefed Unregister(ErrorResult& aRv); From eacfeed59fb03f5b9cc30fe776356cb084d46d19 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Fri, 19 Dec 2014 09:00:07 +0100 Subject: [PATCH 081/183] Backed out changeset 4757a1d4a23e (bug 1113282) for e10s M1 test failures --- dom/media/mediasource/MediaSourceReader.cpp | 1 - dom/media/mediasource/TrackBuffer.cpp | 40 +++++---------------- dom/media/mediasource/TrackBuffer.h | 1 - 3 files changed, 8 insertions(+), 34 deletions(-) diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index 58815262cf6a..0818e9f9d8f5 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -327,7 +327,6 @@ MediaSourceReader::Shutdown() void MediaSourceReader::ContinueShutdown() { - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (mTrackBuffers.Length()) { mTrackBuffers[0]->Shutdown()->Then(GetTaskQueue(), __func__, this, &MediaSourceReader::ContinueShutdown, diff --git a/dom/media/mediasource/TrackBuffer.cpp b/dom/media/mediasource/TrackBuffer.cpp index a1ed3ce53ea2..d8ec425aef9a 100644 --- a/dom/media/mediasource/TrackBuffer.cpp +++ b/dom/media/mediasource/TrackBuffer.cpp @@ -39,14 +39,12 @@ TrackBuffer::TrackBuffer(MediaSourceDecoder* aParentDecoder, const nsACString& a : mParentDecoder(aParentDecoder) , mType(aType) , mLastStartTimestamp(0) - , mShutdown(false) { MOZ_COUNT_CTOR(TrackBuffer); mParser = ContainerParser::CreateForMIMEType(aType); mTaskQueue = new MediaTaskQueue(GetMediaDecodeThreadPool()); aParentDecoder->AddTrackBuffer(this); mDecoderPerSegment = Preferences::GetBool("media.mediasource.decoder-per-segment", false); - MSE_DEBUG("TrackBuffer(%p) created for parent decoder %p", this, aParentDecoder); } TrackBuffer::~TrackBuffer() @@ -103,9 +101,6 @@ private: nsRefPtr TrackBuffer::Shutdown() { - mParentDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); - mShutdown = true; - MOZ_ASSERT(mShutdownPromise.IsEmpty()); nsRefPtr p = mShutdownPromise.Ensure(__func__); @@ -375,42 +370,23 @@ TrackBuffer::QueueInitializeDecoder(SourceBufferDecoder* aDecoder) void TrackBuffer::InitializeDecoder(SourceBufferDecoder* aDecoder) { - // ReadMetadata may block the thread waiting on data, so we must be able - // to leave the monitor while we call it. For the rest of this function - // we want to hold the monitor though, since we run on a different task queue - // from the reader and interact heavily with it. - mParentDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn(); - ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); - - // We may be shut down at any time by the reader on another thread. So we need - // to check for this each time we acquire the monitor. If that happens, we - // need to abort immediately, because the reader has forgotten about us, and - // important pieces of our state (like mTaskQueue) have also been torn down. - if (mShutdown) { - MSE_DEBUG("TrackBuffer(%p) was shut down. Aborting initialization.", this); - return; - } - MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); + + // ReadMetadata may block the thread waiting on data, so it must not be + // called with the monitor held. + mParentDecoder->GetReentrantMonitor().AssertNotCurrentThreadIn(); + MediaDecoderReader* reader = aDecoder->GetReader(); MSE_DEBUG("TrackBuffer(%p): Initializing subdecoder %p reader %p", this, aDecoder, reader); MediaInfo mi; nsAutoPtr tags; // TODO: Handle metadata. - nsresult rv; - { - ReentrantMonitorAutoExit mon(mParentDecoder->GetReentrantMonitor()); - rv = reader->ReadMetadata(&mi, getter_Transfers(tags)); - } - + nsresult rv = reader->ReadMetadata(&mi, getter_Transfers(tags)); reader->SetIdle(); - if (mShutdown) { - MSE_DEBUG("TrackBuffer(%p) was shut down while reading metadata. Aborting initialization.", this); - return; - } if (NS_SUCCEEDED(rv) && reader->IsWaitingOnCDMResource()) { + ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); mWaitingDecoders.AppendElement(aDecoder); return; } @@ -466,7 +442,7 @@ TrackBuffer::ValidateTrackFormats(const MediaInfo& aInfo) bool TrackBuffer::RegisterDecoder(SourceBufferDecoder* aDecoder) { - mParentDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(mParentDecoder->GetReentrantMonitor()); const MediaInfo& info = aDecoder->GetReader()->GetMediaInfo(); // Initialize the track info since this is the first decoder. if (mInitializedDecoders.IsEmpty()) { diff --git a/dom/media/mediasource/TrackBuffer.h b/dom/media/mediasource/TrackBuffer.h index ecb40daff8b1..b7f416efd4e0 100644 --- a/dom/media/mediasource/TrackBuffer.h +++ b/dom/media/mediasource/TrackBuffer.h @@ -163,7 +163,6 @@ private: void ContinueShutdown(); MediaPromiseHolder mShutdownPromise; bool mDecoderPerSegment; - bool mShutdown; }; } // namespace mozilla From e2cfd977a2e4bb36b9bc203eeefdebf861d6c7cb Mon Sep 17 00:00:00 2001 From: Richard Marti Date: Tue, 16 Dec 2014 17:59:38 +0100 Subject: [PATCH 082/183] Bug 1112263 - Remove the border around checkbox-label-box and radio-label-box. r=jaws --- toolkit/themes/windows/global/in-content/common.css | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/toolkit/themes/windows/global/in-content/common.css b/toolkit/themes/windows/global/in-content/common.css index b087b290d757..429d2e0cef36 100644 --- a/toolkit/themes/windows/global/in-content/common.css +++ b/toolkit/themes/windows/global/in-content/common.css @@ -61,3 +61,10 @@ xul|*.text-link:-moz-focusring, xul|*.inline-link:-moz-focusring { border: 1px dotted -moz-DialogText; } + +xul|radio:not([focused="true"]) > xul|*.radio-label-box, +xul|checkbox:not(:-moz-focusring) > xul|*.checkbox-label-box { + border-width: 0; + margin: 1px; + -moz-margin-start: 0; +} From cab354fdd1a2b4144e2554cb442b791eb12dc9ca Mon Sep 17 00:00:00 2001 From: ziyunfei <446240525@qq.com> Date: Thu, 18 Dec 2014 21:36:00 +0100 Subject: [PATCH 083/183] Bug 1111516 - Implement %TypedArray%.prototype.reverse. r=evilpie --- js/src/builtin/TypedArray.js | 38 +++++++++++++++ js/src/tests/ecma_6/TypedArray/reverse.js | 52 +++++++++++++++++++++ js/src/vm/TypedArrayObject.cpp | 1 + js/xpconnect/tests/chrome/test_xrayToJS.xul | 2 +- 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 js/src/tests/ecma_6/TypedArray/reverse.js diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js index efbe03abf65b..f51081d84f40 100644 --- a/js/src/builtin/TypedArray.js +++ b/js/src/builtin/TypedArray.js @@ -158,3 +158,41 @@ function TypedArrayLastIndexOf(searchElement, fromIndex = undefined) { // Step 12. return -1; } + +// ES6 draft rev29 (2014/12/06) 22.2.3.21 %TypedArray%.prototype.reverse(). +function TypedArrayReverse() { + // This function is not generic. + if (!IsObject(this) || !IsTypedArray(this)) { + return callFunction(CallTypedArrayMethodIfWrapped, this, "TypedArrayReverse"); + } + + // Steps 1-2. + var O = this; + + // Steps 3-5. + var len = TypedArrayLength(O); + + // Step 6. + var middle = std_Math_floor(len / 2); + + // Steps 7-8. + // Omit some steps, since there are no holes in typed arrays. + // Especially all the HasProperty/*exists checks always succeed. + for (var lower = 0; lower !== middle; lower++) { + // Step 8.a. + var upper = len - lower - 1; + + // Step 8.f.i. + var lowerValue = O[lower]; + + // Step 8.i.i. + var upperValue = O[upper]; + + // We always end up in the step 8.j. case. + O[lower] = upperValue; + O[upper] = lowerValue; + } + + // Step 9. + return O; +} diff --git a/js/src/tests/ecma_6/TypedArray/reverse.js b/js/src/tests/ecma_6/TypedArray/reverse.js new file mode 100644 index 000000000000..48775f3032a8 --- /dev/null +++ b/js/src/tests/ecma_6/TypedArray/reverse.js @@ -0,0 +1,52 @@ +const constructors = [ + Int8Array, + Uint8Array, + Uint8ClampedArray, + Int16Array, + Uint16Array, + Int32Array, + Uint32Array, + Float32Array, + Float64Array +]; + +for (var constructor of constructors) { + + assertDeepEq(constructor.prototype.reverse.length, 0); + + assertDeepEq(new constructor().reverse(), new constructor()); + assertDeepEq(new constructor(10).reverse(), new constructor(10)); + assertDeepEq(new constructor([]).reverse(), new constructor([])); + assertDeepEq(new constructor([1]).reverse(), new constructor([1])); + assertDeepEq(new constructor([1, 2]).reverse(), new constructor([2, 1])); + assertDeepEq(new constructor([1, 2, 3]).reverse(), new constructor([3, 2, 1])); + assertDeepEq(new constructor([1, 2, 3, 4]).reverse(), new constructor([4, 3, 2, 1])); + assertDeepEq(new constructor([1, 2, 3, 4, 5]).reverse(), new constructor([5, 4, 3, 2, 1])); + assertDeepEq(new constructor([.1, .2, .3]).reverse(), new constructor([.3, .2, .1])); + + // called from other globals + if (typeof newGlobal === "function") { + var reverse = newGlobal()[constructor.name].prototype.reverse; + assertDeepEq(reverse.call(new constructor([3, 2, 1])), new constructor([1, 2, 3])); + } + + // throws if `this` isn't a TypedArray + var nonTypedArrays = [undefined, null, 1, false, "", Symbol(), [], {}, /./, + /* new Proxy(new constructor(), {}) // this probably should throw */ + ]; + nonTypedArrays.forEach(nonTypedArray => { + assertThrowsInstanceOf(function() { + constructor.prototype.reverse.call(nonTypedArray); + }, TypeError, "Assert that reverse fails if this value is not a TypedArray"); + }); + + // test that this.length is never called + Object.defineProperty(new constructor([1, 2, 3]), "length", { + get() { + throw new Error("length accessor called"); + } + }).reverse(); +} + +if (typeof reportCompare === "function") + reportCompare(true, true); diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index ca84f8ef7a83..5c1b7c16b321 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -785,6 +785,7 @@ TypedArrayObject::protoFunctions[] = { JS_SELF_HOSTED_FN("findIndex", "TypedArrayFindIndex", 2, 0), JS_SELF_HOSTED_FN("indexOf", "TypedArrayIndexOf", 2, 0), JS_SELF_HOSTED_FN("lastIndexOf", "TypedArrayLastIndexOf", 2, 0), + JS_SELF_HOSTED_FN("reverse", "TypedArrayReverse", 0, 0), JS_FS_END }; diff --git a/js/xpconnect/tests/chrome/test_xrayToJS.xul b/js/xpconnect/tests/chrome/test_xrayToJS.xul index 9d787118d037..4c674b70c253 100644 --- a/js/xpconnect/tests/chrome/test_xrayToJS.xul +++ b/js/xpconnect/tests/chrome/test_xrayToJS.xul @@ -180,7 +180,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=933681 } gPrototypeProperties['TypedArray'] = ["length", "buffer", "byteLength", "byteOffset", kIteratorSymbol, "subarray", - "set", "copyWithin", "find", "findIndex", "indexOf", "lastIndexOf"]; + "set", "copyWithin", "find", "findIndex", "indexOf", "lastIndexOf", "reverse"]; for (var c of errorObjectClasses) { gPrototypeProperties[c] = ["constructor", "name", From 1e0e97bfcf522728743a6bdbfd9ca52fe089f45a Mon Sep 17 00:00:00 2001 From: Jamin Liu Date: Thu, 18 Dec 2014 17:51:00 +0100 Subject: [PATCH 084/183] Bug 1065751 - Support AGPS with roaming cell by retrieving mcc & mnc from nsIMobileNetworkInfo. r=kchen --- .../gonk/GonkGPSGeolocationProvider.cpp | 95 ++++++++++--------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/dom/system/gonk/GonkGPSGeolocationProvider.cpp b/dom/system/gonk/GonkGPSGeolocationProvider.cpp index 00b6e3c7d110..fbb098062f33 100644 --- a/dom/system/gonk/GonkGPSGeolocationProvider.cpp +++ b/dom/system/gonk/GonkGPSGeolocationProvider.cpp @@ -41,6 +41,7 @@ #include "nsIMobileConnectionInfo.h" #include "nsIMobileConnectionService.h" #include "nsIMobileCellInfo.h" +#include "nsIMobileNetworkInfo.h" #include "nsIRadioInterfaceLayer.h" #endif @@ -502,23 +503,35 @@ GonkGPSGeolocationProvider::SetReferenceLocation() return; } - nsCOMPtr rilCtx; - mRadioInterface->GetRilContext(getter_AddRefs(rilCtx)); - AGpsRefLocation location; // TODO: Bug 772750 - get mobile connection technology from rilcontext location.type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID; - if (rilCtx) { - nsCOMPtr iccInfo; - rilCtx->GetIccInfo(getter_AddRefs(iccInfo)); - if (iccInfo) { + nsCOMPtr service = + do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID); + if (!service) { + NS_WARNING("Cannot get MobileConnectionService"); + return; + } + + nsCOMPtr connection; + // TODO: Bug 878748 - B2G GPS: acquire correct RadioInterface instance in + // MultiSIM configuration + service->GetItemByServiceId(0 /* Client Id */, getter_AddRefs(connection)); + NS_ENSURE_TRUE_VOID(connection); + + nsCOMPtr voice; + connection->GetVoice(getter_AddRefs(voice)); + if (voice) { + nsCOMPtr networkInfo; + voice->GetNetwork(getter_AddRefs(networkInfo)); + if (networkInfo) { nsresult result; nsAutoString mcc, mnc; - iccInfo->GetMcc(mcc); - iccInfo->GetMnc(mnc); + networkInfo->GetMcc(mcc); + networkInfo->GetMnc(mnc); location.u.cellID.mcc = mcc.ToInteger(&result); if (result != NS_OK) { @@ -531,47 +544,41 @@ GonkGPSGeolocationProvider::SetReferenceLocation() NS_WARNING("Cannot parse mnc to integer"); location.u.cellID.mnc = 0; } + } else { + NS_WARNING("Cannot get mobile network info."); + location.u.cellID.mcc = 0; + location.u.cellID.mnc = 0; } - nsCOMPtr service = - do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID); - if (!service) { - NS_WARNING("Cannot get MobileConnectionService"); - return; - } + nsCOMPtr cell; + voice->GetCell(getter_AddRefs(cell)); + if (cell) { + int32_t lac; + int64_t cid; - nsCOMPtr connection; - // TODO: Bug 878748 - B2G GPS: acquire correct RadioInterface instance in - // MultiSIM configuration - service->GetItemByServiceId(0 /* Client Id */, getter_AddRefs(connection)); - NS_ENSURE_TRUE_VOID(connection); - - nsCOMPtr voice; - connection->GetVoice(getter_AddRefs(voice)); - if (voice) { - nsCOMPtr cell; - voice->GetCell(getter_AddRefs(cell)); - if (cell) { - int32_t lac; - int64_t cid; - - cell->GetGsmLocationAreaCode(&lac); - // The valid range of LAC is 0x0 to 0xffff which is defined in - // hardware/ril/include/telephony/ril.h - if (lac >= 0x0 && lac <= 0xffff) { - location.u.cellID.lac = lac; - } - - cell->GetGsmCellId(&cid); - // The valid range of cell id is 0x0 to 0xffffffff which is defined in - // hardware/ril/include/telephony/ril.h - if (cid >= 0x0 && cid <= 0xffffffff) { - location.u.cellID.cid = cid; - } + cell->GetGsmLocationAreaCode(&lac); + // The valid range of LAC is 0x0 to 0xffff which is defined in + // hardware/ril/include/telephony/ril.h + if (lac >= 0x0 && lac <= 0xffff) { + location.u.cellID.lac = lac; } + + cell->GetGsmCellId(&cid); + // The valid range of cell id is 0x0 to 0xffffffff which is defined in + // hardware/ril/include/telephony/ril.h + if (cid >= 0x0 && cid <= 0xffffffff) { + location.u.cellID.cid = cid; + } + } else { + NS_WARNING("Cannot get mobile gell info."); + location.u.cellID.lac = -1; + location.u.cellID.cid = -1; } - mAGpsRilInterface->set_ref_location(&location, sizeof(location)); + } else { + NS_WARNING("Cannot get mobile connection info."); + return; } + mAGpsRilInterface->set_ref_location(&location, sizeof(location)); } #endif // MOZ_B2G_RIL From 8714b58302bbc2d3b75470beb6e2a7f76dfc2ea8 Mon Sep 17 00:00:00 2001 From: Ted Clancy Date: Thu, 18 Dec 2014 17:40:41 -0500 Subject: [PATCH 085/183] Bug 1000305 - Part 1 - Add a getIcon() method. r=fabrice r=ehsan --- dom/apps/Webapps.js | 30 +++++++++++++++- dom/apps/Webapps.jsm | 80 ++++++++++++++++++++++++++++++++++++++++-- dom/webidl/Apps.webidl | 2 ++ 3 files changed, 109 insertions(+), 3 deletions(-) diff --git a/dom/apps/Webapps.js b/dom/apps/Webapps.js index 0d3c6c361704..ee06bd30e74e 100644 --- a/dom/apps/Webapps.js +++ b/dom/apps/Webapps.js @@ -748,6 +748,7 @@ WebappsApplicationMgmt.prototype = { "Webapps:Uninstall:Return:KO", "Webapps:Install:Return:OK", "Webapps:GetNotInstalled:Return:OK", + "Webapps:GetIcon:Return", "Webapps:Import:Return", "Webapps:ExtractManifest:Return", "Webapps:SetEnabled:Return"]); @@ -813,6 +814,21 @@ WebappsApplicationMgmt.prototype = { return request; }, + getIcon: function(aApp, aIconID, aEntryPoint) { + return this.createPromise(function(aResolve, aReject) { + cpmm.sendAsyncMessage("Webapps:GetIcon", { + oid: this._id, + manifestURL: aApp.manifestURL, + iconID: aIconID, + entryPoint: aEntryPoint, + requestID: this.getPromiseResolverId({ + resolve: aResolve, + reject: aReject + }) + }); + }.bind(this)); + }, + getNotInstalled: function() { let request = this.createRequest(); let principal = this._window.document.nodePrincipal; @@ -887,7 +903,8 @@ WebappsApplicationMgmt.prototype = { let msg = aMessage.data; let req; - if (["Webapps:Import:Return", + if (["Webapps:GetIcon:Return", + "Webapps:Import:Return", "Webapps:ExtractManifest:Return"] .indexOf(aMessage.name) != -1) { req = this.takePromiseResolver(msg.requestID); @@ -953,7 +970,18 @@ WebappsApplicationMgmt.prototype = { this.__DOM_IMPL__.dispatchEvent(event); } break; + case "Webapps:GetIcon:Return": + if (msg.blob) { + req.resolve(Cu.cloneInto(msg.blob, this._window)); + } else if (msg.error && msg.error == "NETWORK_ERROR" + && !this._window.navigator.onLine) { + req.reject(new this._window.DOMError("NETWORK_OFFLINE")); + } else { + req.reject(new this._window.DOMError(msg.error || "")); + } + break; } + if (aMessage.name !== "Webapps:Uninstall:Broadcast:Return:OK") { this.removeRequest(msg.requestID); } diff --git a/dom/apps/Webapps.jsm b/dom/apps/Webapps.jsm index 432dfb3adb8d..c48fa1e0b22c 100755 --- a/dom/apps/Webapps.jsm +++ b/dom/apps/Webapps.jsm @@ -221,6 +221,7 @@ this.DOMApplicationRegistry = { "Webapps:RegisterBEP", "Webapps:Export", "Webapps:Import", + "Webapps:GetIcon", "Webapps:ExtractManifest", "Webapps:SetEnabled", "child-process-shutdown"]; @@ -1405,6 +1406,9 @@ this.DOMApplicationRegistry = { case "Webapps:RegisterBEP": this.registerBrowserElementParentForApp(msg, mm); break; + case "Webapps:GetIcon": + this.getIcon(msg, mm); + break; case "Webapps:Export": this.doExport(msg, mm); break; @@ -4213,6 +4217,74 @@ this.DOMApplicationRegistry = { }); }, + getIcon: function(aData, aMm) { + function sendError(aError) { + debug("getIcon error: " + aError); + aData.error = aError; + aMm.sendAsyncMessage("Webapps:GetIcon:Return", aData); + } + + let app = this.getAppByManifestURL(aData.manifestURL); + if (!app) { + sendError("NO_APP"); + return; + } + + function loadIcon(aUrl) { + let fallbackMimeType = aUrl.indexOf('.') >= 0 ? + "image/" + aUrl.split(".").reverse()[0] : ""; + // Set up an xhr to download a blob. + let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest); + xhr.mozBackgroundRequest = true; + xhr.open("GET", aUrl, true); + xhr.responseType = "blob"; + xhr.addEventListener("load", function() { + debug("Got http status=" + xhr.status + " for " + aUrl); + if (xhr.status == 200) { + let blob = xhr.response; + // Reusing aData with sendAsyncMessage() leads to an empty blob in + // the child. + let payload = { + "oid": aData.oid, + "requestID": aData.requestID, + "blob": blob, + "type": xhr.getResponseHeader("Content-Type") || fallbackMimeType + }; + aMm.sendAsyncMessage("Webapps:GetIcon:Return", payload); + } else if (xhr.status === 0) { + sendError("NETWORK_ERROR"); + } else { + sendError("FETCH_ICON_FAILED"); + } + }); + xhr.addEventListener("error", function() { + sendError("FETCH_ICON_FAILED"); + }); + xhr.send(); + } + + // Get the manifest, to find the icon url in the current locale. + this.getManifestFor(aData.manifestURL, aData.entryPoint) + .then((aManifest) => { + if (!aManifest) { + sendError("FETCH_ICON_FAILED"); + return; + } + + let manifest = new ManifestHelper(aManifest, app.origin, app.manifestURL); + let url = manifest.iconURLForSize(aData.iconID); + if (!url) { + sendError("NO_ICON"); + return; + } + loadIcon(url); + }).catch(() => { + sendError("FETCH_ICON_FAILED"); + return; + }); + }, + getAll: function(aCallback) { debug("getAll"); let apps = []; @@ -4446,7 +4518,7 @@ this.DOMApplicationRegistry = { }); }, - getManifestFor: function(aManifestURL) { + getManifestFor: function(aManifestURL, aEntryPoint) { let id = this._appIdForManifestURL(aManifestURL); let app = this.webapps[id]; if (!id || (app.installState == "pending" && !app.retryingDownload)) { @@ -4454,7 +4526,11 @@ this.DOMApplicationRegistry = { } return this._readManifests([{ id: id }]).then((aResult) => { - return aResult[0].manifest; + if (aEntryPoint) { + return aResult[0].manifest.entry_points[aEntryPoint]; + } else { + return aResult[0].manifest; + } }); }, diff --git a/dom/webidl/Apps.webidl b/dom/webidl/Apps.webidl index 212ac8a415ec..b1180e262730 100644 --- a/dom/webidl/Apps.webidl +++ b/dom/webidl/Apps.webidl @@ -98,6 +98,8 @@ interface DOMApplicationsManager : EventTarget { Promise extractManifest(Blob blob); void setEnabled(DOMApplication app, boolean state); + Promise getIcon(DOMApplication app, DOMString iconID, + optional DOMString entryPoint); attribute EventHandler oninstall; attribute EventHandler onuninstall; From cca78a3e59588ce2cc182cce24f1da21685faa6c Mon Sep 17 00:00:00 2001 From: Ted Clancy Date: Thu, 18 Dec 2014 17:42:25 -0500 Subject: [PATCH 086/183] Bug 1000305 - Part 2 - Tests for getIcon(). r=ferjm r=waldo --- dom/apps/tests/file_manifest.json | 24 +++++---- dom/apps/tests/file_packaged_app.sjs | 10 ++++ .../tests/file_packaged_app.template.webapp | 3 ++ dom/apps/tests/icon15.png | Bin 0 -> 281 bytes dom/apps/tests/icon15alternate.png | Bin 0 -> 224 bytes dom/apps/tests/icon48.png | Bin 0 -> 4762 bytes dom/apps/tests/mochitest.ini | 3 ++ dom/apps/tests/test_packaged_app_install.html | 29 ++++++++++ dom/apps/tests/test_web_app_install.html | 51 ++++++++++++++++++ dom/tests/mochitest/webapps/test_list_api.xul | 1 + netwerk/test/httpserver/httpd.js | 2 + 11 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 dom/apps/tests/icon15.png create mode 100644 dom/apps/tests/icon15alternate.png create mode 100644 dom/apps/tests/icon48.png diff --git a/dom/apps/tests/file_manifest.json b/dom/apps/tests/file_manifest.json index 1569a1efe691..42a3f553fda8 100644 --- a/dom/apps/tests/file_manifest.json +++ b/dom/apps/tests/file_manifest.json @@ -1,13 +1,19 @@ { "name": "My W3C Web App", "short_name": "My App", - "icons": [ - { - "src": "/favicon.ico", - "sizes": "64x64", - "type": "image/png" - } - ], + "icons": { + "15": "/tests/dom/apps/tests/icon15.png", + "48": "/tests/dom/apps/tests/icon48.png" + }, "start_url": "/index.html", - "display": "standalone" -} \ No newline at end of file + "display": "standalone", + "entry_points": { + "ep1": { + "name": "This is an entry point", + "icons": { + "15": "/tests/dom/apps/tests/icon15alternate.png", + "48": "/tests/dom/apps/tests/icon48.png" + } + } + } +} diff --git a/dom/apps/tests/file_packaged_app.sjs b/dom/apps/tests/file_packaged_app.sjs index 788ff22b85f0..4bda60a7fe10 100644 --- a/dom/apps/tests/file_packaged_app.sjs +++ b/dom/apps/tests/file_packaged_app.sjs @@ -17,6 +17,13 @@ var gAppName = "appname"; var gDevName = "devname"; var gDevUrl = "http://dev.url"; +var gIconData = +"iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAAABGdBTUEAANbY1E9YMgAAABl0RVh0" + +"U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAA5UExURbVCQs6UlM6EhJwhIa0hIc5zc5wQ" + +"EL1SUu/W1rVjY6UQELUAAOfGxue1tZwAAIwAAP///3sAAK0AAOytg2MAAABmSURBVHjabIkLEsJA" + +"CEOz249aIUDvf1ihVWe208ADQvDeh8I+6s7zSw0wJ6vPA5z7o+u8LbrUD4SXnkln5XSHJnAhDWau" + +"tia1jeXlz7SeeRy5TC6wkBaWhLZoL4RF9Q/EqKv/CDAAFpEM3avxBREAAAAASUVORK5CYII="; + function handleRequest(request, response) { var query = getQuery(request); @@ -87,6 +94,9 @@ function handleRequest(request, response) { appName, devName, devUrl); addZipEntry(zipWriter, app, "index.html"); + var iconString = atob(gIconData); + addZipEntry(zipWriter, iconString, "icon.png"); + zipWriter.close(); } diff --git a/dom/apps/tests/file_packaged_app.template.webapp b/dom/apps/tests/file_packaged_app.template.webapp index 6d4bc0c7480f..14510b36b3f6 100644 --- a/dom/apps/tests/file_packaged_app.template.webapp +++ b/dom/apps/tests/file_packaged_app.template.webapp @@ -12,6 +12,9 @@ "downloads": {} }, "launch_path": "tests/dom/apps/tests/file_packaged_app.sjs", + "icons": { + "15": "icon.png" + }, "developer": { "name": "DEVELOPERTOKEN", "url": "DEVELOPERURLTOKEN" diff --git a/dom/apps/tests/icon15.png b/dom/apps/tests/icon15.png new file mode 100644 index 0000000000000000000000000000000000000000..f752986b7e13a7a2f6eba78c031245d6d5619883 GIT binary patch literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^{2l_A#9tMX0|NmDrFsx-@c(b-S8E8nF zr;B4q#jTu9ZlOaC9L}3>_eUu@yswW~7@EHA@&RV25BJ&+*}XdV*_+ouef4?fIlmXb z-lMzg3V+M=d7kM{OWM^66nWFuZByIY`}FDgE%Pd6cKYaTm>@Q-Wm|@Ri|beZBP&+_ b=P+Opo5*u_^+#4gpp6Wku6{1-oD!M<-aKpU literal 0 HcmV?d00001 diff --git a/dom/apps/tests/icon15alternate.png b/dom/apps/tests/icon15alternate.png new file mode 100644 index 0000000000000000000000000000000000000000..a85552b240fbde0ace475e0727267e611f8bb8ec GIT binary patch literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^{2%ROBjLo`H_Q>M;6;9!!V6s79% zFd+0S)5oXl-G83AS6lhGZATlMOG}@%(;!Mo$juMI5cX*Vzpp zAAY~zK``aB0#}3F?)pzGS5zIYZT`*Q;Kdp-^I^^cs|AxA9yuI4D0x{f-sZeT#wAXM Y;tX$h%O9_#fKF!cboFyt=akR{0Q6Q@KL7v# literal 0 HcmV?d00001 diff --git a/dom/apps/tests/icon48.png b/dom/apps/tests/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..c4307fc8418436bb6b2fd3a6afc702c2db28aa77 GIT binary patch literal 4762 zcmV;L5@qd)P)4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER000g#Nkl-k(>h5*rk*jGY3h=s;}LS}gf>m4rQ@{NxQSg49;C!L*x`|w zT469C%NXh+KmxsxSiN8S-uvu#7YS3_U>R%bwDq06v%B}+{r_{m?|kR`?_S0*4E%52 zn9m9PUnRiM2HY5%rZ9fv2@qUn*RFczwNMVXJ-8j)w?hMN0_W-*FS4y@)f#GRb(5Ph zOB2r`fo+^&G-w}p-TL|_zG+vrHd|S_YXWJB>@pbC0oCi9*zTfkzLd+cUB2A2Bx^z0 z%HZRvz7Xnm@_xS-e^@CrHggmW7hZrCCe0(TA(h-`7 z7fE_Lz`RA{Iw+up*|&Vn@?~dsFJluP=PC#`o3V^;oJh zST4`WLEy}v+$iFN0^?MlqBmcRB$e>Qg;QrjFXj9Aqp;gXC%VrktBZQ%U3GOP8e`T8 zOgl<#E!ek`uZ!MD!llc+pL5Lr*2F+pX*_zNz`f`}@7(eLZ;csj{! zgTZI{&T+5JBXS;C`8la!`))3fRqieGiy3Z7jCQMx%yHOJXUF0I3oFM!rQv(x27Wqb zpnXz@{gR4RdAi}1*yPazJxNv>eL-?^&xeO1qw`#)ELER!<8($$rf0v47CnCD|*cW_9MHw`9%-lTyG z*EPgDWNcm|>X)u3<9%%-9RVkH4n>vAF1s{ov5m&|ZV#%=tP`khWQ&Gl0+T3k8G3cIE9m_?bdH58YbYq^v35{Jwz3)Yq~=$_Cpu5-w6u^0^-=;~D@QAafosXrIk*U zSK9UAA$cO)AKB-!F#E@%T*xjbBeB+*%jk{-ZbqLvZ1A-$oE%6vl$h$~Y+{+rx^|0< zeSuxDN}7Z4$5}8$Age;a5dEe<$-?7jkQ~>bw8mj{$H1rxw3LjBH5L3d8F9JBwhQYqJQF z!Wxh}!qB1#z%Rlma6)%j({>^!b+DsR7{hcvCet+$%q`DF@ON^dS~zrFiY2eSalUoy zgL9u5A5FBJJ^yZ>BG}`t4YkUw5~ye_=e0nFGoDJiMXR_>QC#1ZG=ig zykvt);1dyA{O}wMjfKT-I*|r-cnnNp9BOI%QTEP_( zfeAp94Ok==fjLwg(Ky=Qz6Q1L666F~Y2kV-`U5|BKM)F~Qr7T9GgW}2;+>s z-FYyZ^jMF&x;lM!2%w(cM+Ju?$Hge{^053CYmw?Q{6U{h@(Zk+Cx4=K4`hUUx(M)P zssRnUJVpdUP}L!Df*(06z6@*rd<>jd;q-Etn;F55uSqD#^F)Utv7cU>5Pxp-_%44j zh&Gy(28A+fO9@ohbN+rwvRVa~#&H3GaeWWSTH`C6FR?xsYuGrz!a`4^5DQ(yWY0+? z2986E4}f=-K=5sbE3X`q&p~~{O(SwxoIim=oYgBAEnrtvEk#mMJ30npFLq7(fB0B6 zq8Bg1(%Ran)z;Q(pOS#N?K0nar!(S`W!7!8IaV>c@?D@B9lhG~}~?^Dmcw zK{XstzxuP*imt8}Qaukrte_}ogC$#KXnDb~v>RzhgGR;f^602qI*1HM7%Z#8OG~T8 zODb{i7pgIG>NI*oA;Y?Sxz^V5CjV#Kw}LF;-P0}q`B$s&x$o$wy`d4zqB4oJw)T1@ zN&9wtd*_bh$4^*}96gEQLDonren!(X2y}o5WP%m#1d^k^K+@q-w8V~}bWRwVWHMHf zfncG+S7a!15_yIBD6v@Zz~%?Q7Zu{)j~!Qsdsnh7BXd7*DFFu1)DM1sb%p7=IJeaE3ghs5K@k0Y5(Dg<0G0hnV< zgJBppEg7EYZW3bBfK3_k6lo@1*yg!ug66x0q+@Q1qQK>H(LKcytX^{u9f#I>p@SV6 z9%H(?JFf2E|MJ!=SFW_)mcSHvGZ5(xc;?KRM=~-po+>FRDL#4fBzErHsSXSba6X@p zF(=kE?Iws1zMEutp1(=t)^pRJ1yeqBjVT}V*usSiv3~t}WM^mV-Q7Lt?CfR-2m3KN zIM96R)T!?^H#h%^@Wnrpz!doOfg?wbEGsH1dO9yJuf~iBO`w@hIy5xIz4X$4G&D4( zQ|vdrX}7h}Db4E#4jg!-yuADc8jPcq8Z@z{swz*iq4c`bcG%Y5f<1fo;*DRPghjN# z?RH_h-`xuOqX?M5&1=o^NQPLqZXMRFSp!iNwab?;a|9ZcCO+ z-+I7pYoMW_;pD1StL`P~#3{Wt0-x5oBuSKR9fNfH7>`)t&jwC4zk)sg_#8Srdf;+9 z)7MO8^F!cG;O2K(mec2#E?tV6ni}Nf9MR|VPib1gi+iKk^R!OB9YMuX9*^(LM|p4%&pr2J{H*a1 z;)xhM9?wmAOp~DKrVG>rPh(>9=FPN34;m8_6Z+MwS2>daMZJ$Q@WR1^2lo?{cEYCK z4*2bAz_d&|dH$Z#($Yu$em|%VG%8@WprDX(IBa<8FB16sA6&(yL9PN8aTOIl4SBK zZO@I4j-Ht=(pzhCrmIo&Hyl}72~G5k{QUec(QYG0!2J0Oh{!xPFRzgKBZwr{=vRoA22iFU9e!mCerEGNu%p>b90cNUucw;78^^KEo3J~+<5Z{ zc`Yr}Hf+)0&*CsS8BaGThr^KuZ#FxMaysg(SFbjr(Wq_~sTpKn$&xHdrg_JrZx8W_fN~^7c}(Ho!n*C{@k4+ zl9nWW^p%yB{q~|oi?-+H=8~*(QBY8zFI-rLtgLK?oF;uO6|6yyLY=gmGc!OW`r6vs zOu0bB)RL^eN+gQSE=s#WE|VT?Y-}uDpcL^WkvMqx@Zo)= z`Du4yKC?$mAIOF@C9AIxiHFH@ou+M?o^N(oS`M5csqAfOX*u$7&FHguLUR)c5y_xF zv6dEL_mlhN5~( { + var reader = new FileReader(); + + reader.onloadend = function() { + var success = btoa(reader.result) == gIconData; + ok(success, "== TEST == Icon matches expected icon"); + PackagedTestHelper.next(); + } + + reader.readAsBinaryString(blob); + }, (err) => { + ok(false, "Can't get icon: " + err); + PackagedTestHelper.finish(); + }); + }, function() { info("== TEST == Install packaged app with a cancel/resume"); var miniManifestURL = PackagedTestHelper.gSJS + diff --git a/dom/apps/tests/test_web_app_install.html b/dom/apps/tests/test_web_app_install.html index c57f08b5e8ef..071aecb25301 100644 --- a/dom/apps/tests/test_web_app_install.html +++ b/dom/apps/tests/test_web_app_install.html @@ -19,6 +19,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={1075716}
 
 
From a670bb9fa6e7126622366c28d7b73876ee432c2c Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Wed, 26 Nov 2014 18:30:00 +0100 Subject: [PATCH 093/183] Bug 879717 - Part 2 - Test that drawing a video element to canvas never throws. r=roc --- dom/media/test/mochitest.ini | 1 + dom/media/test/test_bug879717.html | 119 +++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 dom/media/test/test_bug879717.html diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index 0b242c697c95..6479cc42ad61 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -332,6 +332,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 [test_bug726904.html] [test_bug874897.html] +[test_bug879717.html] [test_bug883173.html] [test_bug895091.html] [test_bug895305.html] diff --git a/dom/media/test/test_bug879717.html b/dom/media/test/test_bug879717.html new file mode 100644 index 000000000000..35e68fb2860f --- /dev/null +++ b/dom/media/test/test_bug879717.html @@ -0,0 +1,119 @@ + + + + Test for bug 879717, check that a video element can be drawn into a canvas at various states of playback + + + + + +
+
+
+ + From 099c1c9b788f8b3438f78f919ba8eea8b7b3c3ec Mon Sep 17 00:00:00 2001 From: Andreas Pehrson Date: Fri, 19 Dec 2014 01:25:00 +0100 Subject: [PATCH 094/183] Bug 879717 - Part 3 - Test video dimensions set on loadedmetadata event. r=roc --- dom/media/test/manifest.js | 2 +- dom/media/test/mochitest.ini | 1 + dom/media/test/test_video_dimensions.html | 67 +++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 dom/media/test/test_video_dimensions.html diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js index 28c25f261640..973bb3a8c21e 100644 --- a/dom/media/test/manifest.js +++ b/dom/media/test/manifest.js @@ -14,7 +14,7 @@ var gSmallTests = [ { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 }, { name:"vp9.webm", type:"video/webm", width:320, height:240, duration:4 }, { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 }, - { name:"gizmo.mp4", type:"video/mp4", duration:5.56 }, + { name:"gizmo.mp4", type:"video/mp4", width:560, height:320, duration:5.56 }, { name:"bogus.duh", type:"bogus/duh" } ]; diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index 6479cc42ad61..236fe8a5490c 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -470,6 +470,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 [test_reset_events_async.html] [test_reset_src.html] +[test_video_dimensions.html] [test_resume.html] skip-if = true # bug 1021673 [test_seek_out_of_range.html] diff --git a/dom/media/test/test_video_dimensions.html b/dom/media/test/test_video_dimensions.html new file mode 100644 index 000000000000..30cb959c9bc6 --- /dev/null +++ b/dom/media/test/test_video_dimensions.html @@ -0,0 +1,67 @@ + + + + Test that a video element has set video dimensions on loadedmetadata + + + + + +
+
+
+ + From be6a4e2137796937665f9776592275f8d6ba0857 Mon Sep 17 00:00:00 2001 From: "Carsten \"Tomcat\" Book" Date: Fri, 19 Dec 2014 10:47:41 +0100 Subject: [PATCH 095/183] Backed out changeset 2996cc51cb0d (bug 1000305) --- dom/apps/tests/file_manifest.json | 24 ++++----- dom/apps/tests/file_packaged_app.sjs | 10 ---- .../tests/file_packaged_app.template.webapp | 3 -- dom/apps/tests/icon15.png | Bin 281 -> 0 bytes dom/apps/tests/icon15alternate.png | Bin 224 -> 0 bytes dom/apps/tests/icon48.png | Bin 4762 -> 0 bytes dom/apps/tests/mochitest.ini | 3 -- dom/apps/tests/test_packaged_app_install.html | 29 ---------- dom/apps/tests/test_web_app_install.html | 51 ------------------ dom/tests/mochitest/webapps/test_list_api.xul | 1 - netwerk/test/httpserver/httpd.js | 2 - 11 files changed, 9 insertions(+), 114 deletions(-) delete mode 100644 dom/apps/tests/icon15.png delete mode 100644 dom/apps/tests/icon15alternate.png delete mode 100644 dom/apps/tests/icon48.png diff --git a/dom/apps/tests/file_manifest.json b/dom/apps/tests/file_manifest.json index 42a3f553fda8..1569a1efe691 100644 --- a/dom/apps/tests/file_manifest.json +++ b/dom/apps/tests/file_manifest.json @@ -1,19 +1,13 @@ { "name": "My W3C Web App", "short_name": "My App", - "icons": { - "15": "/tests/dom/apps/tests/icon15.png", - "48": "/tests/dom/apps/tests/icon48.png" - }, - "start_url": "/index.html", - "display": "standalone", - "entry_points": { - "ep1": { - "name": "This is an entry point", - "icons": { - "15": "/tests/dom/apps/tests/icon15alternate.png", - "48": "/tests/dom/apps/tests/icon48.png" - } + "icons": [ + { + "src": "/favicon.ico", + "sizes": "64x64", + "type": "image/png" } - } -} + ], + "start_url": "/index.html", + "display": "standalone" +} \ No newline at end of file diff --git a/dom/apps/tests/file_packaged_app.sjs b/dom/apps/tests/file_packaged_app.sjs index 4bda60a7fe10..788ff22b85f0 100644 --- a/dom/apps/tests/file_packaged_app.sjs +++ b/dom/apps/tests/file_packaged_app.sjs @@ -17,13 +17,6 @@ var gAppName = "appname"; var gDevName = "devname"; var gDevUrl = "http://dev.url"; -var gIconData = -"iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAAABGdBTUEAANbY1E9YMgAAABl0RVh0" + -"U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAA5UExURbVCQs6UlM6EhJwhIa0hIc5zc5wQ" + -"EL1SUu/W1rVjY6UQELUAAOfGxue1tZwAAIwAAP///3sAAK0AAOytg2MAAABmSURBVHjabIkLEsJA" + -"CEOz249aIUDvf1ihVWe208ADQvDeh8I+6s7zSw0wJ6vPA5z7o+u8LbrUD4SXnkln5XSHJnAhDWau" + -"tia1jeXlz7SeeRy5TC6wkBaWhLZoL4RF9Q/EqKv/CDAAFpEM3avxBREAAAAASUVORK5CYII="; - function handleRequest(request, response) { var query = getQuery(request); @@ -94,9 +87,6 @@ function handleRequest(request, response) { appName, devName, devUrl); addZipEntry(zipWriter, app, "index.html"); - var iconString = atob(gIconData); - addZipEntry(zipWriter, iconString, "icon.png"); - zipWriter.close(); } diff --git a/dom/apps/tests/file_packaged_app.template.webapp b/dom/apps/tests/file_packaged_app.template.webapp index 14510b36b3f6..6d4bc0c7480f 100644 --- a/dom/apps/tests/file_packaged_app.template.webapp +++ b/dom/apps/tests/file_packaged_app.template.webapp @@ -12,9 +12,6 @@ "downloads": {} }, "launch_path": "tests/dom/apps/tests/file_packaged_app.sjs", - "icons": { - "15": "icon.png" - }, "developer": { "name": "DEVELOPERTOKEN", "url": "DEVELOPERURLTOKEN" diff --git a/dom/apps/tests/icon15.png b/dom/apps/tests/icon15.png deleted file mode 100644 index f752986b7e13a7a2f6eba78c031245d6d5619883..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^{2l_A#9tMX0|NmDrFsx-@c(b-S8E8nF zr;B4q#jTu9ZlOaC9L}3>_eUu@yswW~7@EHA@&RV25BJ&+*}XdV*_+ouef4?fIlmXb z-lMzg3V+M=d7kM{OWM^66nWFuZByIY`}FDgE%Pd6cKYaTm>@Q-Wm|@Ri|beZBP&+_ b=P+Opo5*u_^+#4gpp6Wku6{1-oD!M<-aKpU diff --git a/dom/apps/tests/icon15alternate.png b/dom/apps/tests/icon15alternate.png deleted file mode 100644 index a85552b240fbde0ace475e0727267e611f8bb8ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^{2%ROBjLo`H_Q>M;6;9!!V6s79% zFd+0S)5oXl-G83AS6lhGZATlMOG}@%(;!Mo$juMI5cX*Vzpp zAAY~zK``aB0#}3F?)pzGS5zIYZT`*Q;Kdp-^I^^cs|AxA9yuI4D0x{f-sZeT#wAXM Y;tX$h%O9_#fKF!cboFyt=akR{0Q6Q@KL7v# diff --git a/dom/apps/tests/icon48.png b/dom/apps/tests/icon48.png deleted file mode 100644 index c4307fc8418436bb6b2fd3a6afc702c2db28aa77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4762 zcmV;L5@qd)P)4Tx05}naRo`#hR1`jmZ&IWdKOk5~hl<6oRa0BJ8yc;~21%2p?MfD<>DVeH z9(p*dx19w`~g7O0}n_%Aq@s%d)fBDv`JHkDym6Hd+5XuAtvnwRpGmK zVkc9?T=n|PIo~X-eVh__(Z?q}P9Z-Dj?gOW6|D%o20XmjW-qs4UjrD(li^iv8@eK9k+ZFm zVRFymFOPAzG5-%Pn|1W;U4vNroTa&AxDScmEA~{ri9gr1^c?U@uwSpaNnw8l_>cP1 zd;)kMQS_;jeRSUEM_*s96y65j1$)tOrwdK{YIQMt92l|D^(E_=$Rjw{b!QT@q!)ni zR`|5oW9X5n$Wv+HVc@|^eX5yXnsHX8PF3UX~a6)MwxDE0HaPjyrlI!;jX{6Kvuh*8ej?;85ekN$?5uuCiS zBTvvVG+XTxAO{m@bvM#Jr)z6J><&E22D|vq?Y?Vkbo_DijopiF$2PET#mZ8eu=y$(ArYkv7@Ex`GL?QCc!_*KFrd&;n1r7 zqW-CFs9&fT)ZaU5gc&=gBz-DaCw(vdOp0__x+47~U6sC(E(JNe@4cTT*n6*E zVH4eoU1-&7pEV~_PRe`a7v+@vy!^5}8?Y3)UmlaER000g#Nkl-k(>h5*rk*jGY3h=s;}LS}gf>m4rQ@{NxQSg49;C!L*x`|w zT469C%NXh+KmxsxSiN8S-uvu#7YS3_U>R%bwDq06v%B}+{r_{m?|kR`?_S0*4E%52 zn9m9PUnRiM2HY5%rZ9fv2@qUn*RFczwNMVXJ-8j)w?hMN0_W-*FS4y@)f#GRb(5Ph zOB2r`fo+^&G-w}p-TL|_zG+vrHd|S_YXWJB>@pbC0oCi9*zTfkzLd+cUB2A2Bx^z0 z%HZRvz7Xnm@_xS-e^@CrHggmW7hZrCCe0(TA(h-`7 z7fE_Lz`RA{Iw+up*|&Vn@?~dsFJluP=PC#`o3V^;oJh zST4`WLEy}v+$iFN0^?MlqBmcRB$e>Qg;QrjFXj9Aqp;gXC%VrktBZQ%U3GOP8e`T8 zOgl<#E!ek`uZ!MD!llc+pL5Lr*2F+pX*_zNz`f`}@7(eLZ;csj{! zgTZI{&T+5JBXS;C`8la!`))3fRqieGiy3Z7jCQMx%yHOJXUF0I3oFM!rQv(x27Wqb zpnXz@{gR4RdAi}1*yPazJxNv>eL-?^&xeO1qw`#)ELER!<8($$rf0v47CnCD|*cW_9MHw`9%-lTyG z*EPgDWNcm|>X)u3<9%%-9RVkH4n>vAF1s{ov5m&|ZV#%=tP`khWQ&Gl0+T3k8G3cIE9m_?bdH58YbYq^v35{Jwz3)Yq~=$_Cpu5-w6u^0^-=;~D@QAafosXrIk*U zSK9UAA$cO)AKB-!F#E@%T*xjbBeB+*%jk{-ZbqLvZ1A-$oE%6vl$h$~Y+{+rx^|0< zeSuxDN}7Z4$5}8$Age;a5dEe<$-?7jkQ~>bw8mj{$H1rxw3LjBH5L3d8F9JBwhQYqJQF z!Wxh}!qB1#z%Rlma6)%j({>^!b+DsR7{hcvCet+$%q`DF@ON^dS~zrFiY2eSalUoy zgL9u5A5FBJJ^yZ>BG}`t4YkUw5~ye_=e0nFGoDJiMXR_>QC#1ZG=ig zykvt);1dyA{O}wMjfKT-I*|r-cnnNp9BOI%QTEP_( zfeAp94Ok==fjLwg(Ky=Qz6Q1L666F~Y2kV-`U5|BKM)F~Qr7T9GgW}2;+>s z-FYyZ^jMF&x;lM!2%w(cM+Ju?$Hge{^053CYmw?Q{6U{h@(Zk+Cx4=K4`hUUx(M)P zssRnUJVpdUP}L!Df*(06z6@*rd<>jd;q-Etn;F55uSqD#^F)Utv7cU>5Pxp-_%44j zh&Gy(28A+fO9@ohbN+rwvRVa~#&H3GaeWWSTH`C6FR?xsYuGrz!a`4^5DQ(yWY0+? z2986E4}f=-K=5sbE3X`q&p~~{O(SwxoIim=oYgBAEnrtvEk#mMJ30npFLq7(fB0B6 zq8Bg1(%Ran)z;Q(pOS#N?K0nar!(S`W!7!8IaV>c@?D@B9lhG~}~?^Dmcw zK{XstzxuP*imt8}Qaukrte_}ogC$#KXnDb~v>RzhgGR;f^602qI*1HM7%Z#8OG~T8 zODb{i7pgIG>NI*oA;Y?Sxz^V5CjV#Kw}LF;-P0}q`B$s&x$o$wy`d4zqB4oJw)T1@ zN&9wtd*_bh$4^*}96gEQLDonren!(X2y}o5WP%m#1d^k^K+@q-w8V~}bWRwVWHMHf zfncG+S7a!15_yIBD6v@Zz~%?Q7Zu{)j~!Qsdsnh7BXd7*DFFu1)DM1sb%p7=IJeaE3ghs5K@k0Y5(Dg<0G0hnV< zgJBppEg7EYZW3bBfK3_k6lo@1*yg!ug66x0q+@Q1qQK>H(LKcytX^{u9f#I>p@SV6 z9%H(?JFf2E|MJ!=SFW_)mcSHvGZ5(xc;?KRM=~-po+>FRDL#4fBzErHsSXSba6X@p zF(=kE?Iws1zMEutp1(=t)^pRJ1yeqBjVT}V*usSiv3~t}WM^mV-Q7Lt?CfR-2m3KN zIM96R)T!?^H#h%^@Wnrpz!doOfg?wbEGsH1dO9yJuf~iBO`w@hIy5xIz4X$4G&D4( zQ|vdrX}7h}Db4E#4jg!-yuADc8jPcq8Z@z{swz*iq4c`bcG%Y5f<1fo;*DRPghjN# z?RH_h-`xuOqX?M5&1=o^NQPLqZXMRFSp!iNwab?;a|9ZcCO+ z-+I7pYoMW_;pD1StL`P~#3{Wt0-x5oBuSKR9fNfH7>`)t&jwC4zk)sg_#8Srdf;+9 z)7MO8^F!cG;O2K(mec2#E?tV6ni}Nf9MR|VPib1gi+iKk^R!OB9YMuX9*^(LM|p4%&pr2J{H*a1 z;)xhM9?wmAOp~DKrVG>rPh(>9=FPN34;m8_6Z+MwS2>daMZJ$Q@WR1^2lo?{cEYCK z4*2bAz_d&|dH$Z#($Yu$em|%VG%8@WprDX(IBa<8FB16sA6&(yL9PN8aTOIl4SBK zZO@I4j-Ht=(pzhCrmIo&Hyl}72~G5k{QUec(QYG0!2J0Oh{!xPFRzgKBZwr{=vRoA22iFU9e!mCerEGNu%p>b90cNUucw;78^^KEo3J~+<5Z{ zc`Yr}Hf+)0&*CsS8BaGThr^KuZ#FxMaysg(SFbjr(Wq_~sTpKn$&xHdrg_JrZx8W_fN~^7c}(Ho!n*C{@k4+ zl9nWW^p%yB{q~|oi?-+H=8~*(QBY8zFI-rLtgLK?oF;uO6|6yyLY=gmGc!OW`r6vs zOu0bB)RL^eN+gQSE=s#WE|VT?Y-}uDpcL^WkvMqx@Zo)= z`Du4yKC?$mAIOF@C9AIxiHFH@ou+M?o^N(oS`M5csqAfOX*u$7&FHguLUR)c5y_xF zv6dEL_mlhN5~( { - var reader = new FileReader(); - - reader.onloadend = function() { - var success = btoa(reader.result) == gIconData; - ok(success, "== TEST == Icon matches expected icon"); - PackagedTestHelper.next(); - } - - reader.readAsBinaryString(blob); - }, (err) => { - ok(false, "Can't get icon: " + err); - PackagedTestHelper.finish(); - }); - }, function() { info("== TEST == Install packaged app with a cancel/resume"); var miniManifestURL = PackagedTestHelper.gSJS + diff --git a/dom/apps/tests/test_web_app_install.html b/dom/apps/tests/test_web_app_install.html index 071aecb25301..c57f08b5e8ef 100644 --- a/dom/apps/tests/test_web_app_install.html +++ b/dom/apps/tests/test_web_app_install.html @@ -19,19 +19,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id={1075716}
 
   
   
diff --git a/mobile/android/base/tests/testHomeBanner.java b/mobile/android/base/tests/testHomeBanner.java
index f8345ef80321..bce3ecf5462c 100644
--- a/mobile/android/base/tests/testHomeBanner.java
+++ b/mobile/android/base/tests/testHomeBanner.java
@@ -22,10 +22,6 @@ public class testHomeBanner extends UITest {
         // Make sure the banner hides when the user starts interacting with the url bar.
         hideOnToolbarFocusTest();
 
-        // TODO: API doesn't actually support this but it used to work due to how the banner was
-        // part of TopSitesPanel's lifecycle
-        // removeBannerTest();
-
         // Make sure to test dismissing the banner after everything else, since dismissing
         // the banner will prevent it from showing up again.
         dismissBannerTest();
@@ -47,53 +43,12 @@ public class testHomeBanner extends UITest {
         // Verify that the banner is visible with the correct text.
         mAboutHome.assertBannerText(TEXT);
 
-        // Test to make sure the onclick handler is called.
-        eventExpecter = getActions().expectGeckoEvent("TestHomeBanner:MessageClicked");
-        mAboutHome.clickOnBanner();
-        eventExpecter.blockForEvent();
-
         // Verify that the banner isn't visible after navigating away from about:home.
         NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_FIREFOX_URL);
-
         mAboutHome.assertBannerNotVisible();
     }
 
 
-    /**
-     * Removes a banner message, and verifies that it no longer appears on about:home.
-     *
-     * Note: This test expects for a message to have been added before it runs.
-     */
-    private void removeBannerTest() {
-        removeBannerMessage();
-
-        // Verify that the banner no longer appears.
-        NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_HOME_URL);
-        mAboutHome.assertVisible()
-                  .assertBannerNotVisible();
-    }
-
-    /**
-     * Adds a banner message, verifies that its ondismiss handler is called in JS,
-     * and verifies that the banner is no longer shown after it is dismissed.
-     *
-     * Note: This test does not remove the message after it is done.
-     */
-    private void dismissBannerTest() {
-        // Add back the banner message to test the dismiss functionality.
-        addBannerMessage();
-
-        NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_HOME_URL);
-        mAboutHome.assertVisible();
-
-        // Test to make sure the ondismiss handler is called when the close button is clicked.
-        final Actions.EventExpecter eventExpecter = getActions().expectGeckoEvent("TestHomeBanner:MessageDismissed");
-        mAboutHome.dismissBanner();
-        eventExpecter.blockForEvent();
-
-        mAboutHome.assertBannerNotVisible();
-    }
-
     private void hideOnToolbarFocusTest() {
         NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_HOME_URL);
         mAboutHome.assertVisible()
@@ -106,6 +61,24 @@ public class testHomeBanner extends UITest {
         mAboutHome.assertBannerVisible();
     }
 
+    /**
+     * Adds a banner message, verifies that its ondismiss handler is called in JS,
+     * and verifies that the banner is no longer shown after it is dismissed.
+     *
+     * Note: This test does not remove the message after it is done.
+     */
+    private void dismissBannerTest() {
+        NavigationHelper.enterAndLoadUrl(StringHelper.ABOUT_HOME_URL);
+        mAboutHome.assertVisible();
+
+        // Test to make sure the ondismiss handler is called when the close button is clicked.
+        final Actions.EventExpecter eventExpecter = getActions().expectGeckoEvent("TestHomeBanner:MessageDismissed");
+        mAboutHome.dismissBanner();
+        eventExpecter.blockForEvent();
+
+        mAboutHome.assertBannerNotVisible();
+    }
+
     /**
      * Loads the roboextender page to add a message to the banner.
      */
@@ -114,13 +87,4 @@ public class testHomeBanner extends UITest {
         NavigationHelper.enterAndLoadUrl(TEST_URL + "#addMessage");
         eventExpecter.blockForEvent();
     }
-
-    /**
-     * Loads the roboextender page to remove the message from the banner.
-     */
-    private void removeBannerMessage() {
-        final Actions.EventExpecter eventExpecter = getActions().expectGeckoEvent("TestHomeBanner:MessageRemoved");
-        NavigationHelper.enterAndLoadUrl(TEST_URL + "#removeMessage");
-        eventExpecter.blockForEvent();
-    }
 }

From fc37f6f0196908167414198a9776a866532b045d Mon Sep 17 00:00:00 2001
From: Geoff Brown 
Date: Fri, 19 Dec 2014 09:22:07 -0700
Subject: [PATCH 124/183] Bug 1090927 - Rename private test... functions in
 testGeckoProfile; r=mfinkle

---
 .../android/base/tests/testGeckoProfile.java  | 76 +++++++++----------
 1 file changed, 38 insertions(+), 38 deletions(-)

diff --git a/mobile/android/base/tests/testGeckoProfile.java b/mobile/android/base/tests/testGeckoProfile.java
index ada10ae00b6c..d891fd24dedf 100644
--- a/mobile/android/base/tests/testGeckoProfile.java
+++ b/mobile/android/base/tests/testGeckoProfile.java
@@ -37,12 +37,12 @@ public class testGeckoProfile extends PixelTest {
             return;
         }
 
-        testProfileCreationDeletion();
-        testGuestProfile();
+        checkProfileCreationDeletion();
+        checkGuestProfile();
     }
 
     // This getter just passes an activity. Passing null should throw.
-    private void testDefaultGetter() {
+    private void checkDefaultGetter() {
         mAsserter.info("Test using the default profile", GeckoProfile.DEFAULT_PROFILE);
         GeckoProfile profile = GeckoProfile.get(getActivity());
         // This profile has been forced into something strange by the test harness, but its name is still right...
@@ -57,7 +57,7 @@ public class testGeckoProfile extends PixelTest {
     }
 
     // Test get(Context, String) methods
-    private void testNamedGetter(String name) {
+    private void checkNamedGetter(String name) {
         mAsserter.info("Test using a named profile", name);
         GeckoProfile profile = GeckoProfile.get(getActivity(), name);
         if (!TextUtils.isEmpty(name)) {
@@ -71,16 +71,16 @@ public class testGeckoProfile extends PixelTest {
     }
 
     // Test get(Context, String, String) methods
-    private void testNameAndPathGetter(String name, boolean createBefore) {
+    private void checkNameAndPathGetter(String name, boolean createBefore) {
         if (TextUtils.isEmpty(name)) {
-            testNameAndPathGetter(name, null, createBefore);
+            checkNameAndPathGetter(name, null, createBefore);
         } else {
-            testNameAndPathGetter(name, name + "_FORCED_DIR", createBefore);
+            checkNameAndPathGetter(name, name + "_FORCED_DIR", createBefore);
         }
     }
 
     // Test get(Context, String, String) methods
-    private void testNameAndPathGetter(String name, String path, boolean createBefore) {
+    private void checkNameAndPathGetter(String name, String path, boolean createBefore) {
         mAsserter.info("Test using a named profile and path", name + ", " + path);
 
         File f = null;
@@ -109,15 +109,15 @@ public class testGeckoProfile extends PixelTest {
         }
     }
 
-    private void testNameAndFileGetter(String name, boolean createBefore) {
+    private void checkNameAndFileGetter(String name, boolean createBefore) {
         if (TextUtils.isEmpty(name)) {
-            testNameAndFileGetter(name, null, createBefore);
+            checkNameAndFileGetter(name, null, createBefore);
         } else {
-            testNameAndFileGetter(name, new File(mozDir, name + "_FORCED_DIR"), createBefore);
+            checkNameAndFileGetter(name, new File(mozDir, name + "_FORCED_DIR"), createBefore);
         }
     }
 
-    private void testNameAndFileGetter(String name, File f, boolean createBefore) {
+    private void checkNameAndFileGetter(String name, File f, boolean createBefore) {
         mAsserter.info("Test using a named profile and path", name + ", " + f);
         if (f != null && createBefore) {
             f.mkdir();
@@ -139,48 +139,48 @@ public class testGeckoProfile extends PixelTest {
         }
     }
 
-    private void testProfileCreationDeletion() {
+    private void checkProfileCreationDeletion() {
         // Test
-        testDefaultGetter();
+        checkDefaultGetter();
 
         int index = 0;
-        testNamedGetter(TEST_PROFILE_NAME + (index++)); // 0
-        testNamedGetter("");
-        testNamedGetter(null);
+        checkNamedGetter(TEST_PROFILE_NAME + (index++)); // 0
+        checkNamedGetter("");
+        checkNamedGetter(null);
 
         // name and path
-        testNameAndPathGetter(TEST_PROFILE_NAME + (index++), true); // 1
-        testNameAndPathGetter(TEST_PROFILE_NAME + (index++), false); // 2
+        checkNameAndPathGetter(TEST_PROFILE_NAME + (index++), true); // 1
+        checkNameAndPathGetter(TEST_PROFILE_NAME + (index++), false); // 2
         // null name and path
-        testNameAndPathGetter(null, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", true); // 3
-        testNameAndPathGetter(null, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", false); // 4
-        testNameAndPathGetter("", TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", true); // 5
-        testNameAndPathGetter("", TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", false); // 6
+        checkNameAndPathGetter(null, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", true); // 3
+        checkNameAndPathGetter(null, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", false); // 4
+        checkNameAndPathGetter("", TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", true); // 5
+        checkNameAndPathGetter("", TEST_PROFILE_NAME + (index++) + "_FORCED_DIR", false); // 6
         // name and null path
-        testNameAndPathGetter(TEST_PROFILE_NAME + (index++), null, false); // 7
-        testNameAndPathGetter(TEST_PROFILE_NAME + (index++), "", false); // 8
+        checkNameAndPathGetter(TEST_PROFILE_NAME + (index++), null, false); // 7
+        checkNameAndPathGetter(TEST_PROFILE_NAME + (index++), "", false); // 8
         // null name and null path
-        testNameAndPathGetter(null, null, false);
-        testNameAndPathGetter("", null, false);
-        testNameAndPathGetter(null, "", false);
-        testNameAndPathGetter("", "", false);
+        checkNameAndPathGetter(null, null, false);
+        checkNameAndPathGetter("", null, false);
+        checkNameAndPathGetter(null, "", false);
+        checkNameAndPathGetter("", "", false);
 
         // name and path
-        testNameAndFileGetter(TEST_PROFILE_NAME + (index++), true); // 9
-        testNameAndFileGetter(TEST_PROFILE_NAME + (index++), false); // 10
+        checkNameAndFileGetter(TEST_PROFILE_NAME + (index++), true); // 9
+        checkNameAndFileGetter(TEST_PROFILE_NAME + (index++), false); // 10
         // null name and path
-        testNameAndFileGetter(null, new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), true); // 11
-        testNameAndFileGetter(null, new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), false); // 12
-        testNameAndFileGetter("", new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), true); // 13
-        testNameAndFileGetter("", new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), false); // 14
+        checkNameAndFileGetter(null, new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), true); // 11
+        checkNameAndFileGetter(null, new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), false); // 12
+        checkNameAndFileGetter("", new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), true); // 13
+        checkNameAndFileGetter("", new File(mozDir, TEST_PROFILE_NAME + (index++) + "_FORCED_DIR"), false); // 14
         // name and null path
-        testNameAndFileGetter(TEST_PROFILE_NAME + (index++), null, false); // 16
+        checkNameAndFileGetter(TEST_PROFILE_NAME + (index++), null, false); // 16
         // null name and null path
-        testNameAndFileGetter(null, null, false);
+        checkNameAndFileGetter(null, null, false);
     }
 
     // Tests of Guest profile methods
-    private void testGuestProfile() {
+    private void checkGuestProfile() {
         mAsserter.info("Test getting a guest profile", "");
         GeckoProfile profile = GeckoProfile.createGuestProfile(getActivity());
         verifyProfile(profile, GeckoProfile.GUEST_PROFILE, getActivity().getFileStreamPath("guest"), true);

From 8bd4181821341969c607f0e55ed7fd94a55f0356 Mon Sep 17 00:00:00 2001
From: Geoff Brown 
Date: Fri, 19 Dec 2014 09:22:07 -0700
Subject: [PATCH 125/183] Bug 1105522 - Copy Robocop exception handling into
 UITest; r=jmaher

---
 mobile/android/base/tests/UITest.java | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/mobile/android/base/tests/UITest.java b/mobile/android/base/tests/UITest.java
index 14376ae760d8..925ab2ad2e32 100644
--- a/mobile/android/base/tests/UITest.java
+++ b/mobile/android/base/tests/UITest.java
@@ -88,6 +88,23 @@ abstract class UITest extends BaseRobocopTest
         super.tearDown();
     }
 
+    @Override
+    protected void runTest() throws Throwable {
+        try {
+            super.runTest();
+        } catch (Throwable t) {
+            // save screenshot -- written to /mnt/sdcard/Robotium-Screenshots
+            // as .jpg
+            mSolo.takeScreenshot("robocop-screenshot");
+            if (mAsserter != null) {
+                mAsserter.dumpLog("Exception caught during test!", t);
+                mAsserter.ok(false, "Exception caught", t.toString());
+            }
+            // re-throw to continue bail-out
+            throw t;
+        }
+    }
+
     private void initComponents() {
         mAboutHome = new AboutHomeComponent(this);
         mAppMenu = new AppMenuComponent(this);

From 47b8d3e1e9e9d3afc04a59e7fa24c2543b146324 Mon Sep 17 00:00:00 2001
From: Geoff Brown 
Date: Fri, 19 Dec 2014 09:22:07 -0700
Subject: [PATCH 126/183] Bug 1107002 - Update robocop dismissEditingMode for
 tablets; r=mcomella

---
 .../base/tests/components/ToolbarComponent.java        | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/mobile/android/base/tests/components/ToolbarComponent.java b/mobile/android/base/tests/components/ToolbarComponent.java
index 5365441d5326..984f09debcff 100644
--- a/mobile/android/base/tests/components/ToolbarComponent.java
+++ b/mobile/android/base/tests/components/ToolbarComponent.java
@@ -185,7 +185,15 @@ public class ToolbarComponent extends BaseComponent {
     public ToolbarComponent dismissEditingMode() {
         assertIsEditing();
 
-        mSolo.clickOnView(getEditCancelButton());
+        if (DeviceHelper.isTablet()) {
+            final EditText urlEditText = getUrlEditText();
+            if (urlEditText.isFocused()) {
+                mSolo.goBack();
+            }
+            mSolo.goBack();
+        } else {
+            mSolo.clickOnView(getEditCancelButton());
+        }
 
         waitForNotEditing();
 

From 3590998fe3bcc8bd0a8f95c9dab753c682fa4ff3 Mon Sep 17 00:00:00 2001
From: Michael Comella 
Date: Fri, 31 Oct 2014 17:08:30 -0700
Subject: [PATCH 127/183] Bug 1085837 - Open legacy "More" menu before
 asserting menu item is disabled; r=liuche

---
 .../tests/components/AppMenuComponent.java    | 41 +++++++++++++++++--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/mobile/android/base/tests/components/AppMenuComponent.java b/mobile/android/base/tests/components/AppMenuComponent.java
index 47a3aed5215b..a45868998c0d 100644
--- a/mobile/android/base/tests/components/AppMenuComponent.java
+++ b/mobile/android/base/tests/components/AppMenuComponent.java
@@ -123,10 +123,19 @@ public class AppMenuComponent extends BaseComponent {
                 fAssertEquals("The parent 'page' menu item is visible", View.VISIBLE, parentMenuItemView.getVisibility());
             }
         } else {
-            // Legacy devices don't have parent menu item "page", check for menu item represented by pageMenuItem.
+            // Legacy devices (Android 2.3 and earlier) don't have the parent menu, "Page", so check directly for the menu
+            // item represented by pageMenuItem.
+            //
+            // We need to make sure the appropriate menu view is constructed
+            // so open the "More" menu to additionally construct those views.
+            openLegacyMoreMenu();
+
             final View pageMenuItemView = findAppMenuItemView(pageMenuItem.getString(mSolo));
             fAssertFalse("The page menu item is not enabled", pageMenuItemView.isEnabled());
             fAssertEquals("The page menu item is visible", View.VISIBLE, pageMenuItemView.getVisibility());
+
+            // Close the "More" menu.
+            mSolo.goBack();
         }
 
         // Close the App Menu.
@@ -140,7 +149,9 @@ public class AppMenuComponent extends BaseComponent {
     /**
      * Try to find a MenuItemActionBar/MenuItemDefault with the given text set as contentDescription / text.
      *
-     * Will return null when the Android legacy menu is in use.
+     * When using legacy menus, make sure the menu has been opened to the appropriate level
+     * (i.e. base menu or "More" menu) to ensure the appropriate menu views are in memory.
+     * TODO: ^ Maybe we just need to have opened the "More" menu and the current one doesn't matter.
      *
      * This method is dependent on not having two views with equivalent contentDescription / text.
      */
@@ -229,6 +240,25 @@ public class AppMenuComponent extends BaseComponent {
         waitForMenuOpen();
     }
 
+    /**
+     * Opens the "More" options menu on legacy Android devices. Assumes the base menu
+     * (i.e. {@link #openAppMenu()}) has already been called and thus the menu is open.
+     */
+    private void openLegacyMoreMenu() {
+        fAssertTrue("The base menu is already open", isMenuOpen());
+
+        // Since there may be more views with "More" on the screen,
+        // this is not robust. However, there may not be a better way.
+        mSolo.clickOnText("^More$");
+
+        WaitHelper.waitFor("legacy \"More\" menu to open", new Condition() {
+            @Override
+            public boolean isSatisfied() {
+                return isLegacyMoreMenuOpen();
+            }
+        });
+    }
+
     private void pressOverflowMenuButton() {
         final View overflowMenuButton = getOverflowMenuButtonView();
 
@@ -247,6 +277,11 @@ public class AppMenuComponent extends BaseComponent {
         return isMenuOpen(MenuItem.NEW_TAB.getString(mSolo));
     }
 
+    private boolean isLegacyMoreMenuOpen() {
+        // Check if the first menu option is visible.
+        return mSolo.searchText(mSolo.getString(R.string.share), true);
+    }
+
     /**
      * Determines whether the app menu is open by searching for the text in menuItemTitle.
      *
@@ -255,7 +290,7 @@ public class AppMenuComponent extends BaseComponent {
      * @return true if app menu is open.
      */
     private boolean isMenuOpen(String menuItemTitle) {
-        return mSolo.searchText(menuItemTitle);
+        return mSolo.searchText(menuItemTitle, true);
     }
 
     private void waitForMenuOpen() {

From a3b10ea1489b893e7f5eb282a339bb258bfe81f1 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 00:17:21 -0800
Subject: [PATCH 128/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/5ec3ded83868
Author: Sean Lee 
Desc: Merge pull request #26869 from weilonge/seanlee/STK/master/Bug1112978

Bug 1112978 - Add mozbehavior.showOnlyOnce attribute for creating IDLE MODE TEXT notifications. r=frsela

========

https://hg.mozilla.org/integration/gaia-central/rev/eb9186a403cd
Author: Sean Lee 
Desc: Bug 1112978 - Add mozbehavior.showOnlyOnce attribute for creating IDLE MODE TEXT notifications.
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 886d361032fc..c4ebb32a8f4e 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "20dd907f42986f522233b523edd12064991a09ea", 
+    "revision": "5ec3ded83868cfc6904e0ad11714f7c3b9dc20f1", 
     "repo_path": "integration/gaia-central"
 }

From 01d8f7c3cdf1ac03160490e662bf481c36a15987 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 00:22:00 -0800
Subject: [PATCH 129/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 64bcfb4b8866..b8907569aaa5 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 02ace38d61db..ef494c3c51b8 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 2403ca196315..3f71896321f8 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index e73808620e65..fde362480852 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 02ace38d61db..ef494c3c51b8 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 5538776ba0f9..f3e85af2cf17 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 2864961c1da2..1b356ef8763d 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 31b488a8101d..9e7b329decd7 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 82395ad39781..8b3a37fac7d5 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 1c109efe4aeb..ee217d9d9c48 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index b0a7faf39a2d..63eae9191343 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From d1dc43ad38bc673425ba0548b57e074f9af7adc7 Mon Sep 17 00:00:00 2001
From: Bevis Tseng 
Date: Mon, 24 Nov 2014 18:43:54 +0800
Subject: [PATCH 130/183] Bug 873351 - Part 1: Re-write SmsService in
 JavaScript. r=echen

---
 b2g/installer/package-manifest.in             |   2 +
 dom/mobilemessage/MobileMessageManager.cpp    |   4 +-
 dom/mobilemessage/gonk/SmsService.cpp         | 159 ------------------
 dom/mobilemessage/gonk/SmsService.h           |  40 -----
 dom/mobilemessage/gonk/SmsService.js          | 154 +++++++++++++++++
 dom/mobilemessage/gonk/SmsService.manifest    |   6 +
 dom/mobilemessage/interfaces/moz.build        |   1 +
 .../interfaces/nsIGonkSmsService.idl          |  18 ++
 .../interfaces/nsISmsService.idl              |   2 +-
 dom/mobilemessage/moz.build                   |   5 +-
 dom/system/gonk/RadioInterfaceLayer.js        |   4 +-
 11 files changed, 188 insertions(+), 207 deletions(-)
 delete mode 100644 dom/mobilemessage/gonk/SmsService.cpp
 delete mode 100644 dom/mobilemessage/gonk/SmsService.h
 create mode 100644 dom/mobilemessage/gonk/SmsService.js
 create mode 100644 dom/mobilemessage/gonk/SmsService.manifest
 create mode 100644 dom/mobilemessage/interfaces/nsIGonkSmsService.idl

diff --git a/b2g/installer/package-manifest.in b/b2g/installer/package-manifest.in
index 5f62bbc9fa7c..59ace3c21438 100644
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -451,6 +451,8 @@
 @BINPATH@/components/RILContentHelper.js
 @BINPATH@/components/RILSystemMessengerHelper.js
 @BINPATH@/components/RILSystemMessengerHelper.manifest
+@BINPATH@/components/SmsService.js
+@BINPATH@/components/SmsService.manifest
 @BINPATH@/components/TelephonyAudioService.js
 @BINPATH@/components/TelephonyAudioService.manifest
 @BINPATH@/components/TelephonyService.js
diff --git a/dom/mobilemessage/MobileMessageManager.cpp b/dom/mobilemessage/MobileMessageManager.cpp
index d6bbdd8ec7ed..6b1238f4bada 100644
--- a/dom/mobilemessage/MobileMessageManager.cpp
+++ b/dom/mobilemessage/MobileMessageManager.cpp
@@ -36,7 +36,7 @@
 #include "android/SmsService.h"
 #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
 #include "nsIRilMobileMessageDatabaseService.h"
-#include "gonk/SmsService.h"
+#include "nsIGonkSmsService.h"
 #endif
 #include "nsXULAppAPI.h" // For XRE_GetProcessType()
 
@@ -711,7 +711,7 @@ NS_CreateSmsService()
 #ifdef MOZ_WIDGET_ANDROID
     smsService = new SmsService();
 #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-    smsService = new SmsService();
+    smsService = do_GetService(GONK_SMSSERVICE_CONTRACTID);
 #endif
   }
 
diff --git a/dom/mobilemessage/gonk/SmsService.cpp b/dom/mobilemessage/gonk/SmsService.cpp
deleted file mode 100644
index 36597f120444..000000000000
--- a/dom/mobilemessage/gonk/SmsService.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "SmsMessage.h"
-#include "SmsService.h"
-#include "mozilla/Preferences.h"
-#include "nsServiceManagerUtils.h"
-
-namespace {
-
-#define kPrefDefaultServiceId "dom.sms.defaultServiceId"
-
-uint32_t
-getDefaultServiceId()
-{
-  static const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
-  int32_t id = mozilla::Preferences::GetInt(kPrefDefaultServiceId, 0);
-  int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1);
-
-  if (id >= numRil || id < 0) {
-    id = 0;
-  }
-
-  return id;
-}
-
-} // Anonymous namespace
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-NS_IMPL_ISUPPORTS(SmsService,
-                  nsISmsService,
-                  nsIObserver)
-
-SmsService::SmsService()
-{
-  mRil = do_GetService("@mozilla.org/ril;1");
-  NS_WARN_IF_FALSE(mRil, "This shouldn't fail!");
-
-  // Initialize observer.
-  static const char* kObservedPrefs[] = {
-    kPrefDefaultServiceId,
-    nullptr
-  };
-  Preferences::AddStrongObservers(this, kObservedPrefs);
-  mDefaultServiceId = getDefaultServiceId();
-}
-
-/*
- * Implementation of nsIObserver.
- */
-
-NS_IMETHODIMP
-SmsService::Observe(nsISupports* aSubject,
-                    const char* aTopic,
-                    const char16_t* aData)
-{
-  if (!strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
-    nsDependentString data(aData);
-    if (data.EqualsLiteral(kPrefDefaultServiceId)) {
-      mDefaultServiceId = getDefaultServiceId();
-    }
-    return NS_OK;
-  }
-
-  MOZ_ASSERT(false, "SmsService got unexpected topic!");
-  return NS_ERROR_UNEXPECTED;
-}
-
-/*
- * Implementation of nsISmsService.
- */
-
-NS_IMETHODIMP
-SmsService::GetSmsDefaultServiceId(uint32_t* aServiceId)
-{
-  *aServiceId = mDefaultServiceId;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-SmsService::GetSegmentInfoForText(const nsAString& aText,
-                                  nsIMobileMessageCallback* aRequest)
-{
-  nsCOMPtr radioInterface;
-  if (mRil) {
-    mRil->GetRadioInterface(0, getter_AddRefs(radioInterface));
-  }
-  NS_ENSURE_TRUE(radioInterface, NS_ERROR_FAILURE);
-
-  return radioInterface->GetSegmentInfoForText(aText, aRequest);
-}
-
-NS_IMETHODIMP
-SmsService::Send(uint32_t aServiceId,
-                 const nsAString& aNumber,
-                 const nsAString& aMessage,
-                 bool aSilent,
-                 nsIMobileMessageCallback* aRequest)
-{
-  nsCOMPtr radioInterface;
-  if (mRil) {
-    mRil->GetRadioInterface(aServiceId, getter_AddRefs(radioInterface));
-  }
-  NS_ENSURE_TRUE(radioInterface, NS_ERROR_FAILURE);
-
-  return radioInterface->SendSMS(aNumber, aMessage, aSilent, aRequest);
-}
-
-NS_IMETHODIMP
-SmsService::IsSilentNumber(const nsAString& aNumber,
-                           bool*            aIsSilent)
-{
-  *aIsSilent = mSilentNumbers.Contains(aNumber);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-SmsService::AddSilentNumber(const nsAString& aNumber)
-{
-  if (mSilentNumbers.Contains(aNumber)) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  NS_ENSURE_TRUE(mSilentNumbers.AppendElement(aNumber), NS_ERROR_FAILURE);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-SmsService::RemoveSilentNumber(const nsAString& aNumber)
-{
-  if (!mSilentNumbers.Contains(aNumber)) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  NS_ENSURE_TRUE(mSilentNumbers.RemoveElement(aNumber), NS_ERROR_FAILURE);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-SmsService::GetSmscAddress(uint32_t aServiceId,
-                           nsIMobileMessageCallback *aRequest)
-{
-  nsCOMPtr radioInterface;
-  if (mRil) {
-    mRil->GetRadioInterface(aServiceId, getter_AddRefs(radioInterface));
-  }
-  NS_ENSURE_TRUE(radioInterface, NS_ERROR_FAILURE);
-
-  return radioInterface->GetSmscAddress(aRequest);
-}
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/mobilemessage/gonk/SmsService.h b/dom/mobilemessage/gonk/SmsService.h
deleted file mode 100644
index 4badee30ea47..000000000000
--- a/dom/mobilemessage/gonk/SmsService.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#ifndef mozilla_dom_mobilemessage_SmsService_h
-#define mozilla_dom_mobilemessage_SmsService_h
-
-#include "nsISmsService.h"
-#include "nsCOMPtr.h"
-#include "nsIObserver.h"
-#include "nsIRadioInterfaceLayer.h"
-#include "nsTArray.h"
-#include "nsString.h"
-#include "mozilla/Attributes.h"
-
-namespace mozilla {
-namespace dom {
-namespace mobilemessage {
-
-class SmsService MOZ_FINAL : public nsISmsService
-                           , public nsIObserver
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSISMSSERVICE
-  NS_DECL_NSIOBSERVER
-
-  SmsService();
-
-protected:
-  nsCOMPtr mRil;
-  nsTArray mSilentNumbers;
-  uint32_t mDefaultServiceId;
-};
-
-} // namespace mobilemessage
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_mobilemessage_SmsService_h
diff --git a/dom/mobilemessage/gonk/SmsService.js b/dom/mobilemessage/gonk/SmsService.js
new file mode 100644
index 000000000000..455833388333
--- /dev/null
+++ b/dom/mobilemessage/gonk/SmsService.js
@@ -0,0 +1,154 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+
+let RIL = {};
+Cu.import("resource://gre/modules/ril_consts.js", RIL);
+
+const GONK_SMSSERVICE_CONTRACTID = "@mozilla.org/sms/gonksmsservice;1";
+const GONK_SMSSERVICE_CID = Components.ID("{f9b9b5e2-73b4-11e4-83ff-a33e27428c86}");
+
+const NS_XPCOM_SHUTDOWN_OBSERVER_ID      = "xpcom-shutdown";
+const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID  = "nsPref:changed";
+
+const kPrefDefaultServiceId = "dom.sms.defaultServiceId";
+const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
+const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
+
+XPCOMUtils.defineLazyGetter(this, "gRadioInterfaces", function() {
+  let ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
+
+  let interfaces = [];
+  for (let i = 0; i < ril.numRadioInterfaces; i++) {
+    interfaces.push(ril.getRadioInterface(i));
+  }
+  return interfaces;
+});
+
+let DEBUG = RIL.DEBUG_RIL;
+function debug(s) {
+  dump("SmsService: " + s);
+}
+
+function SmsService() {
+  this._silentNumbers = [];
+  this.smsDefaultServiceId = this._getDefaultServiceId();
+
+  Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
+  Services.prefs.addObserver(kPrefDefaultServiceId, this, false);
+  Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
+}
+SmsService.prototype = {
+  classID: GONK_SMSSERVICE_CID,
+
+  classInfo: XPCOMUtils.generateCI({classID: GONK_SMSSERVICE_CID,
+                                    contractID: GONK_SMSSERVICE_CONTRACTID,
+                                    classDescription: "SmsService",
+                                    interfaces: [Ci.nsISmsService,
+                                                 Ci.nsIGonkSmsService],
+                                    flags: Ci.nsIClassInfo.SINGLETON}),
+
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsISmsService,
+                                         Ci.nsIGonkSmsService,
+                                         Ci.nsIObserver]),
+
+  _updateDebugFlag: function() {
+    try {
+      DEBUG = RIL.DEBUG_RIL ||
+              Services.prefs.getBoolPref(kPrefRilDebuggingEnabled);
+    } catch (e) {}
+  },
+
+  _getDefaultServiceId: function() {
+    let id = Services.prefs.getIntPref(kPrefDefaultServiceId);
+    let numRil = Services.prefs.getIntPref(kPrefRilNumRadioInterfaces);
+
+    if (id >= numRil || id < 0) {
+      id = 0;
+    }
+
+    return id;
+  },
+
+  /**
+   * nsISmsService interface
+   */
+  smsDefaultServiceId: 0,
+
+  getSegmentInfoForText: function(aText, aRequest) {
+    gRadioInterfaces[0].getSegmentInfoForText(aText, aRequest);
+  },
+
+  send: function(aServiceId, aNumber, aMessage, aSilent, aRequest) {
+    if (aServiceId > (gRadioInterfaces.length - 1)) {
+      throw Cr.NS_ERROR_INVALID_ARG;
+    }
+
+    gRadioInterfaces[aServiceId].sendSMS(aNumber, aMessage, aSilent, aRequest);
+  },
+
+  // An array of slient numbers.
+  _silentNumbers: null,
+  isSilentNumber: function(aNumber) {
+    return this._silentNumbers.indexOf(aNumber) >= 0;
+  },
+
+  addSilentNumber: function(aNumber) {
+    if (this.isSilentNumber(aNumber)) {
+      throw Cr.NS_ERROR_UNEXPECTED;
+    }
+
+    this._silentNumbers.push(aNumber);
+  },
+
+  removeSilentNumber: function(aNumber) {
+   let index = this._silentNumbers.indexOf(aNumber);
+   if (index < 0) {
+     throw Cr.NS_ERROR_INVALID_ARG;
+   }
+
+   this._silentNumbers.splice(index, 1);
+  },
+
+  getSmscAddress: function(aServiceId, aRequest) {
+    if (aServiceId > (gRadioInterfaces.length - 1)) {
+      throw Cr.NS_ERROR_INVALID_ARG;
+    }
+
+    gRadioInterfaces[aServiceId].getSmscAddress(aRequest);
+  },
+
+  /**
+   * TODO: nsIGonkSmsService interface
+   */
+
+  /**
+   * nsIObserver interface.
+   */
+  observe: function(aSubject, aTopic, aData) {
+    switch (aTopic) {
+      case NS_PREFBRANCH_PREFCHANGE_TOPIC_ID:
+        if (aData === kPrefRilDebuggingEnabled) {
+          this._updateDebugFlag();
+        }
+        else if (aData === kPrefDefaultServiceId) {
+          this.smsDefaultServiceId = this._getDefaultServiceId();
+        }
+        break;
+      case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
+        Services.prefs.removeObserver(kPrefRilDebuggingEnabled, this);
+        Services.prefs.removeObserver(kPrefDefaultServiceId, this);
+        Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
+        break;
+    }
+  }
+};
+
+this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SmsService]);
diff --git a/dom/mobilemessage/gonk/SmsService.manifest b/dom/mobilemessage/gonk/SmsService.manifest
new file mode 100644
index 000000000000..8d86800feb43
--- /dev/null
+++ b/dom/mobilemessage/gonk/SmsService.manifest
@@ -0,0 +1,6 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+component {f9b9b5e2-73b4-11e4-83ff-a33e27428c86} SmsService.js
+contract @mozilla.org/sms/gonksmsservice;1 {f9b9b5e2-73b4-11e4-83ff-a33e27428c86}
\ No newline at end of file
diff --git a/dom/mobilemessage/interfaces/moz.build b/dom/mobilemessage/interfaces/moz.build
index dc35b6db0357..dd7cedfd9bfc 100644
--- a/dom/mobilemessage/interfaces/moz.build
+++ b/dom/mobilemessage/interfaces/moz.build
@@ -20,6 +20,7 @@ XPIDL_SOURCES += [
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
     XPIDL_SOURCES += [
+        'nsIGonkSmsService.idl',
         'nsIRilMobileMessageDatabaseService.idl',
         'nsISmsMessenger.idl',
     ]
diff --git a/dom/mobilemessage/interfaces/nsIGonkSmsService.idl b/dom/mobilemessage/interfaces/nsIGonkSmsService.idl
new file mode 100644
index 000000000000..a3c0a53492ea
--- /dev/null
+++ b/dom/mobilemessage/interfaces/nsIGonkSmsService.idl
@@ -0,0 +1,18 @@
+/* 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 "nsISmsService.idl"
+
+%{C++
+#define GONK_SMSSERVICE_CONTRACTID \
+        "@mozilla.org/sms/gonksmsservice;1"
+%}
+
+[scriptable, uuid(63fab75e-73b4-11e4-a10d-dbfa9d05a4f4)]
+interface nsIGonkSmsService : nsISmsService
+{
+  /**
+   * TODO: define callback to receive message from the network.
+   */
+};
\ No newline at end of file
diff --git a/dom/mobilemessage/interfaces/nsISmsService.idl b/dom/mobilemessage/interfaces/nsISmsService.idl
index 27615018d581..4d33dfa5ee5d 100644
--- a/dom/mobilemessage/interfaces/nsISmsService.idl
+++ b/dom/mobilemessage/interfaces/nsISmsService.idl
@@ -12,7 +12,7 @@ interface nsIMobileMessageCallback;
 #define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1"
 %}
 
-[scriptable, builtinclass, uuid(8f86d068-698e-11e4-9470-8f75a088b84a)]
+[scriptable, uuid(31626940-73b4-11e4-8b03-1724e1d8a6a1)]
 interface nsISmsService : nsISupports
 {
   /**
diff --git a/dom/mobilemessage/moz.build b/dom/mobilemessage/moz.build
index 51e9c3e0415d..71ded4d211f8 100644
--- a/dom/mobilemessage/moz.build
+++ b/dom/mobilemessage/moz.build
@@ -34,9 +34,8 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
         'gonk/MmsService.manifest',
         'gonk/MobileMessageDatabaseService.js',
         'gonk/MobileMessageDatabaseService.manifest',
-    ]
-    UNIFIED_SOURCES += [
-        'gonk/SmsService.cpp',
+        'gonk/SmsService.js',
+        'gonk/SmsService.manifest',
     ]
 
 EXPORTS.mozilla.dom += [
diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js
index c256f8983cb7..068d188404fc 100644
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -145,8 +145,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "nsIMobileMessageService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
-                                   "@mozilla.org/sms/smsservice;1",
-                                   "nsISmsService");
+                                   "@mozilla.org/sms/gonksmsservice;1",
+                                   "nsIGonkSmsService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
                                    "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",

From 75a73fbbfdc014322695ad85b530937a9c194ede Mon Sep 17 00:00:00 2001
From: Bevis Tseng 
Date: Wed, 26 Nov 2014 20:02:54 +0800
Subject: [PATCH 131/183] Bug 873351 - Part 2: Refactor SMS Requests from
 RadioInterfaceLayer to SmsService. r=echen

---
 dom/mobilemessage/gonk/SmsSegmentHelper.jsm   | 426 +++++++++++
 dom/mobilemessage/gonk/SmsService.js          | 428 ++++++++++-
 dom/mobilemessage/moz.build                   |   1 +
 .../tests/xpcshell/test_sms_segment_helper.js | 191 +++++
 dom/mobilemessage/tests/xpcshell/xpcshell.ini |   2 +
 dom/system/gonk/RadioInterfaceLayer.js        | 702 ------------------
 dom/system/gonk/nsIRadioInterfaceLayer.idl    |  15 +-
 dom/system/gonk/tests/header_helpers.js       |  17 +-
 dom/system/gonk/tests/test_ril_worker_sms.js  |  16 +-
 .../tests/test_ril_worker_sms_segment_info.js | 200 +----
 10 files changed, 1073 insertions(+), 925 deletions(-)
 create mode 100644 dom/mobilemessage/gonk/SmsSegmentHelper.jsm
 create mode 100644 dom/mobilemessage/tests/xpcshell/test_sms_segment_helper.js

diff --git a/dom/mobilemessage/gonk/SmsSegmentHelper.jsm b/dom/mobilemessage/gonk/SmsSegmentHelper.jsm
new file mode 100644
index 000000000000..ba5e0a4fd10a
--- /dev/null
+++ b/dom/mobilemessage/gonk/SmsSegmentHelper.jsm
@@ -0,0 +1,426 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+let RIL = {};
+Cu.import("resource://gre/modules/ril_consts.js", RIL);
+
+/**
+ * SmsSegmentHelper
+ */
+this.SmsSegmentHelper = {
+  /**
+   * Get valid SMS concatenation reference number.
+   */
+  _segmentRef: 0,
+  get nextSegmentRef() {
+    let ref = this._segmentRef++;
+
+    this._segmentRef %= (this.segmentRef16Bit ? 65535 : 255);
+
+    // 0 is not a valid SMS concatenation reference number.
+    return ref + 1;
+  },
+
+  /**
+   * Calculate encoded length using specified locking/single shift table
+   *
+   * @param aMessage
+   *        message string to be encoded.
+   * @param aLangTable
+   *        locking shift table string.
+   * @param aLangShiftTable
+   *        single shift table string.
+   * @param aStrict7BitEncoding [Optional]
+   *        Enable Latin characters replacement with corresponding
+   *        ones in GSM SMS 7-bit default alphabet.
+   *
+   * @return encoded length in septets.
+   *
+   * @note The algorithm used in this function must match exactly with
+   *       GsmPDUHelper#writeStringAsSeptets.
+   */
+  countGsm7BitSeptets: function(aMessage, aLangTable, aLangShiftTable, aStrict7BitEncoding) {
+    let length = 0;
+    for (let msgIndex = 0; msgIndex < aMessage.length; msgIndex++) {
+      let c = aMessage.charAt(msgIndex);
+      if (aStrict7BitEncoding) {
+        c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c;
+      }
+
+      let septet = aLangTable.indexOf(c);
+
+      // According to 3GPP TS 23.038, section 6.1.1 General notes, "The
+      // characters marked '1)' are not used but are displayed as a space."
+      if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
+        continue;
+      }
+
+      if (septet >= 0) {
+        length++;
+        continue;
+      }
+
+      septet = aLangShiftTable.indexOf(c);
+      if (septet < 0) {
+        if (!aStrict7BitEncoding) {
+          return -1;
+        }
+
+        // Bug 816082, when aStrict7BitEncoding is enabled, we should replace
+        // characters that can't be encoded with GSM 7-Bit alphabets with '*'.
+        c = "*";
+        if (aLangTable.indexOf(c) >= 0) {
+          length++;
+        } else if (aLangShiftTable.indexOf(c) >= 0) {
+          length += 2;
+        } else {
+          // We can't even encode a '*' character with current configuration.
+          return -1;
+        }
+
+        continue;
+      }
+
+      // According to 3GPP TS 23.038 B.2, "This code represents a control
+      // character and therefore must not be used for language specific
+      // characters."
+      if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
+        continue;
+      }
+
+      // The character is not found in locking shfit table, but could be
+      // encoded as  with single shift table. Note that it's
+      // still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE,
+      // but we can display it as a space in this case as said in previous
+      // comment.
+      length += 2;
+    }
+
+    return length;
+  },
+
+  /**
+   * Calculate user data length of specified message string encoded in GSM 7Bit
+   * alphabets.
+   *
+   * @param aMessage
+   *        a message string to be encoded.
+   * @param aStrict7BitEncoding [Optional]
+   *        Enable Latin characters replacement with corresponding
+   *        ones in GSM SMS 7-bit default alphabet.
+   *
+   * @return null or an options object with attributes `dcs`,
+   *         `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`,
+   *         `langShiftIndex`, `segmentMaxSeq` set.
+   *
+   * @see #calculateUserDataLength().
+   *
+   * |enabledGsmTableTuples|:
+   *   List of tuples of national language identifier pairs.
+   *   TODO: Support static/runtime settings, see bug 733331.
+   * |segmentRef16Bit|:
+   *   Use 16-bit reference number for concatenated outgoint messages.
+   *   TODO: Support static/runtime settings, see bug 733331.
+   */
+  enabledGsmTableTuples: [
+    [RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT],
+  ],
+  segmentRef16Bit: false,
+  calculateUserDataLength7Bit: function(aMessage, aStrict7BitEncoding) {
+    let options = null;
+    let minUserDataSeptets = Number.MAX_VALUE;
+    for (let i = 0; i < this.enabledGsmTableTuples.length; i++) {
+      let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i];
+
+      const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
+      const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
+
+      let bodySeptets = this.countGsm7BitSeptets(aMessage,
+                                                  langTable,
+                                                  langShiftTable,
+                                                  aStrict7BitEncoding);
+      if (bodySeptets < 0) {
+        continue;
+      }
+
+      let headerLen = 0;
+      if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) {
+        headerLen += 3; // IEI + len + langIndex
+      }
+      if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) {
+        headerLen += 3; // IEI + len + langShiftIndex
+      }
+
+      // Calculate full user data length, note the extra byte is for header len
+      let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7);
+      let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT;
+      if ((bodySeptets + headerSeptets) > segmentSeptets) {
+        headerLen += this.segmentRef16Bit ? 6 : 5;
+        headerSeptets = Math.ceil((headerLen + 1) * 8 / 7);
+        segmentSeptets -= headerSeptets;
+      }
+
+      let segments = Math.ceil(bodySeptets / segmentSeptets);
+      let userDataSeptets = bodySeptets + headerSeptets * segments;
+      if (userDataSeptets >= minUserDataSeptets) {
+        continue;
+      }
+
+      minUserDataSeptets = userDataSeptets;
+
+      options = {
+        dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET,
+        encodedFullBodyLength: bodySeptets,
+        userDataHeaderLength: headerLen,
+        langIndex: langIndex,
+        langShiftIndex: langShiftIndex,
+        segmentMaxSeq: segments,
+        segmentChars: segmentSeptets,
+      };
+    }
+
+    return options;
+  },
+
+  /**
+   * Calculate user data length of specified message string encoded in UCS2.
+   *
+   * @param aMessage
+   *        a message string to be encoded.
+   *
+   * @return an options object with attributes `dcs`, `userDataHeaderLength`,
+   *         `encodedFullBodyLength`, `segmentMaxSeq` set.
+   *
+   * @see #calculateUserDataLength().
+   */
+  calculateUserDataLengthUCS2: function(aMessage) {
+    let bodyChars = aMessage.length;
+    let headerLen = 0;
+    let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2);
+    let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2;
+    if ((bodyChars + headerChars) > segmentChars) {
+      headerLen += this.segmentRef16Bit ? 6 : 5;
+      headerChars = Math.ceil((headerLen + 1) / 2);
+      segmentChars -= headerChars;
+    }
+
+    let segments = Math.ceil(bodyChars / segmentChars);
+
+    return {
+      dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET,
+      encodedFullBodyLength: bodyChars * 2,
+      userDataHeaderLength: headerLen,
+      segmentMaxSeq: segments,
+      segmentChars: segmentChars,
+    };
+  },
+
+  /**
+   * Calculate user data length and its encoding.
+   *
+   * @param aMessage
+   *        a message string to be encoded.
+   * @param aStrict7BitEncoding [Optional]
+   *        Enable Latin characters replacement with corresponding
+   *        ones in GSM SMS 7-bit default alphabet.
+   *
+   * @return an options object with some or all of following attributes set:
+   *
+   * @param dcs
+   *        Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET
+   *        constants.
+   * @param userDataHeaderLength
+   *        Length of embedded user data header, in bytes. The whole header
+   *        size will be userDataHeaderLength + 1; 0 for no header.
+   * @param encodedFullBodyLength
+   *        Length of the message body when encoded with the given DCS. For
+   *        UCS2, in bytes; for 7-bit, in septets.
+   * @param langIndex
+   *        Table index used for normal 7-bit encoded character lookup.
+   * @param langShiftIndex
+   *        Table index used for escaped 7-bit encoded character lookup.
+   * @param segmentMaxSeq
+   *        Max sequence number of a multi-part messages, or 1 for single one.
+   *        This number might not be accurate for a multi-part message until
+   *        it's processed by #fragmentText() again.
+   */
+  calculateUserDataLength: function(aMessage, aStrict7BitEncoding) {
+    let options = this.calculateUserDataLength7Bit(aMessage, aStrict7BitEncoding);
+    if (!options) {
+      options = this.calculateUserDataLengthUCS2(aMessage);
+    }
+
+    return options;
+  },
+
+  /**
+   * Fragment GSM 7-Bit encodable string for transmission.
+   *
+   * @param aText
+   *        text string to be fragmented.
+   * @param aLangTable
+   *        locking shift table string.
+   * @param aLangShiftTable
+   *        single shift table string.
+   * @param aSegmentSeptets
+   *        Number of available spetets per segment.
+   * @param aStrict7BitEncoding [Optional]
+   *        Enable Latin characters replacement with corresponding
+   *        ones in GSM SMS 7-bit default alphabet.
+   *
+   * @return an array of objects. See #fragmentText() for detailed definition.
+   */
+  fragmentText7Bit: function(aText, aLangTable, aLangShiftTable, aSegmentSeptets, aStrict7BitEncoding) {
+    let ret = [];
+    let body = "", len = 0;
+    // If the message is empty, we only push the empty message to ret.
+    if (aText.length === 0) {
+      ret.push({
+        body: aText,
+        encodedBodyLength: aText.length,
+      });
+      return ret;
+    }
+
+    for (let i = 0, inc = 0; i < aText.length; i++) {
+      let c = aText.charAt(i);
+      if (aStrict7BitEncoding) {
+        c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c;
+      }
+
+      let septet = aLangTable.indexOf(c);
+      if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
+        continue;
+      }
+
+      if (septet >= 0) {
+        inc = 1;
+      } else {
+        septet = aLangShiftTable.indexOf(c);
+        if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
+          continue;
+        }
+
+        inc = 2;
+        if (septet < 0) {
+          if (!aStrict7BitEncoding) {
+            throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!");
+          }
+
+          // Bug 816082, when aStrict7BitEncoding is enabled, we should replace
+          // characters that can't be encoded with GSM 7-Bit alphabets with '*'.
+          c = "*";
+          if (aLangTable.indexOf(c) >= 0) {
+            inc = 1;
+          }
+        }
+      }
+
+      if ((len + inc) > aSegmentSeptets) {
+        ret.push({
+          body: body,
+          encodedBodyLength: len,
+        });
+        body = c;
+        len = inc;
+      } else {
+        body += c;
+        len += inc;
+      }
+    }
+
+    if (len) {
+      ret.push({
+        body: body,
+        encodedBodyLength: len,
+      });
+    }
+
+    return ret;
+  },
+
+  /**
+   * Fragment UCS2 encodable string for transmission.
+   *
+   * @param aText
+   *        text string to be fragmented.
+   * @param aSegmentChars
+   *        Number of available characters per segment.
+   *
+   * @return an array of objects. See #fragmentText() for detailed definition.
+   */
+  fragmentTextUCS2: function(aText, aSegmentChars) {
+    let ret = [];
+    // If the message is empty, we only push the empty message to ret.
+    if (aText.length === 0) {
+      ret.push({
+        body: aText,
+        encodedBodyLength: aText.length,
+      });
+      return ret;
+    }
+
+    for (let offset = 0; offset < aText.length; offset += aSegmentChars) {
+      let str = aText.substr(offset, aSegmentChars);
+      ret.push({
+        body: str,
+        encodedBodyLength: str.length * 2,
+      });
+    }
+
+    return ret;
+  },
+
+  /**
+   * Fragment string for transmission.
+   *
+   * Fragment input text string into an array of objects that contains
+   * attributes `body`, substring for this segment, `encodedBodyLength`,
+   * length of the encoded segment body in septets.
+   *
+   * @param aText
+   *        Text string to be fragmented.
+   * @param aOptions [Optional]
+   *        Optional pre-calculated option object. The output array will be
+   *        stored at aOptions.segments if there are multiple segments.
+   * @param aStrict7BitEncoding [Optional]
+   *        Enable Latin characters replacement with corresponding
+   *        ones in GSM SMS 7-bit default alphabet.
+   *
+   * @return Populated options object.
+   */
+  fragmentText: function(aText, aOptions, aStrict7BitEncoding) {
+    if (!aOptions) {
+      aOptions = this.calculateUserDataLength(aText, aStrict7BitEncoding);
+    }
+
+    if (aOptions.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
+      const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[aOptions.langIndex];
+      const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[aOptions.langShiftIndex];
+      aOptions.segments = this.fragmentText7Bit(aText,
+                                                langTable, langShiftTable,
+                                                aOptions.segmentChars,
+                                                aStrict7BitEncoding);
+    } else {
+      aOptions.segments = this.fragmentTextUCS2(aText,
+                                                aOptions.segmentChars);
+    }
+
+    // Re-sync aOptions.segmentMaxSeq with actual length of returning array.
+    aOptions.segmentMaxSeq = aOptions.segments.length;
+
+    if (aOptions.segmentMaxSeq > 1) {
+      aOptions.segmentRef16Bit = this.segmentRef16Bit;
+      aOptions.segmentRef = this.nextSegmentRef;
+    }
+
+    return aOptions;
+  }
+};
+
+this.EXPORTED_SYMBOLS = [ 'SmsSegmentHelper' ];
\ No newline at end of file
diff --git a/dom/mobilemessage/gonk/SmsService.js b/dom/mobilemessage/gonk/SmsService.js
index 455833388333..8adf1b0df5a8 100644
--- a/dom/mobilemessage/gonk/SmsService.js
+++ b/dom/mobilemessage/gonk/SmsService.js
@@ -22,6 +22,19 @@ const kPrefDefaultServiceId = "dom.sms.defaultServiceId";
 const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
 const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
 
+const kSmsReceivedObserverTopic          = "sms-received";
+const kSilentSmsReceivedObserverTopic    = "silent-sms-received";
+const kSmsSendingObserverTopic           = "sms-sending";
+const kSmsSentObserverTopic              = "sms-sent";
+const kSmsFailedObserverTopic            = "sms-failed";
+const kSmsDeliverySuccessObserverTopic   = "sms-delivery-success";
+const kSmsDeliveryErrorObserverTopic     = "sms-delivery-error";
+
+const DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED = "received";
+const DOM_MOBILE_MESSAGE_DELIVERY_SENDING  = "sending";
+const DOM_MOBILE_MESSAGE_DELIVERY_SENT     = "sent";
+const DOM_MOBILE_MESSAGE_DELIVERY_ERROR    = "error";
+
 XPCOMUtils.defineLazyGetter(this, "gRadioInterfaces", function() {
   let ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
 
@@ -32,6 +45,34 @@ XPCOMUtils.defineLazyGetter(this, "gRadioInterfaces", function() {
   return interfaces;
 });
 
+XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
+  let ns = {};
+  Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
+  return ns.SmsSegmentHelper;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function() {
+  let ns = {};
+  Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns);
+  return ns.PhoneNumberUtils;
+});
+
+XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
+                                   "@mozilla.org/mobileconnection/mobileconnectionservice;1",
+                                   "nsIMobileConnectionService");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
+                                   "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
+                                   "nsIRilMobileMessageDatabaseService");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
+                                   "@mozilla.org/mobilemessage/mobilemessageservice;1",
+                                   "nsIMobileMessageService");
+
+XPCOMUtils.defineLazyServiceGetter(this, "gSmsMessenger",
+                                   "@mozilla.org/ril/system-messenger-helper;1",
+                                   "nsISmsMessenger");
+
 let DEBUG = RIL.DEBUG_RIL;
 function debug(s) {
   dump("SmsService: " + s);
@@ -77,13 +118,279 @@ SmsService.prototype = {
     return id;
   },
 
+  _getPhoneNumber: function(aServiceId) {
+    let number;
+    // Get the proper IccInfo based on the current card type.
+    try {
+      let iccInfo = null;
+      let baseIccInfo = gRadioInterfaces[aServiceId].rilContext.iccInfo;
+      if (baseIccInfo.iccType === 'ruim' || baseIccInfo.iccType === 'csim') {
+        iccInfo = baseIccInfo.QueryInterface(Ci.nsICdmaIccInfo);
+        number = iccInfo.mdn;
+      } else {
+        iccInfo = baseIccInfo.QueryInterface(Ci.nsIGsmIccInfo);
+        number = iccInfo.msisdn;
+      }
+    } catch (e) {
+      if (DEBUG) {
+       debug("Exception - QueryInterface failed on iccinfo for GSM/CDMA info");
+      }
+      return null;
+    }
+
+    return number;
+  },
+
+  _getIccId: function(aServiceId) {
+    let iccInfo = gRadioInterfaces[aServiceId].rilContext.iccInfo;
+
+    if (!iccInfo) {
+      return null;
+    }
+
+    return iccInfo.iccid;
+  },
+
+  _convertSmsMessageClass: function(aMessageClass) {
+    let index = RIL.GECKO_SMS_MESSAGE_CLASSES.indexOf(aMessageClass);
+
+    if (index < 0) {
+      throw new Error("Invalid MessageClass: " + aMessageClass);
+    }
+
+    return index;
+  },
+
+  _convertSmsDelivery: function(aDelivery) {
+    let index = [DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED,
+                 DOM_MOBILE_MESSAGE_DELIVERY_SENDING,
+                 DOM_MOBILE_MESSAGE_DELIVERY_SENT,
+                 DOM_MOBILE_MESSAGE_DELIVERY_ERROR].indexOf(aDelivery);
+
+    if (index < 0) {
+      throw new Error("Invalid Delivery: " + aDelivery);
+    }
+
+    return index;
+  },
+
+  _convertSmsDeliveryStatus: function(aDeliveryStatus) {
+    let index = [RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE,
+                 RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
+                 RIL.GECKO_SMS_DELIVERY_STATUS_PENDING,
+                 RIL.GECKO_SMS_DELIVERY_STATUS_ERROR].indexOf(aDeliveryStatus);
+
+    if (index < 0) {
+      throw new Error("Invalid DeliveryStatus: " + aDeliveryStatus);
+    }
+
+    return index;
+  },
+
+  _sendToTheAir: function(aServiceId, aDomMessage, aSilent, aOptions, aRequest) {
+    // Keep current SMS message info for sent/delivered notifications
+    let sentMessage = aDomMessage;
+    let requestStatusReport = aOptions.requestStatusReport;
+
+    gRadioInterfaces[aServiceId].sendWorkerMessage("sendSMS",
+                                                   aOptions,
+                                                   (aResponse) => {
+      // Failed to send SMS out.
+      if (aResponse.errorMsg) {
+        let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR;
+        switch (aResponse.errorMsg) {
+          case RIL.ERROR_RADIO_NOT_AVAILABLE:
+            error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR;
+            break;
+          case RIL.ERROR_FDN_CHECK_FAILURE:
+            error = Ci.nsIMobileMessageCallback.FDN_CHECK_ERROR;
+            break;
+        }
+
+        if (aSilent) {
+          // There is no way to modify nsIDOMMozSmsMessage attributes as they
+          // are read only so we just create a new sms instance to send along
+          // with the notification.
+          aRequest.notifySendMessageFailed(
+            error,
+            gMobileMessageService.createSmsMessage(sentMessage.id,
+                                                   sentMessage.threadId,
+                                                   sentMessage.iccId,
+                                                   DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
+                                                   RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
+                                                   sentMessage.sender,
+                                                   sentMessage.receiver,
+                                                   sentMessage.body,
+                                                   sentMessage.messageClass,
+                                                   sentMessage.timestamp,
+                                                   0,
+                                                   0,
+                                                   sentMessage.read));
+          return false;
+        }
+
+        gMobileMessageDatabaseService
+          .setMessageDeliveryByMessageId(aDomMessage.id,
+                                         null,
+                                         DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
+                                         RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
+                                         null,
+                                         (aRv, aDomMessage) => {
+          // TODO bug 832140 handle !Components.isSuccessCode(aRv)
+          aRequest.notifySendMessageFailed(error, aDomMessage);
+          Services.obs.notifyObservers(aDomMessage, kSmsFailedObserverTopic, null);
+        });
+        return false;
+      } // End of send failure.
+
+      // Message was sent to SMSC.
+      if (!aResponse.deliveryStatus) {
+        if (aSilent) {
+          // There is no way to modify nsIDOMMozSmsMessage attributes as they
+          // are read only so we just create a new sms instance to send along
+          // with the notification.
+          aRequest.notifyMessageSent(
+            gMobileMessageService.createSmsMessage(sentMessage.id,
+                                                   sentMessage.threadId,
+                                                   sentMessage.iccId,
+                                                   DOM_MOBILE_MESSAGE_DELIVERY_SENT,
+                                                   sentMessage.deliveryStatus,
+                                                   sentMessage.sender,
+                                                   sentMessage.receiver,
+                                                   sentMessage.body,
+                                                   sentMessage.messageClass,
+                                                   sentMessage.timestamp,
+                                                   Date.now(),
+                                                   0,
+                                                   sentMessage.read));
+          // We don't wait for SMS-STATUS-REPORT for silent one.
+          return false;
+        }
+
+        gMobileMessageDatabaseService
+          .setMessageDeliveryByMessageId(sentMessage.id,
+                                         null,
+                                         DOM_MOBILE_MESSAGE_DELIVERY_SENT,
+                                         sentMessage.deliveryStatus,
+                                         null,
+                                         (aRv, aDomMessage) => {
+          // TODO bug 832140 handle !Components.isSuccessCode(aRv)
+
+          if (requestStatusReport) {
+            // Update the sentMessage and wait for the status report.
+            sentMessage = aDomMessage;
+          }
+
+          this._broadcastSmsSystemMessage(
+            Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT, aDomMessage);
+          aRequest.notifyMessageSent(aDomMessage);
+          Services.obs.notifyObservers(aDomMessage, kSmsSentObserverTopic, null);
+        });
+
+        // Keep this callback if we have status report waiting.
+        return requestStatusReport;
+      } // End of Message Sent to SMSC.
+
+      // Got valid deliveryStatus for the delivery to the remote party when
+      // the status report is requested.
+      gMobileMessageDatabaseService
+        .setMessageDeliveryByMessageId(sentMessage.id,
+                                       null,
+                                       sentMessage.delivery,
+                                       aResponse.deliveryStatus,
+                                       null,
+                                       (aRv, aDomMessage) => {
+        // TODO bug 832140 handle !Components.isSuccessCode(aRv)
+
+        let topic = (aResponse.deliveryStatus ==
+                     RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
+                    ? kSmsDeliverySuccessObserverTopic
+                    : kSmsDeliveryErrorObserverTopic;
+
+        // Broadcasting a "sms-delivery-success" system message to open apps.
+        if (topic == kSmsDeliverySuccessObserverTopic) {
+          this._broadcastSmsSystemMessage(
+            Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_SUCCESS, aDomMessage);
+        }
+
+        // Notifying observers the delivery status is updated.
+        Services.obs.notifyObservers(aDomMessage, topic, null);
+      });
+
+      // Send transaction has ended completely.
+      return false;
+    });
+  },
+
+  /**
+   * A helper to broadcast the system message to launch registered apps
+   * like Costcontrol, Notification and Message app... etc.
+   *
+   * @param aNotificationType
+   *        Ci.nsISmsMessenger.NOTIFICATION_TYPE_*.
+   * @param aDomMessage
+   *        The nsIDOMMozSmsMessage object.
+   */
+  _broadcastSmsSystemMessage: function(aNotificationType, aDomMessage) {
+    if (DEBUG) debug("Broadcasting the SMS system message: " + aNotificationType);
+
+    // Sadly we cannot directly broadcast the aDomMessage object
+    // because the system message mechamism will rewrap the object
+    // based on the content window, which needs to know the properties.
+    try {
+      gSmsMessenger.notifySms(aNotificationType,
+                              aDomMessage.id,
+                              aDomMessage.threadId,
+                              aDomMessage.iccId,
+                              this._convertSmsDelivery(
+                                aDomMessage.delivery),
+                              this._convertSmsDeliveryStatus(
+                                aDomMessage.deliveryStatus),
+                              aDomMessage.sender,
+                              aDomMessage.receiver,
+                              aDomMessage.body,
+                              this._convertSmsMessageClass(
+                                aDomMessage.messageClass),
+                              aDomMessage.timestamp,
+                              aDomMessage.sentTimestamp,
+                              aDomMessage.deliveryTimestamp,
+                              aDomMessage.read);
+    } catch (e) {
+      if (DEBUG) {
+        debug("Failed to _broadcastSmsSystemMessage: " + e);
+      }
+    }
+  },
+
   /**
    * nsISmsService interface
    */
   smsDefaultServiceId: 0,
 
   getSegmentInfoForText: function(aText, aRequest) {
-    gRadioInterfaces[0].getSegmentInfoForText(aText, aRequest);
+    let strict7BitEncoding;
+    try {
+      strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding");
+    } catch (e) {
+      strict7BitEncoding = false;
+    }
+
+    let options = gSmsSegmentHelper.fragmentText(aText, null, strict7BitEncoding);
+    let charsInLastSegment;
+    if (options.segmentMaxSeq) {
+      let lastSegment = options.segments[options.segmentMaxSeq - 1];
+      charsInLastSegment = lastSegment.encodedBodyLength;
+      if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) {
+        // In UCS2 encoding, encodedBodyLength is in octets.
+        charsInLastSegment /= 2;
+      }
+    } else {
+      charsInLastSegment = 0;
+    }
+
+    aRequest.notifySegmentInfoForTextGot(options.segmentMaxSeq,
+                                         options.segmentChars,
+                                         options.segmentChars - charsInLastSegment);
   },
 
   send: function(aServiceId, aNumber, aMessage, aSilent, aRequest) {
@@ -91,7 +398,113 @@ SmsService.prototype = {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
-    gRadioInterfaces[aServiceId].sendSMS(aNumber, aMessage, aSilent, aRequest);
+    let strict7BitEncoding;
+    try {
+      strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding");
+    } catch (e) {
+      strict7BitEncoding = false;
+    }
+
+    let options = gSmsSegmentHelper.fragmentText(aMessage, null, strict7BitEncoding);
+    options.number = gPhoneNumberUtils.normalize(aNumber);
+    let requestStatusReport;
+    try {
+      requestStatusReport =
+        Services.prefs.getBoolPref("dom.sms.requestStatusReport");
+    } catch (e) {
+      requestStatusReport = true;
+    }
+    options.requestStatusReport = requestStatusReport && !aSilent;
+
+    let sendingMessage = {
+      type: "sms",
+      sender: this._getPhoneNumber(aServiceId),
+      receiver: aNumber,
+      body: aMessage,
+      deliveryStatusRequested: options.requestStatusReport,
+      timestamp: Date.now(),
+      iccId: this._getIccId(aServiceId)
+    };
+
+    let saveSendingMessageCallback = (aRv, aSendingMessage) => {
+      if (!Components.isSuccessCode(aRv)) {
+        if (DEBUG) debug("Error! Fail to save sending message! aRv = " + aRv);
+        aRequest.notifySendMessageFailed(
+          gMobileMessageDatabaseService.translateCrErrorToMessageCallbackError(aRv),
+          aSendingMessage);
+        Services.obs.notifyObservers(aSendingMessage, kSmsFailedObserverTopic, null);
+        return;
+      }
+
+      if (!aSilent) {
+        Services.obs.notifyObservers(aSendingMessage, kSmsSendingObserverTopic, null);
+      }
+
+      let connection =
+        gMobileConnectionService.getItemByServiceId(aServiceId);
+      // If the radio is disabled or the SIM card is not ready, just directly
+      // return with the corresponding error code.
+      let errorCode;
+      let radioState = connection && connection.radioState;
+      if (!gPhoneNumberUtils.isPlainPhoneNumber(options.number)) {
+        if (DEBUG) debug("Error! Address is invalid when sending SMS: " + options.number);
+        errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR;
+      } else if (radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_UNKNOWN ||
+                 radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED) {
+        if (DEBUG) debug("Error! Radio is disabled when sending SMS.");
+        errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
+      } else if (gRadioInterfaces[aServiceId].rilContext.cardState !=
+                 Ci.nsIIccProvider.CARD_STATE_READY) {
+        if (DEBUG) debug("Error! SIM card is not ready when sending SMS.");
+        errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR;
+      }
+      if (errorCode) {
+        if (aSilent) {
+          aRequest.notifySendMessageFailed(errorCode, aSendingMessage);
+          return;
+        }
+
+        gMobileMessageDatabaseService
+          .setMessageDeliveryByMessageId(aSendingMessage.id,
+                                         null,
+                                         DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
+                                         RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
+                                         null,
+                                         (aRv, aDomMessage) => {
+          // TODO bug 832140 handle !Components.isSuccessCode(aRv)
+          aRequest.notifySendMessageFailed(errorCode, aDomMessage);
+          Services.obs.notifyObservers(aDomMessage, kSmsFailedObserverTopic, null);
+        });
+        return;
+      }
+
+      this._sendToTheAir(aServiceId, aSendingMessage, aSilent, options, aRequest);
+    }; // End of |saveSendingMessageCallback|.
+
+    // Don't save message into DB for silent SMS.
+    if (aSilent) {
+      let delivery = DOM_MOBILE_MESSAGE_DELIVERY_SENDING;
+      let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING;
+      let domMessage =
+        gMobileMessageService.createSmsMessage(-1, // id
+                                               0,  // threadId
+                                               sendingMessage.iccId,
+                                               delivery,
+                                               deliveryStatus,
+                                               sendingMessage.sender,
+                                               sendingMessage.receiver,
+                                               sendingMessage.body,
+                                               "normal", // message class
+                                               sendingMessage.timestamp,
+                                               0,
+                                               0,
+                                               false);
+      saveSendingMessageCallback(Cr.NS_OK, domMessage);
+      return;
+    }
+
+    gMobileMessageDatabaseService.saveSendingMessage(
+      sendingMessage, saveSendingMessageCallback);
   },
 
   // An array of slient numbers.
@@ -122,7 +535,16 @@ SmsService.prototype = {
       throw Cr.NS_ERROR_INVALID_ARG;
     }
 
-    gRadioInterfaces[aServiceId].getSmscAddress(aRequest);
+    gRadioInterfaces[aServiceId].sendWorkerMessage("getSmscAddress",
+                                                   null,
+                                                   (aResponse) => {
+      if (!aResponse.errorMsg) {
+        aRequest.notifyGetSmscAddress(aResponse.smscAddress);
+      } else {
+        aRequest.notifyGetSmscAddressFailed(
+          Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR);
+      }
+    });
   },
 
   /**
diff --git a/dom/mobilemessage/moz.build b/dom/mobilemessage/moz.build
index 71ded4d211f8..7e73a8239fa7 100644
--- a/dom/mobilemessage/moz.build
+++ b/dom/mobilemessage/moz.build
@@ -26,6 +26,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
         'gonk/mms_consts.js',
         'gonk/MmsPduHelper.jsm',
         'gonk/MobileMessageDB.jsm',
+        'gonk/SmsSegmentHelper.jsm',
         'gonk/wap_consts.js',
         'gonk/WspPduHelper.jsm',
     ]
diff --git a/dom/mobilemessage/tests/xpcshell/test_sms_segment_helper.js b/dom/mobilemessage/tests/xpcshell/test_sms_segment_helper.js
new file mode 100644
index 000000000000..6b710a819061
--- /dev/null
+++ b/dom/mobilemessage/tests/xpcshell/test_sms_segment_helper.js
@@ -0,0 +1,191 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
+  let ns = {};
+  Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
+  return ns.SmsSegmentHelper;
+});
+
+const ESCAPE = "\uffff";
+const RESCTL = "\ufffe";
+const SP = " ";
+
+function run_test() {
+  run_next_test();
+}
+
+/**
+ * Verify SmsSegmentHelper#calculateUserDataLength handles national language
+ * selection correctly.
+ */
+add_test(function test_SmsSegmentHelper_calculateUserDataLength() {
+  function test_calc(str, expected, enabledGsmTableTuples, strict7BitEncoding) {
+    gSmsSegmentHelper.enabledGsmTableTuples = enabledGsmTableTuples;
+    let options = gSmsSegmentHelper.calculateUserDataLength(str, strict7BitEncoding);
+
+    do_check_eq(expected[0], options.dcs);
+    do_check_eq(expected[1], options.encodedFullBodyLength);
+    do_check_eq(expected[2], options.userDataHeaderLength);
+    do_check_eq(expected[3], options.langIndex);
+    do_check_eq(expected[4], options.langShiftIndex);
+  }
+
+  // Test UCS fallback
+  // - No any default enabled nl tables
+  test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], []);
+  // - Character not defined in enabled nl tables
+  test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], [[2, 2]]);
+
+  // With GSM default nl tables
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
+  // - SP is defined in both locking/single shift tables, should be directly
+  //   encoded.
+  test_calc(SP, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
+  // - '^' is only defined in single shift table, should be encoded as
+  //   ^.
+  test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[0, 0]]);
+
+  // Test userDataHeaderLength calculation
+  // - Header contains both IEIs
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 6, 1, 1], [[1, 1]]);
+  // - Header contains only locking shift table IEI
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0]]);
+  // - Header contains only single shift table IEI
+  test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 3, 0, 1], [[0, 1]]);
+
+  // Test minimum cost nl tables selection
+  // - 'A' is defined in locking shift table
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 0]]);
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 0], [1, 0]]);
+  // - 'A' is defined in single shift table
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 0], [2, 4]]);
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 4], [2, 0]]);
+  // - 'A' is defined in locking shift table of one tuple and in single shift
+  //   table of another.
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 4]]);
+  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 4], [1, 0]]);
+
+  // Test Bug 733981
+  // - Case 1, headerLen is in octets, not septets. "\\" is defined in default
+  //   single shift table and Portuguese locking shift table. The original code
+  //   will add headerLen 7(octets), which should be 8(septets), to calculated
+  //   cost and gets 14, which should be 15 in total for the first run. As for
+  //   the second run, it will be undoubtedly 14 in total. With correct fix,
+  //   the best choice should be the second one.
+  test_calc("\\\\\\\\\\\\\\",
+            [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 14, 0, 0, 0], [[3, 1], [0, 0]]);
+  // - Case 2, possible early return non-best choice. The original code will
+  //   get total cost 6 in the first run and returns immediately. With correct
+  //   fix, the best choice should be the second one.
+  test_calc(ESCAPE + ESCAPE + ESCAPE + ESCAPE + ESCAPE + "\\",
+            [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[3, 0], [0, 0]]);
+
+  // Test Bug 790192: support strict GSM SMS 7-Bit encoding
+  let str = "", gsmLen = 0, udhl = 0;
+  for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
+    str += c;
+    if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
+      gsmLen += 1;
+    } else {
+      gsmLen += 2;
+    }
+  }
+  if (str.length > PDU_MAX_USER_DATA_UCS2) {
+    udhl = 5;
+  }
+  test_calc(str, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, gsmLen, 0, 0, 0], [[0, 0]], true);
+  test_calc(str, [PDU_DCS_MSG_CODING_16BITS_ALPHABET, str.length * 2, udhl], [[0, 0]]);
+
+  run_next_test();
+});
+
+function generateStringOfLength(str, length) {
+  while (str.length < length) {
+    if (str.length < (length / 2)) {
+      str = str + str;
+    } else {
+      str = str + str.substr(0, length - str.length);
+    }
+  }
+
+  return str;
+}
+
+/**
+ * Verify SmsSegmentHelper#calculateUserDataLength7Bit multipart handling.
+ */
+add_test(function test_SmsSegmentHelper_calculateUserDataLength7Bit_multipart() {
+  function test_calc(str, expected) {
+    let options = gSmsSegmentHelper.calculateUserDataLength7Bit(str);
+
+    do_check_eq(expected[0], options.encodedFullBodyLength);
+    do_check_eq(expected[1], options.userDataHeaderLength);
+    do_check_eq(expected[2], options.segmentMaxSeq);
+  }
+
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT),
+            [PDU_MAX_USER_DATA_7BIT, 0, 1]);
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1),
+            [PDU_MAX_USER_DATA_7BIT + 1, 5, 2]);
+
+  run_next_test();
+});
+
+/**
+ * Verify SmsSegmentHelper#fragmentText().
+ */
+add_test(function test_SmsSegmentHelper_fragmentText7Bit() {
+  function test_calc(str, strict7BitEncoding, expectedSegments) {
+    expectedSegments = expectedSegments || 1;
+    let options = gSmsSegmentHelper.fragmentText(str, null, strict7BitEncoding);
+    do_check_eq(expectedSegments, options.segments.length);
+  }
+
+  // 7-Bit
+
+  // Boundary checks
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), false);
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), true);
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), false, 2);
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), true, 2);
+
+  // Escaped character
+  test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2), false);
+  test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2 + 1), false, 2);
+  // Escaped character cannot be separated
+  test_calc(generateStringOfLength("{", (PDU_MAX_USER_DATA_7BIT - 7) * 2 / 2), false, 3);
+
+  // Test headerLen, 7 = Math.ceil(6 * 8 / 7), 6 = headerLen + 1
+  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT - 7));
+  test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 2), false, 2);
+  test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 3), false, 3);
+
+  // UCS-2
+
+  // Boundary checks
+  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2));
+  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2), true);
+  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), false, 2);
+  // Bug 816082: when strict GSM SMS 7-Bit encoding is enabled, replace unicode
+  // chars with '*'.
+  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), true, 1);
+
+  // UCS2 character cannot be separated
+  gSmsSegmentHelper.segmentRef16Bit = true;
+  test_calc(generateStringOfLength("\ua2db", (PDU_MAX_USER_DATA_UCS2 * 2 - 7) * 2 / 2), false, 3);
+  gSmsSegmentHelper.segmentRef16Bit = false;
+
+  // Test Bug 790192: support strict GSM SMS 7-Bit encoding
+  for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
+    test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), false, 3);
+    test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), true);
+    test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_UCS2), false);
+  }
+
+  run_next_test();
+});
diff --git a/dom/mobilemessage/tests/xpcshell/xpcshell.ini b/dom/mobilemessage/tests/xpcshell/xpcshell.ini
index 66492edfcc83..1b440ed5b3eb 100644
--- a/dom/mobilemessage/tests/xpcshell/xpcshell.ini
+++ b/dom/mobilemessage/tests/xpcshell/xpcshell.ini
@@ -17,3 +17,5 @@ run-if = toolkit == "gonk"
 run-if = toolkit == "gonk"
 [test_mms_service.js]
 run-if = toolkit == "gonk"
+[test_sms_segment_helper.js]
+run-if = toolkit == "gonk"
diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js
index 068d188404fc..a8914b571db9 100644
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -208,12 +208,6 @@ XPCOMUtils.defineLazyGetter(this, "WAP", function() {
   return wap;
 });
 
-XPCOMUtils.defineLazyGetter(this, "PhoneNumberUtils", function() {
-  let ns = {};
-  Cu.import("resource://gre/modules/PhoneNumberUtils.jsm", ns);
-  return ns.PhoneNumberUtils;
-});
-
 XPCOMUtils.defineLazyGetter(this, "gMessageManager", function() {
   return {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
@@ -3131,702 +3125,6 @@ RadioInterface.prototype = {
 
   rilContext: null,
 
-  /**
-   * List of tuples of national language identifier pairs.
-   *
-   * TODO: Support static/runtime settings, see bug 733331.
-   */
-  enabledGsmTableTuples: [
-    [RIL.PDU_NL_IDENTIFIER_DEFAULT, RIL.PDU_NL_IDENTIFIER_DEFAULT],
-  ],
-
-  /**
-   * Use 16-bit reference number for concatenated outgoint messages.
-   *
-   * TODO: Support static/runtime settings, see bug 733331.
-   */
-  segmentRef16Bit: false,
-
-  /**
-   * Get valid SMS concatenation reference number.
-   */
-  _segmentRef: 0,
-  get nextSegmentRef() {
-    let ref = this._segmentRef++;
-
-    this._segmentRef %= (this.segmentRef16Bit ? 65535 : 255);
-
-    // 0 is not a valid SMS concatenation reference number.
-    return ref + 1;
-  },
-
-  /**
-   * Calculate encoded length using specified locking/single shift table
-   *
-   * @param message
-   *        message string to be encoded.
-   * @param langTable
-   *        locking shift table string.
-   * @param langShiftTable
-   *        single shift table string.
-   * @param strict7BitEncoding
-   *        Optional. Enable Latin characters replacement with corresponding
-   *        ones in GSM SMS 7-bit default alphabet.
-   *
-   * @return encoded length in septets.
-   *
-   * @note that the algorithm used in this function must match exactly with
-   * GsmPDUHelper#writeStringAsSeptets.
-   */
-  _countGsm7BitSeptets: function(message, langTable, langShiftTable, strict7BitEncoding) {
-    let length = 0;
-    for (let msgIndex = 0; msgIndex < message.length; msgIndex++) {
-      let c = message.charAt(msgIndex);
-      if (strict7BitEncoding) {
-        c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c;
-      }
-
-      let septet = langTable.indexOf(c);
-
-      // According to 3GPP TS 23.038, section 6.1.1 General notes, "The
-      // characters marked '1)' are not used but are displayed as a space."
-      if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
-        continue;
-      }
-
-      if (septet >= 0) {
-        length++;
-        continue;
-      }
-
-      septet = langShiftTable.indexOf(c);
-      if (septet < 0) {
-        if (!strict7BitEncoding) {
-          return -1;
-        }
-
-        // Bug 816082, when strict7BitEncoding is enabled, we should replace
-        // characters that can't be encoded with GSM 7-Bit alphabets with '*'.
-        c = "*";
-        if (langTable.indexOf(c) >= 0) {
-          length++;
-        } else if (langShiftTable.indexOf(c) >= 0) {
-          length += 2;
-        } else {
-          // We can't even encode a '*' character with current configuration.
-          return -1;
-        }
-
-        continue;
-      }
-
-      // According to 3GPP TS 23.038 B.2, "This code represents a control
-      // character and therefore must not be used for language specific
-      // characters."
-      if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
-        continue;
-      }
-
-      // The character is not found in locking shfit table, but could be
-      // encoded as  with single shift table. Note that it's
-      // still possible for septet to has the value of PDU_NL_EXTENDED_ESCAPE,
-      // but we can display it as a space in this case as said in previous
-      // comment.
-      length += 2;
-    }
-
-    return length;
-  },
-
-  /**
-   * Calculate user data length of specified message string encoded in GSM 7Bit
-   * alphabets.
-   *
-   * @param message
-   *        a message string to be encoded.
-   * @param strict7BitEncoding
-   *        Optional. Enable Latin characters replacement with corresponding
-   *        ones in GSM SMS 7-bit default alphabet.
-   *
-   * @return null or an options object with attributes `dcs`,
-   *         `userDataHeaderLength`, `encodedFullBodyLength`, `langIndex`,
-   *         `langShiftIndex`, `segmentMaxSeq` set.
-   *
-   * @see #_calculateUserDataLength().
-   */
-  _calculateUserDataLength7Bit: function(message, strict7BitEncoding) {
-    let options = null;
-    let minUserDataSeptets = Number.MAX_VALUE;
-    for (let i = 0; i < this.enabledGsmTableTuples.length; i++) {
-      let [langIndex, langShiftIndex] = this.enabledGsmTableTuples[i];
-
-      const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
-      const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
-
-      let bodySeptets = this._countGsm7BitSeptets(message,
-                                                  langTable,
-                                                  langShiftTable,
-                                                  strict7BitEncoding);
-      if (bodySeptets < 0) {
-        continue;
-      }
-
-      let headerLen = 0;
-      if (langIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) {
-        headerLen += 3; // IEI + len + langIndex
-      }
-      if (langShiftIndex != RIL.PDU_NL_IDENTIFIER_DEFAULT) {
-        headerLen += 3; // IEI + len + langShiftIndex
-      }
-
-      // Calculate full user data length, note the extra byte is for header len
-      let headerSeptets = Math.ceil((headerLen ? headerLen + 1 : 0) * 8 / 7);
-      let segmentSeptets = RIL.PDU_MAX_USER_DATA_7BIT;
-      if ((bodySeptets + headerSeptets) > segmentSeptets) {
-        headerLen += this.segmentRef16Bit ? 6 : 5;
-        headerSeptets = Math.ceil((headerLen + 1) * 8 / 7);
-        segmentSeptets -= headerSeptets;
-      }
-
-      let segments = Math.ceil(bodySeptets / segmentSeptets);
-      let userDataSeptets = bodySeptets + headerSeptets * segments;
-      if (userDataSeptets >= minUserDataSeptets) {
-        continue;
-      }
-
-      minUserDataSeptets = userDataSeptets;
-
-      options = {
-        dcs: RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET,
-        encodedFullBodyLength: bodySeptets,
-        userDataHeaderLength: headerLen,
-        langIndex: langIndex,
-        langShiftIndex: langShiftIndex,
-        segmentMaxSeq: segments,
-        segmentChars: segmentSeptets,
-      };
-    }
-
-    return options;
-  },
-
-  /**
-   * Calculate user data length of specified message string encoded in UCS2.
-   *
-   * @param message
-   *        a message string to be encoded.
-   *
-   * @return an options object with attributes `dcs`, `userDataHeaderLength`,
-   *         `encodedFullBodyLength`, `segmentMaxSeq` set.
-   *
-   * @see #_calculateUserDataLength().
-   */
-  _calculateUserDataLengthUCS2: function(message) {
-    let bodyChars = message.length;
-    let headerLen = 0;
-    let headerChars = Math.ceil((headerLen ? headerLen + 1 : 0) / 2);
-    let segmentChars = RIL.PDU_MAX_USER_DATA_UCS2;
-    if ((bodyChars + headerChars) > segmentChars) {
-      headerLen += this.segmentRef16Bit ? 6 : 5;
-      headerChars = Math.ceil((headerLen + 1) / 2);
-      segmentChars -= headerChars;
-    }
-
-    let segments = Math.ceil(bodyChars / segmentChars);
-
-    return {
-      dcs: RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET,
-      encodedFullBodyLength: bodyChars * 2,
-      userDataHeaderLength: headerLen,
-      segmentMaxSeq: segments,
-      segmentChars: segmentChars,
-    };
-  },
-
-  /**
-   * Calculate user data length and its encoding.
-   *
-   * @param message
-   *        a message string to be encoded.
-   * @param strict7BitEncoding
-   *        Optional. Enable Latin characters replacement with corresponding
-   *        ones in GSM SMS 7-bit default alphabet.
-   *
-   * @return an options object with some or all of following attributes set:
-   *
-   * @param dcs
-   *        Data coding scheme. One of the PDU_DCS_MSG_CODING_*BITS_ALPHABET
-   *        constants.
-   * @param userDataHeaderLength
-   *        Length of embedded user data header, in bytes. The whole header
-   *        size will be userDataHeaderLength + 1; 0 for no header.
-   * @param encodedFullBodyLength
-   *        Length of the message body when encoded with the given DCS. For
-   *        UCS2, in bytes; for 7-bit, in septets.
-   * @param langIndex
-   *        Table index used for normal 7-bit encoded character lookup.
-   * @param langShiftIndex
-   *        Table index used for escaped 7-bit encoded character lookup.
-   * @param segmentMaxSeq
-   *        Max sequence number of a multi-part messages, or 1 for single one.
-   *        This number might not be accurate for a multi-part message until
-   *        it's processed by #_fragmentText() again.
-   */
-  _calculateUserDataLength: function(message, strict7BitEncoding) {
-    let options = this._calculateUserDataLength7Bit(message, strict7BitEncoding);
-    if (!options) {
-      options = this._calculateUserDataLengthUCS2(message);
-    }
-
-    if (DEBUG) this.debug("_calculateUserDataLength: " + JSON.stringify(options));
-    return options;
-  },
-
-  /**
-   * Fragment GSM 7-Bit encodable string for transmission.
-   *
-   * @param text
-   *        text string to be fragmented.
-   * @param langTable
-   *        locking shift table string.
-   * @param langShiftTable
-   *        single shift table string.
-   * @param segmentSeptets
-   *        Number of available spetets per segment.
-   * @param strict7BitEncoding
-   *        Optional. Enable Latin characters replacement with corresponding
-   *        ones in GSM SMS 7-bit default alphabet.
-   *
-   * @return an array of objects. See #_fragmentText() for detailed definition.
-   */
-  _fragmentText7Bit: function(text, langTable, langShiftTable, segmentSeptets, strict7BitEncoding) {
-    let ret = [];
-    let body = "", len = 0;
-    // If the message is empty, we only push the empty message to ret.
-    if (text.length === 0) {
-      ret.push({
-        body: text,
-        encodedBodyLength: text.length,
-      });
-      return ret;
-    }
-
-    for (let i = 0, inc = 0; i < text.length; i++) {
-      let c = text.charAt(i);
-      if (strict7BitEncoding) {
-        c = RIL.GSM_SMS_STRICT_7BIT_CHARMAP[c] || c;
-      }
-
-      let septet = langTable.indexOf(c);
-      if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
-        continue;
-      }
-
-      if (septet >= 0) {
-        inc = 1;
-      } else {
-        septet = langShiftTable.indexOf(c);
-        if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
-          continue;
-        }
-
-        inc = 2;
-        if (septet < 0) {
-          if (!strict7BitEncoding) {
-            throw new Error("Given text cannot be encoded with GSM 7-bit Alphabet!");
-          }
-
-          // Bug 816082, when strict7BitEncoding is enabled, we should replace
-          // characters that can't be encoded with GSM 7-Bit alphabets with '*'.
-          c = "*";
-          if (langTable.indexOf(c) >= 0) {
-            inc = 1;
-          }
-        }
-      }
-
-      if ((len + inc) > segmentSeptets) {
-        ret.push({
-          body: body,
-          encodedBodyLength: len,
-        });
-        body = c;
-        len = inc;
-      } else {
-        body += c;
-        len += inc;
-      }
-    }
-
-    if (len) {
-      ret.push({
-        body: body,
-        encodedBodyLength: len,
-      });
-    }
-
-    return ret;
-  },
-
-  /**
-   * Fragment UCS2 encodable string for transmission.
-   *
-   * @param text
-   *        text string to be fragmented.
-   * @param segmentChars
-   *        Number of available characters per segment.
-   *
-   * @return an array of objects. See #_fragmentText() for detailed definition.
-   */
-  _fragmentTextUCS2: function(text, segmentChars) {
-    let ret = [];
-    // If the message is empty, we only push the empty message to ret.
-    if (text.length === 0) {
-      ret.push({
-        body: text,
-        encodedBodyLength: text.length,
-      });
-      return ret;
-    }
-
-    for (let offset = 0; offset < text.length; offset += segmentChars) {
-      let str = text.substr(offset, segmentChars);
-      ret.push({
-        body: str,
-        encodedBodyLength: str.length * 2,
-      });
-    }
-
-    return ret;
-  },
-
-  /**
-   * Fragment string for transmission.
-   *
-   * Fragment input text string into an array of objects that contains
-   * attributes `body`, substring for this segment, `encodedBodyLength`,
-   * length of the encoded segment body in septets.
-   *
-   * @param text
-   *        Text string to be fragmented.
-   * @param options
-   *        Optional pre-calculated option object. The output array will be
-   *        stored at options.segments if there are multiple segments.
-   * @param strict7BitEncoding
-   *        Optional. Enable Latin characters replacement with corresponding
-   *        ones in GSM SMS 7-bit default alphabet.
-   *
-   * @return Populated options object.
-   */
-  _fragmentText: function(text, options, strict7BitEncoding) {
-    if (!options) {
-      options = this._calculateUserDataLength(text, strict7BitEncoding);
-    }
-
-    if (options.dcs == RIL.PDU_DCS_MSG_CODING_7BITS_ALPHABET) {
-      const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[options.langIndex];
-      const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[options.langShiftIndex];
-      options.segments = this._fragmentText7Bit(text,
-                                                langTable, langShiftTable,
-                                                options.segmentChars,
-                                                strict7BitEncoding);
-    } else {
-      options.segments = this._fragmentTextUCS2(text,
-                                                options.segmentChars);
-    }
-
-    // Re-sync options.segmentMaxSeq with actual length of returning array.
-    options.segmentMaxSeq = options.segments.length;
-
-    return options;
-  },
-
-  getSegmentInfoForText: function(text, request) {
-    let strict7BitEncoding;
-    try {
-      strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding");
-    } catch (e) {
-      strict7BitEncoding = false;
-    }
-
-    let options = this._fragmentText(text, null, strict7BitEncoding);
-    let charsInLastSegment;
-    if (options.segmentMaxSeq) {
-      let lastSegment = options.segments[options.segmentMaxSeq - 1];
-      charsInLastSegment = lastSegment.encodedBodyLength;
-      if (options.dcs == RIL.PDU_DCS_MSG_CODING_16BITS_ALPHABET) {
-        // In UCS2 encoding, encodedBodyLength is in octets.
-        charsInLastSegment /= 2;
-      }
-    } else {
-      charsInLastSegment = 0;
-    }
-
-    request.notifySegmentInfoForTextGot(options.segmentMaxSeq,
-                                        options.segmentChars,
-                                        options.segmentChars - charsInLastSegment);
-  },
-
-  getSmscAddress: function(request) {
-    this.workerMessenger.send("getSmscAddress",
-                              null,
-                              (function(response) {
-      if (!response.errorMsg) {
-        request.notifyGetSmscAddress(response.smscAddress);
-      } else {
-        request.notifyGetSmscAddressFailed(Ci.nsIMobileMessageCallback.NOT_FOUND_ERROR);
-      }
-    }).bind(this));
-  },
-
-  sendSMS: function(number, message, silent, request) {
-    let strict7BitEncoding;
-    try {
-      strict7BitEncoding = Services.prefs.getBoolPref("dom.sms.strict7BitEncoding");
-    } catch (e) {
-      strict7BitEncoding = false;
-    }
-
-    let options = this._fragmentText(message, null, strict7BitEncoding);
-    options.number = PhoneNumberUtils.normalize(number);
-    let requestStatusReport;
-    try {
-      requestStatusReport =
-        Services.prefs.getBoolPref("dom.sms.requestStatusReport");
-    } catch (e) {
-      requestStatusReport = true;
-    }
-    options.requestStatusReport = requestStatusReport && !silent;
-    if (options.segmentMaxSeq > 1) {
-      options.segmentRef16Bit = this.segmentRef16Bit;
-      options.segmentRef = this.nextSegmentRef;
-    }
-
-    let notifyResult = (function notifyResult(rv, domMessage) {
-      if (!Components.isSuccessCode(rv)) {
-        if (DEBUG) this.debug("Error! Fail to save sending message! rv = " + rv);
-        request.notifySendMessageFailed(
-          gMobileMessageDatabaseService.translateCrErrorToMessageCallbackError(rv),
-          domMessage);
-        Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
-        return;
-      }
-
-      if (!silent) {
-        Services.obs.notifyObservers(domMessage, kSmsSendingObserverTopic, null);
-      }
-
-      let connection =
-        gMobileConnectionService.getItemByServiceId(this.clientId);
-      // If the radio is disabled or the SIM card is not ready, just directly
-      // return with the corresponding error code.
-      let errorCode;
-      let radioState = connection && connection.radioState;
-      if (!PhoneNumberUtils.isPlainPhoneNumber(options.number)) {
-        if (DEBUG) this.debug("Error! Address is invalid when sending SMS: " +
-                              options.number);
-        errorCode = Ci.nsIMobileMessageCallback.INVALID_ADDRESS_ERROR;
-      } else if (radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_UNKNOWN ||
-                 radioState == Ci.nsIMobileConnection.MOBILE_RADIO_STATE_DISABLED) {
-        if (DEBUG) this.debug("Error! Radio is disabled when sending SMS.");
-        errorCode = Ci.nsIMobileMessageCallback.RADIO_DISABLED_ERROR;
-      } else if (this.rilContext.cardState != Ci.nsIIccProvider.CARD_STATE_READY) {
-        if (DEBUG) this.debug("Error! SIM card is not ready when sending SMS.");
-        errorCode = Ci.nsIMobileMessageCallback.NO_SIM_CARD_ERROR;
-      }
-      if (errorCode) {
-        if (silent) {
-          request.notifySendMessageFailed(errorCode, domMessage);
-          return;
-        }
-
-        gMobileMessageDatabaseService
-          .setMessageDeliveryByMessageId(domMessage.id,
-                                         null,
-                                         DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
-                                         RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
-                                         null,
-                                         function notifyResult(rv, domMessage) {
-          // TODO bug 832140 handle !Components.isSuccessCode(rv)
-          request.notifySendMessageFailed(errorCode, domMessage);
-          Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
-        });
-        return;
-      }
-
-      // Keep current SMS message info for sent/delivered notifications
-      let context = {
-        request: request,
-        sms: domMessage,
-        requestStatusReport: options.requestStatusReport,
-        silent: silent
-      };
-
-      // This is the entry point starting to send SMS.
-      this.workerMessenger.send("sendSMS", options,
-                                (function(context, response) {
-        if (response.errorMsg) {
-          // Failed to send SMS out.
-          let error = Ci.nsIMobileMessageCallback.UNKNOWN_ERROR;
-          switch (response.errorMsg) {
-            case RIL.ERROR_RADIO_NOT_AVAILABLE:
-              error = Ci.nsIMobileMessageCallback.NO_SIGNAL_ERROR;
-              break;
-            case RIL.ERROR_FDN_CHECK_FAILURE:
-              error = Ci.nsIMobileMessageCallback.FDN_CHECK_ERROR;
-              break;
-          }
-
-          if (context.silent) {
-            // There is no way to modify nsIDOMMozSmsMessage attributes as they
-            // are read only so we just create a new sms instance to send along
-            // with the notification.
-            let sms = context.sms;
-            context.request.notifySendMessageFailed(
-              error,
-              gMobileMessageService.createSmsMessage(sms.id,
-                                                     sms.threadId,
-                                                     sms.iccId,
-                                                     DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
-                                                     RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
-                                                     sms.sender,
-                                                     sms.receiver,
-                                                     sms.body,
-                                                     sms.messageClass,
-                                                     sms.timestamp,
-                                                     0,
-                                                     0,
-                                                     sms.read));
-            return false;
-          }
-
-          gMobileMessageDatabaseService
-            .setMessageDeliveryByMessageId(context.sms.id,
-                                           null,
-                                           DOM_MOBILE_MESSAGE_DELIVERY_ERROR,
-                                           RIL.GECKO_SMS_DELIVERY_STATUS_ERROR,
-                                           null,
-                                           function notifyResult(rv, domMessage) {
-            // TODO bug 832140 handle !Components.isSuccessCode(rv)
-            context.request.notifySendMessageFailed(error, domMessage);
-            Services.obs.notifyObservers(domMessage, kSmsFailedObserverTopic, null);
-          });
-          return false;
-        } // End of send failure.
-
-        if (response.deliveryStatus) {
-          // Message delivery.
-          gMobileMessageDatabaseService
-            .setMessageDeliveryByMessageId(context.sms.id,
-                                           null,
-                                           context.sms.delivery,
-                                           response.deliveryStatus,
-                                           null,
-                                           (function notifyResult(rv, domMessage) {
-            // TODO bug 832140 handle !Components.isSuccessCode(rv)
-
-            let topic = (response.deliveryStatus ==
-                         RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS)
-                        ? kSmsDeliverySuccessObserverTopic
-                        : kSmsDeliveryErrorObserverTopic;
-
-            // Broadcasting a "sms-delivery-success" system message to open apps.
-            if (topic == kSmsDeliverySuccessObserverTopic) {
-              this.broadcastSmsSystemMessage(
-                Ci.nsISmsMessenger.NOTIFICATION_TYPE_DELIVERY_SUCCESS, domMessage);
-            }
-
-            // Notifying observers the delivery status is updated.
-            Services.obs.notifyObservers(domMessage, topic, null);
-          }).bind(this));
-
-          // Send transaction has ended completely.
-          return false;
-        } // End of message delivery.
-
-        // Message sent.
-        if (context.silent) {
-          // There is no way to modify nsIDOMMozSmsMessage attributes as they
-          // are read only so we just create a new sms instance to send along
-          // with the notification.
-          let sms = context.sms;
-          context.request.notifyMessageSent(
-            gMobileMessageService.createSmsMessage(sms.id,
-                                                   sms.threadId,
-                                                   sms.iccId,
-                                                   DOM_MOBILE_MESSAGE_DELIVERY_SENT,
-                                                   sms.deliveryStatus,
-                                                   sms.sender,
-                                                   sms.receiver,
-                                                   sms.body,
-                                                   sms.messageClass,
-                                                   sms.timestamp,
-                                                   Date.now(),
-                                                   0,
-                                                   sms.read));
-          // We don't wait for SMS-DELIVER-REPORT for silent one.
-          return false;
-        }
-
-        gMobileMessageDatabaseService
-          .setMessageDeliveryByMessageId(context.sms.id,
-                                         null,
-                                         DOM_MOBILE_MESSAGE_DELIVERY_SENT,
-                                         context.sms.deliveryStatus,
-                                         null,
-                                         (function notifyResult(rv, domMessage) {
-          // TODO bug 832140 handle !Components.isSuccessCode(rv)
-
-          if (context.requestStatusReport) {
-            context.sms = domMessage;
-          }
-
-          this.broadcastSmsSystemMessage(
-            Ci.nsISmsMessenger.NOTIFICATION_TYPE_SENT, domMessage);
-          context.request.notifyMessageSent(domMessage);
-          Services.obs.notifyObservers(domMessage, kSmsSentObserverTopic, null);
-        }).bind(this));
-
-        // Only keep current context if we have requested for delivery report.
-        return context.requestStatusReport;
-      }).bind(this, context)); // End of |workerMessenger.send| callback.
-    }).bind(this); // End of DB saveSendingMessage callback.
-
-    let sendingMessage = {
-      type: "sms",
-      sender: this.getPhoneNumber(),
-      receiver: number,
-      body: message,
-      deliveryStatusRequested: options.requestStatusReport,
-      timestamp: Date.now(),
-      iccId: this.getIccId()
-    };
-
-    if (silent) {
-      let delivery = DOM_MOBILE_MESSAGE_DELIVERY_SENDING;
-      let deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_PENDING;
-      let domMessage =
-        gMobileMessageService.createSmsMessage(-1, // id
-                                               0,  // threadId
-                                               sendingMessage.iccId,
-                                               delivery,
-                                               deliveryStatus,
-                                               sendingMessage.sender,
-                                               sendingMessage.receiver,
-                                               sendingMessage.body,
-                                               "normal", // message class
-                                               sendingMessage.timestamp,
-                                               0,
-                                               0,
-                                               false);
-      notifyResult(Cr.NS_OK, domMessage);
-      return;
-    }
-
-    let id = gMobileMessageDatabaseService.saveSendingMessage(
-      sendingMessage, notifyResult);
-  },
-
   // TODO: Bug 928861 - B2G NetworkManager: Provide a more generic function
   //                    for connecting
   setupDataCallByType: function(networkType) {
diff --git a/dom/system/gonk/nsIRadioInterfaceLayer.idl b/dom/system/gonk/nsIRadioInterfaceLayer.idl
index fb8d943b7e63..f20564c7aac9 100644
--- a/dom/system/gonk/nsIRadioInterfaceLayer.idl
+++ b/dom/system/gonk/nsIRadioInterfaceLayer.idl
@@ -40,7 +40,7 @@ interface nsIRilSendWorkerMessageCallback : nsISupports
   boolean handleResponse(in jsval response);
 };
 
-[scriptable, uuid(864a47d6-a576-4a5c-b8b8-9ca312345f52)]
+[scriptable, uuid(fe01c648-867a-11e4-915f-033b36e8177b)]
 interface nsIRadioInterface : nsISupports
 {
   readonly attribute nsIRilContext rilContext;
@@ -58,22 +58,9 @@ interface nsIRadioInterface : nsISupports
 
   void updateRILNetworkInterface();
 
-  /**
-   * SMS-related functionality.
-   */
-  void getSegmentInfoForText(in DOMString text,
-                             in nsIMobileMessageCallback request);
-
-  void sendSMS(in DOMString number,
-               in DOMString message,
-               in boolean silent,
-               in nsIMobileMessageCallback request);
-
   void sendWorkerMessage(in DOMString type,
               [optional] in jsval message,
               [optional] in nsIRilSendWorkerMessageCallback callback);
-
-  void getSmscAddress(in nsIMobileMessageCallback request);
 };
 
 [scriptable, uuid(78b65e8c-68e7-4510-9a05-65bba12b283e)]
diff --git a/dom/system/gonk/tests/header_helpers.js b/dom/system/gonk/tests/header_helpers.js
index 8976a6faffdb..8c36e1c6645f 100644
--- a/dom/system/gonk/tests/header_helpers.js
+++ b/dom/system/gonk/tests/header_helpers.js
@@ -11,7 +11,7 @@ let subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
 
 /**
  * Start a new RIL worker.
- * 
+ *
  * @param custom_ns
  *        Namespace with symbols to be injected into the new worker
  *        namespace.
@@ -192,21 +192,6 @@ function newIncomingParcel(fakeParcelSize, response, request, data) {
   return bytes;
 }
 
-/**
- *
- */
-let ril_ns;
-function newRadioInterface() {
-  if (!ril_ns) {
-    ril_ns = {};
-    subscriptLoader.loadSubScript("resource://gre/components/RadioInterfaceLayer.js", ril_ns);
-  }
-
-  return {
-    __proto__: ril_ns.RadioInterface.prototype,
-  };
-}
-
 /**
  * Test whether specified function throws exception with expected
  * result.
diff --git a/dom/system/gonk/tests/test_ril_worker_sms.js b/dom/system/gonk/tests/test_ril_worker_sms.js
index 7fc3e471fc69..4e3ba768ec01 100644
--- a/dom/system/gonk/tests/test_ril_worker_sms.js
+++ b/dom/system/gonk/tests/test_ril_worker_sms.js
@@ -3,6 +3,14 @@
 
 subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
 
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
+  let ns = {};
+  Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
+  return ns.SmsSegmentHelper;
+});
+
 const ESCAPE = "\uffff";
 const RESCTL = "\ufffe";
 
@@ -146,14 +154,11 @@ function add_test_receiving_sms(expected, pdu) {
   });
 }
 
-let test_receiving_7bit_alphabets__ril;
 let test_receiving_7bit_alphabets__worker;
 function test_receiving_7bit_alphabets(lst, sst) {
-  if (!test_receiving_7bit_alphabets__ril) {
-    test_receiving_7bit_alphabets__ril = newRadioInterface();
+  if (!test_receiving_7bit_alphabets__worker) {
     test_receiving_7bit_alphabets__worker = newWriteHexOctetAsUint8Worker();
   }
-  let ril = test_receiving_7bit_alphabets__ril;
   let worker = test_receiving_7bit_alphabets__worker;
   let context = worker.ContextPool._contexts[0];
   let helper = context.GsmPDUHelper;
@@ -174,7 +179,8 @@ function test_receiving_7bit_alphabets(lst, sst) {
   for (let i = 0; i < text.length;) {
     let len = Math.min(70, text.length - i);
     let expected = text.substring(i, i + len);
-    let septets = ril._countGsm7BitSeptets(expected, langTable, langShiftTable);
+    let septets =
+      gSmsSegmentHelper.countGsm7BitSeptets(expected, langTable, langShiftTable);
     let rawBytes = get7bitRawBytes(expected);
     let pdu = compose7bitPdu(lst, sst, rawBytes, septets);
     add_test_receiving_sms(expected, pdu);
diff --git a/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js b/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
index c472bb274cf3..1b3c2c02b213 100644
--- a/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
+++ b/dom/system/gonk/tests/test_ril_worker_sms_segment_info.js
@@ -3,21 +3,26 @@
 
 subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this);
 
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyGetter(this, "gSmsSegmentHelper", function() {
+  let ns = {};
+  Cu.import("resource://gre/modules/SmsSegmentHelper.jsm", ns);
+  return ns.SmsSegmentHelper;
+});
+
 const ESCAPE = "\uffff";
 const RESCTL = "\ufffe";
-const SP = " ";
 
 function run_test() {
   run_next_test();
 }
 
 /**
- * Verify RadioInterface#_countGsm7BitSeptets() and
+ * Verify SmsSegmentHelper#countGsm7BitSeptets() and
  * GsmPDUHelper#writeStringAsSeptets() algorithm match each other.
  */
-add_test(function test_RadioInterface__countGsm7BitSeptets() {
-  let ril = newRadioInterface();
-
+add_test(function test_SmsSegmentHelper__countGsm7BitSeptets() {
   let worker = newWorker({
     postRILMessage: function(data) {
       // Do nothing
@@ -38,10 +43,11 @@ add_test(function test_RadioInterface__countGsm7BitSeptets() {
 
   function do_check_calc(str, expectedCalcLen, lst, sst, strict7BitEncoding, strToWrite) {
     do_check_eq(expectedCalcLen,
-                ril._countGsm7BitSeptets(str,
-                                         PDU_NL_LOCKING_SHIFT_TABLES[lst],
-                                         PDU_NL_SINGLE_SHIFT_TABLES[sst],
-                                         strict7BitEncoding));
+                gSmsSegmentHelper
+                  .countGsm7BitSeptets(str,
+                                       PDU_NL_LOCKING_SHIFT_TABLES[lst],
+                                       PDU_NL_SINGLE_SHIFT_TABLES[sst],
+                                       strict7BitEncoding));
 
     helper.resetOctetWritten();
     strToWrite = strToWrite || str;
@@ -107,179 +113,3 @@ add_test(function test_RadioInterface__countGsm7BitSeptets() {
   run_next_test();
 });
 
-/**
- * Verify RadioInterface#calculateUserDataLength handles national language
- * selection correctly.
- */
-add_test(function test_RadioInterface__calculateUserDataLength() {
-  let ril = newRadioInterface();
-
-  function test_calc(str, expected, enabledGsmTableTuples, strict7BitEncoding) {
-    ril.enabledGsmTableTuples = enabledGsmTableTuples;
-    let options = ril._calculateUserDataLength(str, strict7BitEncoding);
-
-    do_check_eq(expected[0], options.dcs);
-    do_check_eq(expected[1], options.encodedFullBodyLength);
-    do_check_eq(expected[2], options.userDataHeaderLength);
-    do_check_eq(expected[3], options.langIndex);
-    do_check_eq(expected[4], options.langShiftIndex);
-  }
-
-  // Test UCS fallback
-  // - No any default enabled nl tables
-  test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], []);
-  // - Character not defined in enabled nl tables
-  test_calc("A", [PDU_DCS_MSG_CODING_16BITS_ALPHABET, 2, 0,], [[2, 2]]);
-
-  // With GSM default nl tables
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
-  // - SP is defined in both locking/single shift tables, should be directly
-  //   encoded.
-  test_calc(SP, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 0, 0, 0], [[0, 0]]);
-  // - '^' is only defined in single shift table, should be encoded as
-  //   ^.
-  test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[0, 0]]);
-
-  // Test userDataHeaderLength calculation
-  // - Header contains both IEIs
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 6, 1, 1], [[1, 1]]);
-  // - Header contains only locking shift table IEI
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0]]);
-  // - Header contains only single shift table IEI
-  test_calc("^", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 3, 0, 1], [[0, 1]]);
-
-  // Test minimum cost nl tables selection
-  // - 'A' is defined in locking shift table
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 0]]);
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 0], [1, 0]]);
-  // - 'A' is defined in single shift table
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 0], [2, 4]]);
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 6, 2, 4], [[2, 4], [2, 0]]);
-  // - 'A' is defined in locking shift table of one tuple and in single shift
-  //   table of another.
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[1, 0], [2, 4]]);
-  test_calc("A", [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 1, 3, 1, 0], [[2, 4], [1, 0]]);
-
-  // Test Bug 733981
-  // - Case 1, headerLen is in octets, not septets. "\\" is defined in default
-  //   single shift table and Portuguese locking shift table. The original code
-  //   will add headerLen 7(octets), which should be 8(septets), to calculated
-  //   cost and gets 14, which should be 15 in total for the first run. As for
-  //   the second run, it will be undoubtedly 14 in total. With correct fix,
-  //   the best choice should be the second one.
-  test_calc("\\\\\\\\\\\\\\",
-            [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 14, 0, 0, 0], [[3, 1], [0, 0]]);
-  // - Case 2, possible early return non-best choice. The original code will
-  //   get total cost 6 in the first run and returns immediately. With correct
-  //   fix, the best choice should be the second one.
-  test_calc(ESCAPE + ESCAPE + ESCAPE + ESCAPE + ESCAPE + "\\",
-            [PDU_DCS_MSG_CODING_7BITS_ALPHABET, 2, 0, 0, 0], [[3, 0], [0, 0]]);
-
-  // Test Bug 790192: support strict GSM SMS 7-Bit encoding
-  let str = "", gsmLen = 0, udhl = 0;
-  for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
-    str += c;
-    if (PDU_NL_LOCKING_SHIFT_TABLES.indexOf(GSM_SMS_STRICT_7BIT_CHARMAP[c])) {
-      gsmLen += 1;
-    } else {
-      gsmLen += 2;
-    }
-  }
-  if (str.length > PDU_MAX_USER_DATA_UCS2) {
-    udhl = 5;
-  }
-  test_calc(str, [PDU_DCS_MSG_CODING_7BITS_ALPHABET, gsmLen, 0, 0, 0], [[0, 0]], true);
-  test_calc(str, [PDU_DCS_MSG_CODING_16BITS_ALPHABET, str.length * 2, udhl], [[0, 0]]);
-
-  run_next_test();
-});
-
-function generateStringOfLength(str, length) {
-  while (str.length < length) {
-    if (str.length < (length / 2)) {
-      str = str + str;
-    } else {
-      str = str + str.substr(0, length - str.length);
-    }
-  }
-
-  return str;
-}
-
-/**
- * Verify RadioInterface#_calculateUserDataLength7Bit multipart handling.
- */
-add_test(function test_RadioInterface__calculateUserDataLength7Bit_multipart() {
-  let ril = newRadioInterface();
-
-  function test_calc(str, expected) {
-    let options = ril._calculateUserDataLength7Bit(str);
-
-    do_check_eq(expected[0], options.encodedFullBodyLength);
-    do_check_eq(expected[1], options.userDataHeaderLength);
-    do_check_eq(expected[2], options.segmentMaxSeq);
-  }
-
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT),
-            [PDU_MAX_USER_DATA_7BIT, 0, 1]);
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1),
-            [PDU_MAX_USER_DATA_7BIT + 1, 5, 2]);
-
-  run_next_test();
-});
-
-/**
- * Verify RadioInterface#_fragmentText().
- */
-add_test(function test_RadioInterface__fragmentText7Bit() {
-  let ril = newRadioInterface();
-
-  function test_calc(str, strict7BitEncoding, expectedSegments) {
-    expectedSegments = expectedSegments || 1;
-    let options = ril._fragmentText(str, null, strict7BitEncoding);
-    do_check_eq(expectedSegments, options.segments.length);
-  }
-
-  // 7-Bit
-
-  // Boundary checks
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), false);
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT), true);
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), false, 2);
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT + 1), true, 2);
-
-  // Escaped character
-  test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2), false);
-  test_calc(generateStringOfLength("{", PDU_MAX_USER_DATA_7BIT / 2 + 1), false, 2);
-  // Escaped character cannot be separated
-  test_calc(generateStringOfLength("{", (PDU_MAX_USER_DATA_7BIT - 7) * 2 / 2), false, 3);
-
-  // Test headerLen, 7 = Math.ceil(6 * 8 / 7), 6 = headerLen + 1
-  test_calc(generateStringOfLength("A", PDU_MAX_USER_DATA_7BIT - 7));
-  test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 2), false, 2);
-  test_calc(generateStringOfLength("A", (PDU_MAX_USER_DATA_7BIT - 7) * 3), false, 3);
-
-  // UCS-2
-
-  // Boundary checks
-  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2));
-  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2), true);
-  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), false, 2);
-  // Bug 816082: when strict GSM SMS 7-Bit encoding is enabled, replace unicode
-  // chars with '*'.
-  test_calc(generateStringOfLength("\ua2db", PDU_MAX_USER_DATA_UCS2 + 1), true, 1);
-
-  // UCS2 character cannot be separated
-  ril.segmentRef16Bit = true;
-  test_calc(generateStringOfLength("\ua2db", (PDU_MAX_USER_DATA_UCS2 * 2 - 7) * 2 / 2), false, 3);
-  ril.segmentRef16Bit = false;
-
-  // Test Bug 790192: support strict GSM SMS 7-Bit encoding
-  for (let c in GSM_SMS_STRICT_7BIT_CHARMAP) {
-    test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), false, 3);
-    test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_7BIT), true);
-    test_calc(generateStringOfLength(c, PDU_MAX_USER_DATA_UCS2), false);
-  }
-
-  run_next_test();
-});

From 4a672075aef65b628957662ad05178d462d75543 Mon Sep 17 00:00:00 2001
From: Bevis Tseng 
Date: Thu, 27 Nov 2014 18:59:06 +0800
Subject: [PATCH 132/183] Bug 873351 - Part 3: Refactor SMS Notifications from
 RadioInterfaceLayer to SmsService. r=echen

---
 dom/mobilemessage/android/SmsService.cpp      |   8 -
 dom/mobilemessage/gonk/MobileMessageDB.jsm    |   4 +-
 dom/mobilemessage/gonk/SmsService.js          | 483 ++++++++++++-
 .../interfaces/nsIGonkSmsService.idl          |  83 ++-
 .../interfaces/nsISmsService.idl              |   3 +-
 dom/mobilemessage/ipc/SmsIPCService.cpp       |   8 -
 dom/system/gonk/RadioInterfaceLayer.js        | 656 ++----------------
 7 files changed, 618 insertions(+), 627 deletions(-)

diff --git a/dom/mobilemessage/android/SmsService.cpp b/dom/mobilemessage/android/SmsService.cpp
index 3a169c57b0b6..1bff0128ecc7 100644
--- a/dom/mobilemessage/android/SmsService.cpp
+++ b/dom/mobilemessage/android/SmsService.cpp
@@ -50,14 +50,6 @@ SmsService::Send(uint32_t aServiceId,
   return NS_OK;
 }
 
-NS_IMETHODIMP
-SmsService::IsSilentNumber(const nsAString& aNumber,
-                           bool*            aIsSilent)
-{
-  NS_NOTYETIMPLEMENTED("Implement me!");
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
 NS_IMETHODIMP
 SmsService::AddSilentNumber(const nsAString& aNumber)
 {
diff --git a/dom/mobilemessage/gonk/MobileMessageDB.jsm b/dom/mobilemessage/gonk/MobileMessageDB.jsm
index 182d54cc248e..55e7dce599ea 100644
--- a/dom/mobilemessage/gonk/MobileMessageDB.jsm
+++ b/dom/mobilemessage/gonk/MobileMessageDB.jsm
@@ -2968,11 +2968,11 @@ MobileMessageDB.prototype = {
         // save it into the segmentRecord.
         if (aSmsSegment.teleservice === RIL.PDU_CDMA_MSG_TELESERIVCIE_ID_WAP
             && seq === 1) {
-          if (aSmsSegment.originatorPort) {
+          if (aSmsSegment.originatorPort === Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID) {
             segmentRecord.originatorPort = aSmsSegment.originatorPort;
           }
 
-          if (aSmsSegment.destinationPort) {
+          if (aSmsSegment.destinationPort === Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID) {
             segmentRecord.destinationPort = aSmsSegment.destinationPort;
           }
         }
diff --git a/dom/mobilemessage/gonk/SmsService.js b/dom/mobilemessage/gonk/SmsService.js
index 8adf1b0df5a8..362717d8043d 100644
--- a/dom/mobilemessage/gonk/SmsService.js
+++ b/dom/mobilemessage/gonk/SmsService.js
@@ -35,6 +35,8 @@ const DOM_MOBILE_MESSAGE_DELIVERY_SENDING  = "sending";
 const DOM_MOBILE_MESSAGE_DELIVERY_SENT     = "sent";
 const DOM_MOBILE_MESSAGE_DELIVERY_ERROR    = "error";
 
+const SMS_HANDLED_WAKELOCK_TIMEOUT = 5000;
+
 XPCOMUtils.defineLazyGetter(this, "gRadioInterfaces", function() {
   let ril = Cc["@mozilla.org/ril;1"].getService(Ci.nsIRadioInterfaceLayer);
 
@@ -57,6 +59,16 @@ XPCOMUtils.defineLazyGetter(this, "gPhoneNumberUtils", function() {
   return ns.PhoneNumberUtils;
 });
 
+XPCOMUtils.defineLazyGetter(this, "gWAP", function() {
+  let ns = {};
+  Cu.import("resource://gre/modules/WapPushManager.js", ns);
+  return ns;
+});
+
+XPCOMUtils.defineLazyServiceGetter(this, "gCellBroadcastService",
+                                   "@mozilla.org/cellbroadcast/gonkservice;1",
+                                   "nsIGonkCellBroadcastService");
+
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
                                    "@mozilla.org/mobileconnection/mobileconnectionservice;1",
                                    "nsIMobileConnectionService");
@@ -69,6 +81,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "@mozilla.org/mobilemessage/mobilemessageservice;1",
                                    "nsIMobileMessageService");
 
+XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
+                                   "@mozilla.org/power/powermanagerservice;1",
+                                   "nsIPowerManagerService");
+
 XPCOMUtils.defineLazyServiceGetter(this, "gSmsMessenger",
                                    "@mozilla.org/ril/system-messenger-helper;1",
                                    "nsISmsMessenger");
@@ -82,6 +98,11 @@ function SmsService() {
   this._silentNumbers = [];
   this.smsDefaultServiceId = this._getDefaultServiceId();
 
+  this._portAddressedSmsApps = {};
+  this._portAddressedSmsApps[gWAP.WDP_PORT_PUSH] = this._handleSmsWdpPortPush.bind(this);
+
+  this._receivedSmsSegmentsMap = {};
+
   Services.prefs.addObserver(kPrefRilDebuggingEnabled, this, false);
   Services.prefs.addObserver(kPrefDefaultServiceId, this, false);
   Services.obs.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
@@ -151,6 +172,43 @@ SmsService.prototype = {
     return iccInfo.iccid;
   },
 
+  // The following attributes/functions are used for acquiring/releasing the
+  // CPU wake lock when the RIL handles the received SMS. Note that we need
+  // a timer to bound the lock's life cycle to avoid exhausting the battery.
+  _smsHandledWakeLock: null,
+  _smsHandledWakeLockTimer: null,
+  _acquireSmsHandledWakeLock: function() {
+    if (!this._smsHandledWakeLock) {
+      if (DEBUG) debug("Acquiring a CPU wake lock for handling SMS.");
+      this._smsHandledWakeLock = gPowerManagerService.newWakeLock("cpu");
+    }
+    if (!this._smsHandledWakeLockTimer) {
+      if (DEBUG) debug("Creating a timer for releasing the CPU wake lock.");
+      this._smsHandledWakeLockTimer =
+        Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+    }
+    if (DEBUG) debug("Setting the timer for releasing the CPU wake lock.");
+    this._smsHandledWakeLockTimer
+        .initWithCallback(this._releaseSmsHandledWakeLock.bind(this),
+                          SMS_HANDLED_WAKELOCK_TIMEOUT,
+                          Ci.nsITimer.TYPE_ONE_SHOT);
+  },
+
+  _releaseSmsHandledWakeLock: function() {
+    if (DEBUG) debug("Releasing the CPU wake lock for handling SMS.");
+    if (this._smsHandledWakeLockTimer) {
+      this._smsHandledWakeLockTimer.cancel();
+    }
+    if (this._smsHandledWakeLock) {
+      this._smsHandledWakeLock.unlock();
+      this._smsHandledWakeLock = null;
+    }
+  },
+
+  _convertSmsMessageClassToString: function(aMessageClass) {
+    return RIL.GECKO_SMS_MESSAGE_CLASSES[aMessageClass] || null;
+  },
+
   _convertSmsMessageClass: function(aMessageClass) {
     let index = RIL.GECKO_SMS_MESSAGE_CLASSES.indexOf(aMessageClass);
 
@@ -362,6 +420,347 @@ SmsService.prototype = {
     }
   },
 
+  /**
+   * Helper for processing received multipart SMS.
+   *
+   * @return null for handled segments, and an object containing full message
+   *         body/data once all segments are received.
+   *
+   * |_receivedSmsSegmentsMap|:
+   *   Hash map for received multipart sms fragments. Messages are hashed with
+   *   its sender address and concatenation reference number. Three additional
+   *   attributes `segmentMaxSeq`, `receivedSegments`, `segments` are inserted.
+   */
+  _receivedSmsSegmentsMap: null,
+  _processReceivedSmsSegment: function(aSegment) {
+    // Directly replace full message body for single SMS.
+    if (!(aSegment.segmentMaxSeq && (aSegment.segmentMaxSeq > 1))) {
+      if (aSegment.encoding == Ci.nsIGonkSmsService.SMS_MESSAGE_ENCODING_8BITS_ALPHABET) {
+        aSegment.fullData = aSegment.data;
+      } else {
+        aSegment.fullBody = aSegment.body;
+      }
+      return aSegment;
+    }
+
+    // Handle Concatenation for Class 0 SMS
+    let hash = aSegment.sender + ":" +
+               aSegment.segmentRef + ":" +
+               aSegment.segmentMaxSeq;
+    let seq = aSegment.segmentSeq;
+
+    let options = this._receivedSmsSegmentsMap[hash];
+    if (!options) {
+      options = aSegment;
+      this._receivedSmsSegmentsMap[hash] = options;
+
+      options.receivedSegments = 0;
+      options.segments = [];
+    } else if (options.segments[seq]) {
+      // Duplicated segment?
+      if (DEBUG) {
+        debug("Got duplicated segment no." + seq +
+              " of a multipart SMS: " + JSON.stringify(aSegment));
+      }
+      return null;
+    }
+
+    if (options.receivedSegments > 0) {
+      // Update received timestamp.
+      options.timestamp = aSegment.timestamp;
+    }
+
+    if (options.encoding == Ci.nsIGonkSmsService.SMS_MESSAGE_ENCODING_8BITS_ALPHABET) {
+      options.segments[seq] = aSegment.data;
+    } else {
+      options.segments[seq] = aSegment.body;
+    }
+    options.receivedSegments++;
+
+    // The port information is only available in 1st segment for CDMA WAP Push.
+    // If the segments of a WAP Push are not received in sequence
+    // (e.g., SMS with seq == 1 is not the 1st segment received by the device),
+    // we have to retrieve the port information from 1st segment and
+    // save it into the cached options.
+    if (aSegment.teleservice === RIL.PDU_CDMA_MSG_TELESERIVCIE_ID_WAP
+        && seq === 1) {
+      if (options.originatorPort === Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID
+          && aSegment.originatorPort !== Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID) {
+        options.originatorPort = aSegment.originatorPort;
+      }
+
+      if (options.destinationPort === Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID
+          && aSegment.destinationPort !== Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID) {
+        options.destinationPort = aSegment.destinationPort;
+      }
+    }
+
+    if (options.receivedSegments < options.segmentMaxSeq) {
+      if (DEBUG) {
+        debug("Got segment no." + seq + " of a multipart SMS: " +
+                           JSON.stringify(options));
+      }
+      return null;
+    }
+
+    // Remove from map
+    delete this._receivedSmsSegmentsMap[hash];
+
+    // Rebuild full body
+    if (options.encoding == Ci.nsIGonkSmsService.SMS_MESSAGE_ENCODING_8BITS_ALPHABET) {
+      // Uint8Array doesn't have `concat`, so we have to merge all segements
+      // by hand.
+      let fullDataLen = 0;
+      for (let i = 1; i <= options.segmentMaxSeq; i++) {
+        fullDataLen += options.segments[i].length;
+      }
+
+      options.fullData = new Uint8Array(fullDataLen);
+      for (let d= 0, i = 1; i <= options.segmentMaxSeq; i++) {
+        let data = options.segments[i];
+        for (let j = 0; j < data.length; j++) {
+          options.fullData[d++] = data[j];
+        }
+      }
+    } else {
+      options.fullBody = options.segments.join("");
+    }
+
+    // Remove handy fields after completing the concatenation.
+    delete options.receivedSegments;
+    delete options.segments;
+
+    if (DEBUG) {
+      debug("Got full multipart SMS: " + JSON.stringify(options));
+    }
+
+    return options;
+  },
+
+  /**
+   * Helper to purge complete message.
+   *
+   * We remove unnessary fields after completing the concatenation.
+   */
+  _purgeCompleteSmsMessage: function(aMessage) {
+    // Purge concatenation info
+    delete aMessage.segmentRef;
+    delete aMessage.segmentSeq;
+    delete aMessage.segmentMaxSeq;
+
+    // Purge partial message body
+    delete aMessage.data;
+    delete aMessage.body;
+  },
+
+  /**
+   * Handle WDP port push PDU. Constructor WDP bearer information and deliver
+   * to WapPushManager.
+   *
+   * @param aMessage
+   *        A SMS message.
+   */
+  _handleSmsWdpPortPush: function(aMessage, aServiceId) {
+    if (aMessage.encoding != Ci.nsIGonkSmsService.SMS_MESSAGE_ENCODING_8BITS_ALPHABET) {
+      if (DEBUG) {
+        debug("Got port addressed SMS but not encoded in 8-bit alphabet." +
+                   " Drop!");
+      }
+      return;
+    }
+
+    let options = {
+      bearer: gWAP.WDP_BEARER_GSM_SMS_GSM_MSISDN,
+      sourceAddress: aMessage.sender,
+      sourcePort: aMessage.originatorPort,
+      destinationAddress: this._getPhoneNumber(aServiceId),
+      destinationPort: aMessage.destinationPort,
+      serviceId: aServiceId
+    };
+    gWAP.WapPushManager.receiveWdpPDU(aMessage.fullData, aMessage.fullData.length,
+                                     0, options);
+  },
+
+  _handleCellbroadcastMessageReceived: function(aMessage, aServiceId) {
+    gCellBroadcastService
+      .notifyMessageReceived(aServiceId,
+                             Ci.nsICellBroadcastService.GSM_GEOGRAPHICAL_SCOPE_INVALID,
+                             aMessage.messageCode,
+                             aMessage.messageId,
+                             aMessage.language,
+                             aMessage.fullBody,
+                             Ci.nsICellBroadcastService.GSM_MESSAGE_CLASS_NORMAL,
+                             Date.now(),
+                             aMessage.serviceCategory,
+                             false,
+                             Ci.nsICellBroadcastService.GSM_ETWS_WARNING_INVALID,
+                             false,
+                             false);
+  },
+
+  _handleMwis: function(aMwi, aServiceId) {
+    let service = Cc["@mozilla.org/voicemail/voicemailservice;1"]
+                  .getService(Ci.nsIGonkVoicemailService);
+    service.notifyStatusChanged(aServiceId, aMwi.active, aMwi.msgCount,
+                                aMwi.returnNumber, aMwi.returnMessage);
+
+    gRadioInterfaces[aServiceId].sendWorkerMessage("updateMwis", { mwi: aMwi });
+  },
+
+  _portAddressedSmsApps: null,
+  _handleSmsReceived: function(aMessage, aServiceId) {
+    if (DEBUG) debug("_handleSmsReceived: " + JSON.stringify(aMessage));
+
+    if (aMessage.messageType == RIL.PDU_CDMA_MSG_TYPE_BROADCAST) {
+      this._handleCellbroadcastMessageReceived(aMessage, aServiceId);
+      return true;
+    }
+
+    // Dispatch to registered handler if application port addressing is
+    // available. Note that the destination port can possibly be zero when
+    // representing a UDP/TCP port.
+    if (aMessage.destinationPort !== Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID) {
+      let handler = this._portAddressedSmsApps[aMessage.destinationPort];
+      if (handler) {
+        handler(aMessage, aServiceId);
+      }
+      return true;
+    }
+
+    if (aMessage.encoding == Ci.nsIGonkSmsService.SMS_MESSAGE_ENCODING_8BITS_ALPHABET) {
+      // Don't know how to handle binary data yet.
+      return true;
+    }
+
+    aMessage.type = "sms";
+    aMessage.sender = aMessage.sender || null;
+    aMessage.receiver = this._getPhoneNumber(aServiceId);
+    aMessage.body = aMessage.fullBody = aMessage.fullBody || null;
+
+    if (this._isSilentNumber(aMessage.sender)) {
+      aMessage.id = -1;
+      aMessage.threadId = 0;
+      aMessage.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
+      aMessage.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
+      aMessage.read = false;
+
+      let domMessage =
+        gMobileMessageService.createSmsMessage(aMessage.id,
+                                               aMessage.threadId,
+                                               aMessage.iccId,
+                                               aMessage.delivery,
+                                               aMessage.deliveryStatus,
+                                               aMessage.sender,
+                                               aMessage.receiver,
+                                               aMessage.body,
+                                               aMessage.messageClass,
+                                               aMessage.timestamp,
+                                               aMessage.sentTimestamp,
+                                               0,
+                                               aMessage.read);
+
+      Services.obs.notifyObservers(domMessage,
+                                   kSilentSmsReceivedObserverTopic,
+                                   null);
+      return true;
+    }
+
+    if (aMessage.mwiPresent) {
+      let mwi = {
+        discard: aMessage.mwiDiscard,
+        msgCount: aMessage.mwiMsgCount,
+        active: aMessage.mwiActive,
+        returnNumber: aMessage.sender || null,
+        returnMessage: aMessage.fullBody || null
+      };
+
+      this._handleMwis(mwi, aServiceId);
+
+      // Dicarded MWI comes without text body.
+      // Hence, we discard it here after notifying the MWI status.
+      if (aMessage.mwiDiscard) {
+        return true;
+      }
+    }
+
+    let notifyReceived = (aRv, aDomMessage) => {
+      let success = Components.isSuccessCode(aRv);
+
+      this._sendAckSms(aRv, aMessage, aServiceId);
+
+      if (!success) {
+        // At this point we could send a message to content to notify the user
+        // that storing an incoming SMS failed, most likely due to a full disk.
+        if (DEBUG) {
+          debug("Could not store SMS, error code " + aRv);
+        }
+        return;
+      }
+
+      this._broadcastSmsSystemMessage(
+        Ci.nsISmsMessenger.NOTIFICATION_TYPE_RECEIVED, aDomMessage);
+      Services.obs.notifyObservers(aDomMessage, kSmsReceivedObserverTopic, null);
+    };
+
+    if (aMessage.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
+      gMobileMessageDatabaseService.saveReceivedMessage(aMessage,
+                                                        notifyReceived);
+    } else {
+      aMessage.id = -1;
+      aMessage.threadId = 0;
+      aMessage.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
+      aMessage.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
+      aMessage.read = false;
+
+      let domMessage =
+        gMobileMessageService.createSmsMessage(aMessage.id,
+                                               aMessage.threadId,
+                                               aMessage.iccId,
+                                               aMessage.delivery,
+                                               aMessage.deliveryStatus,
+                                               aMessage.sender,
+                                               aMessage.receiver,
+                                               aMessage.body,
+                                               aMessage.messageClass,
+                                               aMessage.timestamp,
+                                               aMessage.sentTimestamp,
+                                               0,
+                                               aMessage.read);
+
+      notifyReceived(Cr.NS_OK, domMessage);
+    }
+
+    // SMS ACK will be sent in notifyReceived. Return false here.
+    return false;
+  },
+
+  /**
+   * Handle ACK response of received SMS.
+   */
+  _sendAckSms: function(aRv, aMessage, aServiceId) {
+    if (aMessage.messageClass === RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_2]) {
+      return;
+    }
+
+    let result = RIL.PDU_FCS_OK;
+    if (!Components.isSuccessCode(aRv)) {
+      if (DEBUG) debug("Failed to handle received sms: " + aRv);
+      result = (aRv === Cr.NS_ERROR_FILE_NO_DEVICE_SPACE)
+                ? RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED
+                : RIL.PDU_FCS_UNSPECIFIED;
+    }
+
+    gRadioInterfaces[aServiceId]
+      .sendWorkerMessage("ackSMS", { result: result });
+
+  },
+
+  // An array of slient numbers.
+  _silentNumbers: null,
+  _isSilentNumber: function(aNumber) {
+    return this._silentNumbers.indexOf(aNumber) >= 0;
+  },
+
   /**
    * nsISmsService interface
    */
@@ -507,14 +906,8 @@ SmsService.prototype = {
       sendingMessage, saveSendingMessageCallback);
   },
 
-  // An array of slient numbers.
-  _silentNumbers: null,
-  isSilentNumber: function(aNumber) {
-    return this._silentNumbers.indexOf(aNumber) >= 0;
-  },
-
   addSilentNumber: function(aNumber) {
-    if (this.isSilentNumber(aNumber)) {
+    if (this._isSilentNumber(aNumber)) {
       throw Cr.NS_ERROR_UNEXPECTED;
     }
 
@@ -548,8 +941,80 @@ SmsService.prototype = {
   },
 
   /**
-   * TODO: nsIGonkSmsService interface
+   * nsIGonkSmsService interface
    */
+  notifyMessageReceived: function(aServiceId, aSMSC, aSentTimestamp,
+                                  aSender, aPid, aEncoding, aMessageClass,
+                                  aLanguage, aSegmentRef, aSegmentSeq,
+                                  aSegmentMaxSeq, aOriginatorPort,
+                                  aDestinationPort, aMwiPresent, aMwiDiscard,
+                                  aMwiMsgCount, aMwiActive, aCdmaMessageType,
+                                  aCdmaTeleservice, aCdmaServiceCategory,
+                                  aBody, aData, aDataLength) {
+
+    this._acquireSmsHandledWakeLock();
+
+    let segment = {};
+    segment.iccId = this._getIccId(aServiceId);
+    segment.SMSC = aSMSC;
+    segment.sentTimestamp = aSentTimestamp;
+    segment.timestamp = Date.now();
+    segment.sender = aSender;
+    segment.pid = aPid;
+    segment.encoding = aEncoding;
+    segment.messageClass = this._convertSmsMessageClassToString(aMessageClass);
+    segment.language = aLanguage;
+    segment.segmentRef = aSegmentRef;
+    segment.segmentSeq = aSegmentSeq;
+    segment.segmentMaxSeq = aSegmentMaxSeq;
+    segment.originatorPort = aOriginatorPort;
+    segment.destinationPort = aDestinationPort;
+    segment.mwiPresent = aMwiPresent;
+    segment.mwiDiscard = aMwiDiscard;
+    segment.mwiMsgCount = aMwiMsgCount;
+    segment.mwiActive = aMwiActive;
+    segment.messageType = aCdmaMessageType;
+    segment.teleservice = aCdmaTeleservice;
+    segment.serviceCategory = aCdmaServiceCategory;
+    segment.body = aBody;
+    segment.data = (aData && aDataLength > 0) ? aData : null;
+
+    let isMultipart = (segment.segmentMaxSeq && (segment.segmentMaxSeq > 1));
+    let messageClass = segment.messageClass;
+
+    let handleReceivedAndAck = (aRvOfIncompleteMsg, aCompleteMessage) => {
+      if (aCompleteMessage) {
+        this._purgeCompleteSmsMessage(aCompleteMessage);
+        if (this._handleSmsReceived(aCompleteMessage, aServiceId)) {
+          this._sendAckSms(Cr.NS_OK, aCompleteMessage, aServiceId);
+        }
+        // else Ack will be sent after further process in _handleSmsReceived.
+      } else {
+        this._sendAckSms(aRvOfIncompleteMsg, segment, aServiceId);
+      }
+    };
+
+    // No need to access SmsSegmentStore for Class 0 SMS and Single SMS.
+    if (!isMultipart ||
+        (messageClass == RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0])) {
+      // `When a mobile terminated message is class 0 and the MS has the
+      // capability of displaying short messages, the MS shall display the
+      // message immediately and send an acknowledgement to the SC when the
+      // message has successfully reached the MS irrespective of whether
+      // there is memory available in the (U)SIM or ME. The message shall
+      // not be automatically stored in the (U)SIM or ME.`
+      // ~ 3GPP 23.038 clause 4
+
+      handleReceivedAndAck(Cr.NS_OK,  // ACK OK For Incomplete Class 0
+                           this._processReceivedSmsSegment(segment));
+    } else {
+      gMobileMessageDatabaseService
+        .saveSmsSegment(segment, function notifyResult(aRv, aCompleteMessage) {
+        handleReceivedAndAck(aRv,  // Ack according to the result after saving
+                             aCompleteMessage);
+      });
+    }
+  },
 
   /**
    * nsIObserver interface.
@@ -565,6 +1030,8 @@ SmsService.prototype = {
         }
         break;
       case NS_XPCOM_SHUTDOWN_OBSERVER_ID:
+        // Release the CPU wake lock for handling the received SMS.
+        this._releaseSmsHandledWakeLock();
         Services.prefs.removeObserver(kPrefRilDebuggingEnabled, this);
         Services.prefs.removeObserver(kPrefDefaultServiceId, this);
         Services.obs.removeObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
diff --git a/dom/mobilemessage/interfaces/nsIGonkSmsService.idl b/dom/mobilemessage/interfaces/nsIGonkSmsService.idl
index a3c0a53492ea..b57bbd2b84c0 100644
--- a/dom/mobilemessage/interfaces/nsIGonkSmsService.idl
+++ b/dom/mobilemessage/interfaces/nsIGonkSmsService.idl
@@ -2,6 +2,7 @@
  * 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"
 #include "nsISmsService.idl"
 
 %{C++
@@ -9,10 +10,86 @@
         "@mozilla.org/sms/gonksmsservice;1"
 %}
 
-[scriptable, uuid(63fab75e-73b4-11e4-a10d-dbfa9d05a4f4)]
+[scriptable, uuid(4dda515e-05ec-47b1-b750-e42c74576c43)]
 interface nsIGonkSmsService : nsISmsService
 {
+  const unsigned short SMS_MESSAGE_ENCODING_7BITS_ALPHABET = 0x00;
+  const unsigned short SMS_MESSAGE_ENCODING_8BITS_ALPHABET = 0x04;
+  const unsigned short SMS_MESSAGE_ENCODING_16BITS_ALPHABET = 0x08;
+
+  const unsigned long SMS_APPLICATION_PORT_INVALID = 0xFFFFFFFF;
+
   /**
-   * TODO: define callback to receive message from the network.
+   * Called when a short message has been received by the network.
+   *
+   * @param aServiceId
+   *        The ID of the service where this message is received from.
+   * @param aSMSC
+   *        SMS Center address.
+   * @param aSentTimestamp
+   *        The time stamp when message is arrived to SMSC.
+   * @param aSender
+   *        The sender's address of this message.
+   * @param aPid
+   *        Protocol Identifier, See TS 23.040, subcluase 9.2.3.9.
+   *        Set to 0 if invalid.
+   * @param aEncoding
+   *        The encoding of message body.
+   *        SMS_MESSAGE_ENCODING_*.
+   * @param aMessageClass
+   *        A predefined constant of nsISmsService.MESSAGE_CLASS_TYPE_*.
+   * @param aLanguage
+   *        ISO-639-1 language code for this message. Null if unspecified.
+   * @param aSegmentRef, aSegmentSeq, aSegmentMaxSeq
+   *        Concatenation info. See TS 23.040, subclause 9.2.3.24.1.
+   *        All set to 1 if no need for concatenatenation.
+   * @param aOriginatorPort, aDestinationPort
+   *        Application Port Addressing. See TS 23.040 subclause 9.2.3.24.3~4.
+   *        All set to 1 if no need for concatenatenation.
+   * @param aMwiPresent
+   *        True if MWI is presented in this message.
+   * @param aMwiDiscard
+   *        True if MWI has to be discarded after received.
+   * @param aMwiMsgCount
+   *        The number of messages waiting in the voicemail server.
+   *        -1 if number is unknown from the decoded MWI.
+   * @param aMwiActive
+   *        True if there are messages waiting in the voicemail server.
+   * @param aCdmaMessageType
+   *        CDMA SMS Message Type, as defined in 3GPP2 C.S0015-A v2.0, Table 3.4-1
+   *        Set to 0 if invalid.
+   * @param aCdmaTeleservice
+   *        SMS Teleservice Identitifier, as defined in 3GPP2 N.S0005, Table 175.
+   *        Set to 0 if invalid.
+   * @param aCdmaServiceCategory
+   *        CDMA Service Category, 3GPP2 C.R1001-D v2.0, 9.3 Service Category.
+   *        Set to 0 if invalid.
+   * @param aBody
+   *        Text message body.
+   * @param aData
+   *        Binary message body.
    */
-};
\ No newline at end of file
+  void notifyMessageReceived(in unsigned long aServiceId,
+                             in DOMString aSMSC,
+                             in DOMTimeStamp aSentTimestamp,
+                             in DOMString aSender,
+                             in unsigned short aPid,
+                             in unsigned short aEncoding,
+                             in unsigned long aMessageClass,
+                             in DOMString aLanguage,
+                             in unsigned short aSegmentRef,
+                             in unsigned short aSegmentSeq,
+                             in unsigned short aSegmentMaxSeq,
+                             in unsigned long aOriginatorPort,
+                             in unsigned long aDestinationPort,
+                             in boolean aMwiPresent,
+                             in boolean aMwiDiscard,
+                             in short aMwiMsgCount,
+                             in boolean aMwiActive,
+                             in unsigned short aCdmaMessageType,
+                             in unsigned long aCdmaTeleservice,
+                             in unsigned long aCdmaServiceCategory,
+                             in DOMString aBody,
+                             [array, size_is(aDataLength)] in octet aData,
+                             in uint32_t aDataLength);
+};
diff --git a/dom/mobilemessage/interfaces/nsISmsService.idl b/dom/mobilemessage/interfaces/nsISmsService.idl
index 4d33dfa5ee5d..a5320956d2e9 100644
--- a/dom/mobilemessage/interfaces/nsISmsService.idl
+++ b/dom/mobilemessage/interfaces/nsISmsService.idl
@@ -12,7 +12,7 @@ interface nsIMobileMessageCallback;
 #define SMS_SERVICE_CONTRACTID "@mozilla.org/sms/smsservice;1"
 %}
 
-[scriptable, uuid(31626940-73b4-11e4-8b03-1724e1d8a6a1)]
+[scriptable, uuid(ae688bca-00c9-4d08-945d-e8a5272ad5b1)]
 interface nsISmsService : nsISupports
 {
   /**
@@ -52,7 +52,6 @@ interface nsISmsService : nsISupports
             in boolean silent,
             in nsIMobileMessageCallback request);
 
-  boolean isSilentNumber(in DOMString number);
   void addSilentNumber(in DOMString number);
   void removeSilentNumber(in DOMString number);
 
diff --git a/dom/mobilemessage/ipc/SmsIPCService.cpp b/dom/mobilemessage/ipc/SmsIPCService.cpp
index a33316a20db4..d7bfe3627334 100644
--- a/dom/mobilemessage/ipc/SmsIPCService.cpp
+++ b/dom/mobilemessage/ipc/SmsIPCService.cpp
@@ -193,14 +193,6 @@ SmsIPCService::Send(uint32_t aServiceId,
                      aRequest);
 }
 
-NS_IMETHODIMP
-SmsIPCService::IsSilentNumber(const nsAString& aNumber,
-                              bool*            aIsSilent)
-{
-  NS_ERROR("We should not be here!");
-  return NS_ERROR_FAILURE;
-}
-
 NS_IMETHODIMP
 SmsIPCService::AddSilentNumber(const nsAString& aNumber)
 {
diff --git a/dom/system/gonk/RadioInterfaceLayer.js b/dom/system/gonk/RadioInterfaceLayer.js
index a8914b571db9..86227fef5bb3 100644
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -56,13 +56,6 @@ const RILNETWORKINTERFACE_CID =
 
 const NS_XPCOM_SHUTDOWN_OBSERVER_ID      = "xpcom-shutdown";
 const kNetworkConnStateChangedTopic      = "network-connection-state-changed";
-const kSmsReceivedObserverTopic          = "sms-received";
-const kSilentSmsReceivedObserverTopic    = "silent-sms-received";
-const kSmsSendingObserverTopic           = "sms-sending";
-const kSmsSentObserverTopic              = "sms-sent";
-const kSmsFailedObserverTopic            = "sms-failed";
-const kSmsDeliverySuccessObserverTopic   = "sms-delivery-success";
-const kSmsDeliveryErrorObserverTopic     = "sms-delivery-error";
 const kMozSettingsChangedObserverTopic   = "mozsettings-changed";
 const kSysMsgListenerReadyObserverTopic  = "system-message-listener-ready";
 const kSysClockChangeObserverTopic       = "system-clock-change";
@@ -78,13 +71,7 @@ const NS_PREFBRANCH_PREFCHANGE_TOPIC_ID = "nsPref:changed";
 const kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
 const kPrefRilDebuggingEnabled = "ril.debugging.enabled";
 
-const DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED = "received";
-const DOM_MOBILE_MESSAGE_DELIVERY_SENDING  = "sending";
-const DOM_MOBILE_MESSAGE_DELIVERY_SENT     = "sent";
-const DOM_MOBILE_MESSAGE_DELIVERY_ERROR    = "error";
-
 const RADIO_POWER_OFF_TIMEOUT = 30000;
-const SMS_HANDLED_WAKELOCK_TIMEOUT = 5000;
 const HW_DEFAULT_CLIENT_ID = 0;
 
 const INT32_MAX = 2147483647;
@@ -136,10 +123,6 @@ function debug(s) {
   dump("-*- RadioInterfaceLayer: " + s + "\n");
 }
 
-XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
-                                   "@mozilla.org/power/powermanagerservice;1",
-                                   "nsIPowerManagerService");
-
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "@mozilla.org/mobilemessage/mobilemessageservice;1",
                                    "nsIMobileMessageService");
@@ -148,10 +131,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSmsService",
                                    "@mozilla.org/sms/gonksmsservice;1",
                                    "nsIGonkSmsService");
 
-XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
-                                   "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
-                                   "nsIRilMobileMessageDatabaseService");
-
 XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
                                    "@mozilla.org/parentprocessmessagemanager;1",
                                    "nsIMessageBroadcaster");
@@ -160,10 +139,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gSettingsService",
                                    "@mozilla.org/settingsService;1",
                                    "nsISettingsService");
 
-XPCOMUtils.defineLazyServiceGetter(this, "gSystemMessenger",
-                                   "@mozilla.org/system-message-internal;1",
-                                   "nsISystemMessagesInternal");
-
 XPCOMUtils.defineLazyServiceGetter(this, "gNetworkManager",
                                    "@mozilla.org/network/manager;1",
                                    "nsINetworkManager");
@@ -188,10 +163,6 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCellBroadcastService",
                                    "@mozilla.org/cellbroadcast/gonkservice;1",
                                    "nsIGonkCellBroadcastService");
 
-XPCOMUtils.defineLazyServiceGetter(this, "gSmsMessenger",
-                                   "@mozilla.org/ril/system-messenger-helper;1",
-                                   "nsISmsMessenger");
-
 XPCOMUtils.defineLazyServiceGetter(this, "gIccMessenger",
                                    "@mozilla.org/ril/system-messenger-helper;1",
                                    "nsIIccMessenger");
@@ -202,12 +173,6 @@ XPCOMUtils.defineLazyGetter(this, "gStkCmdFactory", function() {
   return stk.StkProactiveCmdFactory;
 });
 
-XPCOMUtils.defineLazyGetter(this, "WAP", function() {
-  let wap = {};
-  Cu.import("resource://gre/modules/WapPushManager.js", wap);
-  return wap;
-});
-
 XPCOMUtils.defineLazyGetter(this, "gMessageManager", function() {
   return {
     QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
@@ -1740,11 +1705,6 @@ function RadioInterface(aClientId, aWorkerMessenger) {
 
   Services.obs.addObserver(this, kNetworkConnStateChangedTopic, false);
 
-  this.portAddressedSmsApps = {};
-  this.portAddressedSmsApps[WAP.WDP_PORT_PUSH] = this.handleSmsWdpPortPush.bind(this);
-
-  this._receivedSmsSegmentsMap = {};
-
   this._sntp = new Sntp(this.setClockBySntp.bind(this),
                         Services.prefs.getIntPref("network.sntp.maxRetryCount"),
                         Services.prefs.getIntPref("network.sntp.refreshPeriod"),
@@ -1772,9 +1732,6 @@ RadioInterface.prototype = {
   },
 
   shutdown: function() {
-    // Release the CPU wake lock for handling the received SMS.
-    this._releaseSmsHandledWakeLock();
-
     Services.obs.removeObserver(this, kMozSettingsChangedObserverTopic);
     Services.obs.removeObserver(this, kSysClockChangeObserverTopic);
     Services.obs.removeObserver(this, kScreenStateChangedTopic);
@@ -1977,7 +1934,7 @@ RadioInterface.prototype = {
                                        this.clientId, message);
         break;
       case "sms-received":
-        this.handleSmsMultipart(message);
+        this.handleSmsReceived(message);
         break;
       case "cellbroadcast-received":
         this.handleCellbroadcastMessageReceived(message);
@@ -2012,58 +1969,6 @@ RadioInterface.prototype = {
     }
   },
 
-  /**
-   * Get phone number from iccInfo.
-   *
-   * If the icc card is gsm card, the phone number is in msisdn.
-   * @see nsIGsmIccInfo
-   *
-   * Otherwise, the phone number is in mdn.
-   * @see nsICdmaIccInfo
-   */
-  getPhoneNumber: function() {
-    let iccInfo = this.rilContext.iccInfo;
-
-    if (!iccInfo) {
-      return null;
-    }
-
-    // After moving SMS code out of RadioInterfaceLayer, we could use
-    // |iccInfo instanceof Ci.nsIGsmIccInfo| here.
-    // TODO: Bug 873351 - B2G SMS: move SMS code out of RadioInterfaceLayer to
-    //                    SmsService
-    let number = (iccInfo instanceof GsmIccInfo) ? iccInfo.msisdn : iccInfo.mdn;
-
-    // Workaround an xpconnect issue with undefined string objects.
-    // See bug 808220
-    if (number === undefined || number === "undefined") {
-      return null;
-    }
-
-    return number;
-  },
-
-  /**
-   * A utility function to get the ICC ID of the SIM card (if installed).
-   */
-  getIccId: function() {
-    let iccInfo = this.rilContext.iccInfo;
-
-    if (!iccInfo) {
-      return null;
-    }
-
-    let iccId = iccInfo.iccid;
-
-    // Workaround an xpconnect issue with undefined string objects.
-    // See bug 808220
-    if (iccId === undefined || iccId === "undefined") {
-      return null;
-    }
-
-    return iccId;
-  },
-
   // Matches the mvnoData pattern with imsi. Characters 'x' and 'X' are skipped
   // and not compared. E.g., if the mvnoData passed is '310260x10xxxxxx',
   // then the function returns true only if imsi has the same first 6 digits,
@@ -2163,506 +2068,64 @@ RadioInterface.prototype = {
   },
 
   /**
-   * Handle WDP port push PDU. Constructor WDP bearer information and deliver
-   * to WapPushManager.
-   *
-   * @param message
-   *        A SMS message.
+   * handle received SMS.
    */
-  handleSmsWdpPortPush: function(message) {
-    if (message.encoding != RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
-      if (DEBUG) {
-        this.debug("Got port addressed SMS but not encoded in 8-bit alphabet." +
-                   " Drop!");
-      }
-      return;
-    }
-
-    let options = {
-      bearer: WAP.WDP_BEARER_GSM_SMS_GSM_MSISDN,
-      sourceAddress: message.sender,
-      sourcePort: message.originatorPort,
-      destinationAddress: this.rilContext.iccInfo.msisdn,
-      destinationPort: message.destinationPort,
-      serviceId: this.clientId
-    };
-    WAP.WapPushManager.receiveWdpPDU(message.fullData, message.fullData.length,
-                                     0, options);
-  },
-
-  _convertSmsMessageClass: function(aMessageClass) {
-    let index = RIL.GECKO_SMS_MESSAGE_CLASSES.indexOf(aMessageClass);
-
-    if (index < 0) {
-      throw new Error("Invalid MessageClass: " + aMessageClass);
-    }
-
-    return index;
-  },
-
-  _convertSmsDelivery: function(aDelivery) {
-    let index = [DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED,
-                 DOM_MOBILE_MESSAGE_DELIVERY_SENDING,
-                 DOM_MOBILE_MESSAGE_DELIVERY_SENT,
-                 DOM_MOBILE_MESSAGE_DELIVERY_ERROR].indexOf(aDelivery);
-
-    if (index < 0) {
-      throw new Error("Invalid Delivery: " + aDelivery);
-    }
-
-    return index;
-  },
-
-  _convertSmsDeliveryStatus: function(aDeliveryStatus) {
-    let index = [RIL.GECKO_SMS_DELIVERY_STATUS_NOT_APPLICABLE,
-                 RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS,
-                 RIL.GECKO_SMS_DELIVERY_STATUS_PENDING,
-                 RIL.GECKO_SMS_DELIVERY_STATUS_ERROR].indexOf(aDeliveryStatus);
-
-    if (index < 0) {
-      throw new Error("Invalid DeliveryStatus: " + aDeliveryStatus);
-    }
-
-    return index;
-  },
-
-  /**
-   * A helper to broadcast the system message to launch registered apps
-   * like Costcontrol, Notification and Message app... etc.
-   *
-   * @param aName
-   *        The system message name.
-   * @param aDomMessage
-   *        The nsIDOMMozSmsMessage object.
-   */
-  broadcastSmsSystemMessage: function(aNotificationType, aDomMessage) {
-    if (DEBUG) this.debug("Broadcasting the SMS system message: " + aNotificationType);
-
-    // Sadly we cannot directly broadcast the aDomMessage object
-    // because the system message mechamism will rewrap the object
-    // based on the content window, which needs to know the properties.
-    try {
-      gSmsMessenger.notifySms(aNotificationType,
-                              aDomMessage.id,
-                              aDomMessage.threadId,
-                              aDomMessage.iccId,
-                              this._convertSmsDelivery(
-                                aDomMessage.delivery),
-                              this._convertSmsDeliveryStatus(
-                                aDomMessage.deliveryStatus),
-                              aDomMessage.sender,
-                              aDomMessage.receiver,
-                              aDomMessage.body,
-                              this._convertSmsMessageClass(
-                                aDomMessage.messageClass),
-                              aDomMessage.timestamp,
-                              aDomMessage.sentTimestamp,
-                              aDomMessage.deliveryTimestamp,
-                              aDomMessage.read);
-    } catch (e) {
-      if (DEBUG) {
-        this.debug("Failed to broadcastSmsSystemMessage: " + e);
-      }
-    }
-  },
-
-  // The following attributes/functions are used for acquiring/releasing the
-  // CPU wake lock when the RIL handles the received SMS. Note that we need
-  // a timer to bound the lock's life cycle to avoid exhausting the battery.
-  _smsHandledWakeLock: null,
-  _smsHandledWakeLockTimer: null,
-
-  _acquireSmsHandledWakeLock: function() {
-    if (!this._smsHandledWakeLock) {
-      if (DEBUG) this.debug("Acquiring a CPU wake lock for handling SMS.");
-      this._smsHandledWakeLock = gPowerManagerService.newWakeLock("cpu");
-    }
-    if (!this._smsHandledWakeLockTimer) {
-      if (DEBUG) this.debug("Creating a timer for releasing the CPU wake lock.");
-      this._smsHandledWakeLockTimer =
-        Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
-    }
-    if (DEBUG) this.debug("Setting the timer for releasing the CPU wake lock.");
-    this._smsHandledWakeLockTimer
-        .initWithCallback(this._releaseSmsHandledWakeLock.bind(this),
-                          SMS_HANDLED_WAKELOCK_TIMEOUT,
-                          Ci.nsITimer.TYPE_ONE_SHOT);
-  },
-
-  _releaseSmsHandledWakeLock: function() {
-    if (DEBUG) this.debug("Releasing the CPU wake lock for handling SMS.");
-    if (this._smsHandledWakeLockTimer) {
-      this._smsHandledWakeLockTimer.cancel();
-    }
-    if (this._smsHandledWakeLock) {
-      this._smsHandledWakeLock.unlock();
-      this._smsHandledWakeLock = null;
-    }
-  },
-
-  /**
-   * Hash map for received multipart sms fragments. Messages are hashed with
-   * its sender address and concatenation reference number. Three additional
-   * attributes `segmentMaxSeq`, `receivedSegments`, `segments` are inserted.
-   */
-  _receivedSmsSegmentsMap: null,
-
-  /**
-   * Helper for processing received multipart SMS.
-   *
-   * @return null for handled segments, and an object containing full message
-   *         body/data once all segments are received.
-   */
-  _processReceivedSmsSegment: function(aSegment) {
-
-    // Directly replace full message body for single SMS.
-    if (!(aSegment.segmentMaxSeq && (aSegment.segmentMaxSeq > 1))) {
-      if (aSegment.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
-        aSegment.fullData = aSegment.data;
-      } else {
-        aSegment.fullBody = aSegment.body;
-      }
-      return aSegment;
-    }
-
-    // Handle Concatenation for Class 0 SMS
-    let hash = aSegment.sender + ":" +
-               aSegment.segmentRef + ":" +
-               aSegment.segmentMaxSeq;
-    let seq = aSegment.segmentSeq;
-
-    let options = this._receivedSmsSegmentsMap[hash];
-    if (!options) {
-      options = aSegment;
-      this._receivedSmsSegmentsMap[hash] = options;
-
-      options.receivedSegments = 0;
-      options.segments = [];
-    } else if (options.segments[seq]) {
-      // Duplicated segment?
-      if (DEBUG) {
-        this.debug("Got duplicated segment no." + seq +
-                           " of a multipart SMS: " + JSON.stringify(aSegment));
-      }
-      return null;
-    }
-
-    if (options.receivedSegments > 0) {
-      // Update received timestamp.
-      options.timestamp = aSegment.timestamp;
-    }
-
-    if (options.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
-      options.segments[seq] = aSegment.data;
-    } else {
-      options.segments[seq] = aSegment.body;
-    }
-    options.receivedSegments++;
-
-    // The port information is only available in 1st segment for CDMA WAP Push.
-    // If the segments of a WAP Push are not received in sequence
-    // (e.g., SMS with seq == 1 is not the 1st segment received by the device),
-    // we have to retrieve the port information from 1st segment and
-    // save it into the cached options.
-    if (aSegment.teleservice === RIL.PDU_CDMA_MSG_TELESERIVCIE_ID_WAP
-        && seq === 1) {
-      if (!options.originatorPort && aSegment.originatorPort) {
-        options.originatorPort = aSegment.originatorPort;
-      }
-
-      if (!options.destinationPort && aSegment.destinationPort) {
-        options.destinationPort = aSegment.destinationPort;
-      }
-    }
-
-    if (options.receivedSegments < options.segmentMaxSeq) {
-      if (DEBUG) {
-        this.debug("Got segment no." + seq + " of a multipart SMS: " +
-                           JSON.stringify(options));
-      }
-      return null;
-    }
-
-    // Remove from map
-    delete this._receivedSmsSegmentsMap[hash];
-
-    // Rebuild full body
-    if (options.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
-      // Uint8Array doesn't have `concat`, so we have to merge all segements
-      // by hand.
-      let fullDataLen = 0;
-      for (let i = 1; i <= options.segmentMaxSeq; i++) {
-        fullDataLen += options.segments[i].length;
-      }
-
-      options.fullData = new Uint8Array(fullDataLen);
-      for (let d= 0, i = 1; i <= options.segmentMaxSeq; i++) {
-        let data = options.segments[i];
-        for (let j = 0; j < data.length; j++) {
-          options.fullData[d++] = data[j];
-        }
-      }
-    } else {
-      options.fullBody = options.segments.join("");
-    }
-
-    // Remove handy fields after completing the concatenation.
-    delete options.receivedSegments;
-    delete options.segments;
-
-    if (DEBUG) {
-      this.debug("Got full multipart SMS: " + JSON.stringify(options));
-    }
-
-    return options;
-  },
-
-  /**
-   * Helper to create Savable SmsSegment.
-   */
-  _createSavableSmsSegment: function(aMessage) {
-    // We precisely define what data fields to be stored into
-    // DB here for better data migration.
-    let segment = {};
-    segment.messageType = aMessage.messageType;
-    segment.teleservice = aMessage.teleservice;
-    segment.SMSC = aMessage.SMSC;
-    segment.sentTimestamp = aMessage.sentTimestamp;
-    segment.timestamp = Date.now();
-    segment.sender = aMessage.sender;
-    segment.pid = aMessage.pid;
-    segment.encoding = aMessage.encoding;
-    segment.messageClass = aMessage.messageClass;
-    segment.iccId = this.getIccId();
-    if (aMessage.header) {
-      segment.segmentRef = aMessage.header.segmentRef;
-      segment.segmentSeq = aMessage.header.segmentSeq;
-      segment.segmentMaxSeq = aMessage.header.segmentMaxSeq;
-      segment.originatorPort = aMessage.header.originatorPort;
-      segment.destinationPort = aMessage.header.destinationPort;
-    }
-    segment.mwiPresent = (aMessage.mwi)? true: false;
-    segment.mwiDiscard = (segment.mwiPresent)? aMessage.mwi.discard: false;
-    segment.mwiMsgCount = (segment.mwiPresent)? aMessage.mwi.msgCount: 0;
-    segment.mwiActive = (segment.mwiPresent)? aMessage.mwi.active: false;
-    segment.serviceCategory = aMessage.serviceCategory;
-    segment.language = aMessage.language;
-    segment.data = aMessage.data;
-    segment.body = aMessage.body;
-
-    return segment;
-  },
-
-  /**
-   * Helper to purge complete message.
-   *
-   * We remove unnessary fields defined in _createSavableSmsSegment() after
-   * completing the concatenation.
-   */
-  _purgeCompleteSmsMessage: function(aMessage) {
-    // Purge concatenation info
-    delete aMessage.segmentRef;
-    delete aMessage.segmentSeq;
-    delete aMessage.segmentMaxSeq;
-
-    // Purge partial message body
-    delete aMessage.data;
-    delete aMessage.body;
-  },
-
-  /**
-   * handle concatenation of received SMS.
-   */
-  handleSmsMultipart: function(aMessage) {
-    if (DEBUG) this.debug("handleSmsMultipart: " + JSON.stringify(aMessage));
-
-    this._acquireSmsHandledWakeLock();
-
-    let segment = this._createSavableSmsSegment(aMessage);
-
-    let isMultipart = (segment.segmentMaxSeq && (segment.segmentMaxSeq > 1));
-    let messageClass = segment.messageClass;
-
-    let handleReceivedAndAck = function(aRvOfIncompleteMsg, aCompleteMessage) {
-      if (aCompleteMessage) {
-        this._purgeCompleteSmsMessage(aCompleteMessage);
-        if (this.handleSmsReceived(aCompleteMessage)) {
-          this.sendAckSms(Cr.NS_OK, aCompleteMessage);
-        }
-        // else Ack will be sent after further process in handleSmsReceived.
-      } else {
-        this.sendAckSms(aRvOfIncompleteMsg, segment);
-      }
-    }.bind(this);
-
-    // No need to access SmsSegmentStore for Class 0 SMS and Single SMS.
-    if (!isMultipart ||
-        (messageClass == RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0])) {
-      // `When a mobile terminated message is class 0 and the MS has the
-      // capability of displaying short messages, the MS shall display the
-      // message immediately and send an acknowledgement to the SC when the
-      // message has successfully reached the MS irrespective of whether
-      // there is memory available in the (U)SIM or ME. The message shall
-      // not be automatically stored in the (U)SIM or ME.`
-      // ~ 3GPP 23.038 clause 4
-
-      handleReceivedAndAck(Cr.NS_OK,  // ACK OK For Incomplete Class 0
-                           this._processReceivedSmsSegment(segment));
-    } else {
-      gMobileMessageDatabaseService
-        .saveSmsSegment(segment, function notifyResult(aRv, aCompleteMessage) {
-        handleReceivedAndAck(aRv,  // Ack according to the result after saving
-                             aCompleteMessage);
-      });
-    }
-  },
-
-  portAddressedSmsApps: null,
-  handleSmsReceived: function(message) {
-    if (DEBUG) this.debug("handleSmsReceived: " + JSON.stringify(message));
-
-    if (message.messageType == RIL.PDU_CDMA_MSG_TYPE_BROADCAST) {
-      this.handleCellbroadcastMessageReceived(message);
-      return true;
-    }
-
-    // Dispatch to registered handler if application port addressing is
-    // available. Note that the destination port can possibly be zero when
-    // representing a UDP/TCP port.
-    if (message.destinationPort != null) {
-      let handler = this.portAddressedSmsApps[message.destinationPort];
-      if (handler) {
-        handler(message);
-      }
-      return true;
-    }
-
-    if (message.encoding == RIL.PDU_DCS_MSG_CODING_8BITS_ALPHABET) {
-      // Don't know how to handle binary data yet.
-      return true;
-    }
-
-    message.type = "sms";
-    message.sender = message.sender || null;
-    message.receiver = this.getPhoneNumber();
-    message.body = message.fullBody = message.fullBody || null;
-
-    if (gSmsService.isSilentNumber(message.sender)) {
-      message.id = -1;
-      message.threadId = 0;
-      message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
-      message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
-      message.read = false;
-
-      let domMessage =
-        gMobileMessageService.createSmsMessage(message.id,
-                                               message.threadId,
-                                               message.iccId,
-                                               message.delivery,
-                                               message.deliveryStatus,
-                                               message.sender,
-                                               message.receiver,
-                                               message.body,
-                                               message.messageClass,
-                                               message.timestamp,
-                                               message.sentTimestamp,
-                                               0,
-                                               message.read);
-
-      Services.obs.notifyObservers(domMessage,
-                                   kSilentSmsReceivedObserverTopic,
-                                   null);
-      return true;
-    }
-
-    if (message.mwiPresent) {
-      let mwi = {
-        discard: message.mwiDiscard,
-        msgCount: message.mwiMsgCount,
-        active: message.mwiActive
-      };
-      this.workerMessenger.send("updateMwis", { mwi: mwi });
-
-      mwi.returnNumber = message.sender;
-      mwi.returnMessage = message.fullBody;
-      this.handleIccMwis(mwi);
-
-      // Dicarded MWI comes without text body.
-      // Hence, we discard it here after notifying the MWI status.
-      if (message.mwiDiscard) {
-        return true;
-      }
-    }
-
-    let notifyReceived = function notifyReceived(rv, domMessage) {
-      let success = Components.isSuccessCode(rv);
-
-      this.sendAckSms(rv, message);
-
-      if (!success) {
-        // At this point we could send a message to content to notify the user
-        // that storing an incoming SMS failed, most likely due to a full disk.
-        if (DEBUG) {
-          this.debug("Could not store SMS, error code " + rv);
-        }
-        return;
-      }
-
-      this.broadcastSmsSystemMessage(
-        Ci.nsISmsMessenger.NOTIFICATION_TYPE_RECEIVED, domMessage);
-      Services.obs.notifyObservers(domMessage, kSmsReceivedObserverTopic, null);
-    }.bind(this);
-
-    if (message.messageClass != RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_0]) {
-      gMobileMessageDatabaseService.saveReceivedMessage(message,
-                                                        notifyReceived);
-    } else {
-      message.id = -1;
-      message.threadId = 0;
-      message.delivery = DOM_MOBILE_MESSAGE_DELIVERY_RECEIVED;
-      message.deliveryStatus = RIL.GECKO_SMS_DELIVERY_STATUS_SUCCESS;
-      message.read = false;
-
-      let domMessage =
-        gMobileMessageService.createSmsMessage(message.id,
-                                               message.threadId,
-                                               message.iccId,
-                                               message.delivery,
-                                               message.deliveryStatus,
-                                               message.sender,
-                                               message.receiver,
-                                               message.body,
-                                               message.messageClass,
-                                               message.timestamp,
-                                               message.sentTimestamp,
-                                               0,
-                                               message.read);
-
-      notifyReceived(Cr.NS_OK, domMessage);
-    }
-
-    // SMS ACK will be sent in notifyReceived. Return false here.
-    return false;
-  },
-
-  /**
-   * Handle ACK response of received SMS.
-   */
-  sendAckSms: function(aRv, aMessage) {
-    if (aMessage.messageClass === RIL.GECKO_SMS_MESSAGE_CLASSES[RIL.PDU_DCS_MSG_CLASS_2]) {
-      return;
-    }
-
-    let result = RIL.PDU_FCS_OK;
-    if (!Components.isSuccessCode(aRv)) {
-      if (DEBUG) this.debug("Failed to handle received sms: " + aRv);
-      result = (aRv === Cr.NS_ERROR_FILE_NO_DEVICE_SPACE)
-                ? RIL.PDU_FCS_MEMORY_CAPACITY_EXCEEDED
-                : RIL.PDU_FCS_UNSPECIFIED;
-    }
-
-    this.workerMessenger.send("ackSMS", { result: result });
-
+  handleSmsReceived: function(aMessage) {
+    let header = aMessage.header;
+    // Concatenation Info:
+    // - segmentRef: a modulo 256 counter indicating the reference number for a
+    //               particular concatenated short message. '0' is a valid number.
+    // - The concatenation info will not be available in |header| if
+    //   segmentSeq or segmentMaxSeq is 0.
+    // See 3GPP TS 23.040, 9.2.3.24.1 Concatenated Short Messages.
+    let segmentRef = (header && header.segmentRef !== undefined)
+      ? header.segmentRef : 1;
+    let segmentSeq = header && header.segmentSeq || 1;
+    let segmentMaxSeq = header && header.segmentMaxSeq || 1;
+    // Application Ports:
+    // The port number ranges from 0 to 49151.
+    // see 3GPP TS 23.040, 9.2.3.24.3/4 Application Port Addressing.
+    let originatorPort = (header && header.originatorPort !== undefined)
+      ? header.originatorPort
+      : Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID;
+    let destinationPort = (header && header.destinationPort !== undefined)
+      ? header.destinationPort
+      : Ci.nsIGonkSmsService.SMS_APPLICATION_PORT_INVALID;
+    // MWI info:
+    let mwiPresent = (aMessage.mwi)? true : false;
+    let mwiDiscard = (mwiPresent)? aMessage.mwi.discard: false;
+    let mwiMsgCount = (mwiPresent)? aMessage.mwi.msgCount: 0;
+    let mwiActive = (mwiPresent)? aMessage.mwi.active: false;
+    // CDMA related attributes:
+    let cdmaMessageType = aMessage.messageType || 0;
+    let cdmaTeleservice = aMessage.teleservice || 0;
+    let cdmaServiceCategory = aMessage.serviceCategory || 0;
+
+    gSmsService
+      .notifyMessageReceived(this.clientId,
+                             aMessage.SMSC || null,
+                             aMessage.sentTimestamp,
+                             aMessage.sender,
+                             aMessage.pid,
+                             aMessage.encoding,
+                             RIL.GECKO_SMS_MESSAGE_CLASSES
+                               .indexOf(aMessage.messageClass),
+                             aMessage.language || null,
+                             segmentRef,
+                             segmentSeq,
+                             segmentMaxSeq,
+                             originatorPort,
+                             destinationPort,
+                             mwiPresent,
+                             mwiDiscard,
+                             mwiMsgCount,
+                             mwiActive,
+                             cdmaMessageType,
+                             cdmaTeleservice,
+                             cdmaServiceCategory,
+                             aMessage.body || null,
+                             aMessage.data || [],
+                             (aMessage.data) ? aMessage.data.length : 0);
   },
 
   /**
@@ -2756,8 +2219,9 @@ RadioInterface.prototype = {
   handleIccMwis: function(mwi) {
     let service = Cc["@mozilla.org/voicemail/voicemailservice;1"]
                   .getService(Ci.nsIGonkVoicemailService);
+    // Note: returnNumber and returnMessage is not available from UICC.
     service.notifyStatusChanged(this.clientId, mwi.active, mwi.msgCount,
-                                mwi.returnNumber, mwi.returnMessage);
+                                null, null);
   },
 
   handleIccInfoChange: function(message) {

From 28ab63d671cfe2f37c0f9e59ed458bec97adcc13 Mon Sep 17 00:00:00 2001
From: Bevis Tseng 
Date: Wed, 10 Dec 2014 15:30:59 +0800
Subject: [PATCH 133/183] Bug 1108900 - Part 1: rename
 MobileMessageDatabaseService. r=echen

--HG--
rename : dom/mobilemessage/interfaces/nsIRilMobileMessageDatabaseService.idl => dom/mobilemessage/interfaces/nsIGonkMobileMessageDatabaseService.idl
---
 dom/mobilemessage/MobileMessageManager.cpp    |  4 +-
 dom/mobilemessage/gonk/MmsService.js          |  4 +-
 dom/mobilemessage/gonk/MobileMessageDB.jsm    |  2 +-
 .../gonk/MobileMessageDatabaseService.js      | 14 ++---
 .../MobileMessageDatabaseService.manifest     |  6 +--
 dom/mobilemessage/gonk/SmsService.js          |  4 +-
 dom/mobilemessage/interfaces/moz.build        |  2 +-
 ...> nsIGonkMobileMessageDatabaseService.idl} | 52 +++++++++----------
 .../tests/marionette/mmdb_head.js             |  4 +-
 .../test_error_of_mms_manual_retrieval.js     |  4 +-
 10 files changed, 48 insertions(+), 48 deletions(-)
 rename dom/mobilemessage/interfaces/{nsIRilMobileMessageDatabaseService.idl => nsIGonkMobileMessageDatabaseService.idl} (71%)

diff --git a/dom/mobilemessage/MobileMessageManager.cpp b/dom/mobilemessage/MobileMessageManager.cpp
index 6b1238f4bada..7357164ea291 100644
--- a/dom/mobilemessage/MobileMessageManager.cpp
+++ b/dom/mobilemessage/MobileMessageManager.cpp
@@ -35,7 +35,7 @@
 #include "android/MobileMessageDatabaseService.h"
 #include "android/SmsService.h"
 #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-#include "nsIRilMobileMessageDatabaseService.h"
+#include "nsIGonkMobileMessageDatabaseService.h"
 #include "nsIGonkSmsService.h"
 #endif
 #include "nsXULAppAPI.h" // For XRE_GetProcessType()
@@ -729,7 +729,7 @@ NS_CreateMobileMessageDatabaseService()
     mobileMessageDBService = new MobileMessageDatabaseService();
 #elif defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
     mobileMessageDBService =
-      do_CreateInstance(RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
+      do_CreateInstance(GONK_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID);
 #endif
   }
 
diff --git a/dom/mobilemessage/gonk/MmsService.js b/dom/mobilemessage/gonk/MmsService.js
index d488cad2f904..042762d130bd 100644
--- a/dom/mobilemessage/gonk/MmsService.js
+++ b/dom/mobilemessage/gonk/MmsService.js
@@ -144,8 +144,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator",
                                    "nsIUUIDGenerator");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
-                                   "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
-                                   "nsIRilMobileMessageDatabaseService");
+                                   "@mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1",
+                                   "nsIGonkMobileMessageDatabaseService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "@mozilla.org/mobilemessage/mobilemessageservice;1",
diff --git a/dom/mobilemessage/gonk/MobileMessageDB.jsm b/dom/mobilemessage/gonk/MobileMessageDB.jsm
index 55e7dce599ea..a8fd33c54643 100644
--- a/dom/mobilemessage/gonk/MobileMessageDB.jsm
+++ b/dom/mobilemessage/gonk/MobileMessageDB.jsm
@@ -2559,7 +2559,7 @@ MobileMessageDB.prototype = {
   },
 
   /**
-   * nsIRilMobileMessageDatabaseService API
+   * nsIGonkMobileMessageDatabaseService API
    */
 
   saveReceivedMessage: function(aMessage, aCallback) {
diff --git a/dom/mobilemessage/gonk/MobileMessageDatabaseService.js b/dom/mobilemessage/gonk/MobileMessageDatabaseService.js
index 0b10153aadbc..9ca19e57de62 100644
--- a/dom/mobilemessage/gonk/MobileMessageDatabaseService.js
+++ b/dom/mobilemessage/gonk/MobileMessageDatabaseService.js
@@ -12,10 +12,10 @@ Cu.import("resource://gre/modules/Services.jsm");
 let MMDB = {};
 Cu.import("resource://gre/modules/MobileMessageDB.jsm", MMDB);
 
-const RIL_MOBILEMESSAGEDATABASESERVICE_CONTRACTID =
-  "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1";
-const RIL_MOBILEMESSAGEDATABASESERVICE_CID =
-  Components.ID("{29785f90-6b5b-11e2-9201-3b280170b2ec}");
+const GONK_MOBILEMESSAGEDATABASESERVICE_CONTRACTID =
+  "@mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1";
+const GONK_MOBILEMESSAGEDATABASESERVICE_CID =
+  Components.ID("{7db05024-8038-11e4-b7fa-a3edb6f1bf0c}");
 
 const DB_NAME = "sms";
 
@@ -33,8 +33,8 @@ function MobileMessageDatabaseService() {
 }
 MobileMessageDatabaseService.prototype = {
 
-  classID: RIL_MOBILEMESSAGEDATABASESERVICE_CID,
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsIRilMobileMessageDatabaseService,
+  classID: GONK_MOBILEMESSAGEDATABASESERVICE_CID,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIGonkMobileMessageDatabaseService,
                                          Ci.nsIMobileMessageDatabaseService,
                                          Ci.nsIObserver]),
 
@@ -49,7 +49,7 @@ MobileMessageDatabaseService.prototype = {
   observe: function() {},
 
   /**
-   * nsIRilMobileMessageDatabaseService API
+   * nsIGonkMobileMessageDatabaseService API
    */
 
   saveReceivedMessage: function(aMessage, aCallback) {
diff --git a/dom/mobilemessage/gonk/MobileMessageDatabaseService.manifest b/dom/mobilemessage/gonk/MobileMessageDatabaseService.manifest
index e398b403b397..d5b9af315813 100644
--- a/dom/mobilemessage/gonk/MobileMessageDatabaseService.manifest
+++ b/dom/mobilemessage/gonk/MobileMessageDatabaseService.manifest
@@ -1,3 +1,3 @@
-component {29785f90-6b5b-11e2-9201-3b280170b2ec} MobileMessageDatabaseService.js
-contract @mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1 {29785f90-6b5b-11e2-9201-3b280170b2ec}
-category profile-after-change MobileMessageDatabaseService @mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1
+component {7db05024-8038-11e4-b7fa-a3edb6f1bf0c} MobileMessageDatabaseService.js
+contract @mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1 {7db05024-8038-11e4-b7fa-a3edb6f1bf0c}
+category profile-after-change MobileMessageDatabaseService @mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1
diff --git a/dom/mobilemessage/gonk/SmsService.js b/dom/mobilemessage/gonk/SmsService.js
index 362717d8043d..dd85b4d4a14a 100644
--- a/dom/mobilemessage/gonk/SmsService.js
+++ b/dom/mobilemessage/gonk/SmsService.js
@@ -74,8 +74,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileConnectionService",
                                    "nsIMobileConnectionService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageDatabaseService",
-                                   "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1",
-                                   "nsIRilMobileMessageDatabaseService");
+                                   "@mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1",
+                                   "nsIGonkMobileMessageDatabaseService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "@mozilla.org/mobilemessage/mobilemessageservice;1",
diff --git a/dom/mobilemessage/interfaces/moz.build b/dom/mobilemessage/interfaces/moz.build
index dd7cedfd9bfc..64dca0732a2c 100644
--- a/dom/mobilemessage/interfaces/moz.build
+++ b/dom/mobilemessage/interfaces/moz.build
@@ -20,8 +20,8 @@ XPIDL_SOURCES += [
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
     XPIDL_SOURCES += [
+        'nsIGonkMobileMessageDatabaseService.idl',
         'nsIGonkSmsService.idl',
-        'nsIRilMobileMessageDatabaseService.idl',
         'nsISmsMessenger.idl',
     ]
 
diff --git a/dom/mobilemessage/interfaces/nsIRilMobileMessageDatabaseService.idl b/dom/mobilemessage/interfaces/nsIGonkMobileMessageDatabaseService.idl
similarity index 71%
rename from dom/mobilemessage/interfaces/nsIRilMobileMessageDatabaseService.idl
rename to dom/mobilemessage/interfaces/nsIGonkMobileMessageDatabaseService.idl
index e708f1dcc04b..5765a9b0e84e 100644
--- a/dom/mobilemessage/interfaces/nsIRilMobileMessageDatabaseService.idl
+++ b/dom/mobilemessage/interfaces/nsIGonkMobileMessageDatabaseService.idl
@@ -6,8 +6,8 @@
 #include "nsISupports.idl"
 #include "nsIMobileMessageDatabaseService.idl"
 
-[scriptable, function, uuid(92986322-8d56-11e2-8816-73a531c493c2)]
-interface nsIRilMobileMessageDatabaseCallback : nsISupports
+[scriptable, function, uuid(2ae081ac-8038-11e4-a472-1ba11eb89d79)]
+interface nsIGonkMobileMessageDatabaseCallback : nsISupports
 {
   /**
    * |aDomMessage|: the nsIDOMMoz{Mms,Sms}Message
@@ -15,8 +15,8 @@ interface nsIRilMobileMessageDatabaseCallback : nsISupports
   void notify(in nsresult aRv, in nsISupports aDomMessage);
 };
 
-[scriptable, function, uuid(32b02bbe-60a1-45e0-a748-ad40709b09dd)]
-interface nsIRilMobileMessageDatabaseRecordCallback : nsISupports
+[scriptable, function, uuid(2f7a6fde-8038-11e4-9d93-5b9ffba492fb)]
+interface nsIGonkMobileMessageDatabaseRecordCallback : nsISupports
 {
   /**
    * |aMessageRecord| Object: the mobile-message database record
@@ -25,8 +25,8 @@ interface nsIRilMobileMessageDatabaseRecordCallback : nsISupports
   void notify(in nsresult aRv, in jsval aMessageRecord, in nsISupports aDomMessage);
 };
 
-[scriptable, function, uuid(1b0ff03c-a2bc-11e3-a443-838d034c9805)]
-interface nsIRilMobileMessageDatabaseConcatenationCallback : nsISupports
+[scriptable, function, uuid(36f9732c-8038-11e4-b634-3f7e3df5232a)]
+interface nsIGonkMobileMessageDatabaseConcatenationCallback : nsISupports
 {
   /**
    * |aCompleteMessage|: jsval: the completely concatenated message. Noted, this value might be null.
@@ -35,14 +35,14 @@ interface nsIRilMobileMessageDatabaseConcatenationCallback : nsISupports
 };
 
 %{C++
-#define RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CID \
-  { 0x29785f90, 0x6b5b, 0x11e2, { 0x92, 0x01, 0x3b, 0x28, 0x01, 0x70, 0xb2, 0xec } }
-#define RIL_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID \
-  "@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1"
+#define GONK_MOBILE_MESSAGE_DATABASE_SERVICE_CID \
+  { 0x7db05024, 0x8038, 0x11e4, { 0xb7, 0xfa, 0xa3, 0xed, 0xb6, 0xf1, 0xbf, 0x0c } }
+#define GONK_MOBILE_MESSAGE_DATABASE_SERVICE_CONTRACTID \
+  "@mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1"
 %}
 
-[scriptable, uuid(0b437a5c-a2bc-11e3-bd1b-dbb173eb35f8)]
-interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
+[scriptable, uuid(48a3c28a-8038-11e4-b7b9-0f2df5b53100)]
+interface nsIGonkMobileMessageDatabaseService : nsIMobileMessageDatabaseService
 {
   /**
    * |aMessage| Object: should contain the following properties for internal use:
@@ -64,7 +64,7 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
    *     - |phoneNumber| DOMString: [optional] my own phone number.
    */
   void saveReceivedMessage(in jsval aMessage,
-                [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+                [optional] in nsIGonkMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aMessage| Object: should contain the following properties for internal use:
@@ -81,7 +81,7 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
    *     - |receivers| DOMString Array: the phone numbers of receivers
    */
   void saveSendingMessage(in jsval aMessage,
-               [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+               [optional] in nsIGonkMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aMessageId| Number: the message's DB record ID.
@@ -89,52 +89,52 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
    * |aDelivery| DOMString: the new delivery value to update (can be null).
    * |aDeliveryStatus| DOMString: the new delivery status to update (can be null).
    * |aEnvelopeId| DOMString: the "message-id" specified in the MMS PDU headers.
-   * |aCallback| nsIRilMobileMessageDatabaseCallback: an optional callback.
+   * |aCallback| nsIGonkMobileMessageDatabaseCallback: an optional callback.
    */
   void setMessageDeliveryByMessageId(in long aMessageId,
                                      in DOMString aReceiver,
                                      in DOMString aDelivery,
                                      in DOMString aDeliveryStatus,
                                      in DOMString aEnvelopeId,
-                          [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+                          [optional] in nsIGonkMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aEnvelopeId| DOMString: the "message-id" specified in the MMS PDU headers.
    * |aReceiver| DOMString: the phone number of receiver (for MMS; can be null).
    * |aDeliveryStatus| DOMString: the new delivery status to be updated (can be null).
-   * |aCallback| nsIRilMobileMessageDatabaseCallback: an optional callback.
+   * |aCallback| nsIGonkMobileMessageDatabaseCallback: an optional callback.
    */
   void setMessageDeliveryStatusByEnvelopeId(in DOMString aEnvelopeId,
                                             in DOMString aReceiver,
                                             in DOMString aDeliveryStatus,
-                                 [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+                                 [optional] in nsIGonkMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aEnvelopeId| DOMString: the "message-id" specified in the MMS PDU headers.
    * |aReceiver| DOMString: the phone number of receiver (for MMS; can be null).
    * |aReadStatus| DOMString: the new read status to be updated.
-   * |aCallback| nsIRilMobileMessageDatabaseCallback: an optional callback.
+   * |aCallback| nsIGonkMobileMessageDatabaseCallback: an optional callback.
    */
   void setMessageReadStatusByEnvelopeId(in DOMString aEnvelopeId,
                                         in DOMString aReceiver,
                                         in DOMString aReadStatus,
-                             [optional] in nsIRilMobileMessageDatabaseCallback aCallback);
+                             [optional] in nsIGonkMobileMessageDatabaseCallback aCallback);
 
   /**
    * |aMessageId| Number: the message's DB record ID.
-   * |aCallback| nsIRilMobileMessageDatabaseRecordCallback: a callback which
+   * |aCallback| nsIGonkMobileMessageDatabaseRecordCallback: a callback which
    *   takes result flag, message record and domMessage as parameters.
    */
   void getMessageRecordById(in long aMessageId,
-                            in nsIRilMobileMessageDatabaseRecordCallback aCallback);
+                            in nsIGonkMobileMessageDatabaseRecordCallback aCallback);
 
   /**
    * |aTransactionId| DOMString: the transaction ID of MMS PDU.
-   * |aCallback| nsIRilMobileMessageDatabaseRecordCallback: a callback which
+   * |aCallback| nsIGonkMobileMessageDatabaseRecordCallback: a callback which
    *   takes result flag and message record as parameters.
    */
   void getMessageRecordByTransactionId(in DOMString aTransactionId,
-                                       in nsIRilMobileMessageDatabaseRecordCallback aCallback);
+                                       in nsIGonkMobileMessageDatabaseRecordCallback aCallback);
 
   /**
    * |aCrError| nsresult: the NS_ERROR defined in Components.results.
@@ -145,9 +145,9 @@ interface nsIRilMobileMessageDatabaseService : nsIMobileMessageDatabaseService
 
   /**
    * |aSmsSegment| jsval: Decoded Single SMS PDU.
-   * |aCallback| nsIRilMobileMessageDatabaseConcatenationCallback: a callback which
+   * |aCallback| nsIGonkMobileMessageDatabaseConcatenationCallback: a callback which
    *   takes result flag, and complete mesage as parameters.
    */
   void saveSmsSegment(in jsval aSmsSegment,
-                      in nsIRilMobileMessageDatabaseConcatenationCallback aCallback);
+                      in nsIGonkMobileMessageDatabaseConcatenationCallback aCallback);
 };
diff --git a/dom/mobilemessage/tests/marionette/mmdb_head.js b/dom/mobilemessage/tests/marionette/mmdb_head.js
index f6ace2c4cade..cc77643174a1 100644
--- a/dom/mobilemessage/tests/marionette/mmdb_head.js
+++ b/dom/mobilemessage/tests/marionette/mmdb_head.js
@@ -73,8 +73,8 @@ function closeMobileMessageDB(aMmdb) {
 
 /**
  * Utility function for calling MMDB methods that takes either a
- * nsIRilMobileMessageDatabaseCallback or a
- * nsIRilMobileMessageDatabaseRecordCallback.
+ * nsIGonkMobileMessageDatabaseCallback or a
+ * nsIGonkMobileMessageDatabaseRecordCallback.
  *
  * Resolve when the target method notifies us with a successful result code;
  * reject otherwise. In either case, the arguments passed are packed into an
diff --git a/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js b/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
index 5c6f25d105fe..4ad692405c2e 100644
--- a/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
+++ b/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
@@ -13,8 +13,8 @@ let MMS = {};
 Cu.import("resource://gre/modules/MmsPduHelper.jsm", MMS);
 
 let gMobileMessageDatabaseService =
-  Cc["@mozilla.org/mobilemessage/rilmobilemessagedatabaseservice;1"]
-    .getService(Ci.nsIRilMobileMessageDatabaseService);
+  Cc["@mozilla.org/mobilemessage/gonkmobilemessagedatabaseservice;1"]
+    .getService(Ci.nsIGonkMobileMessageDatabaseService);
 
 let gUuidGenerator =
   Cc["@mozilla.org/uuid-generator;1"]

From 7e09d18454ec99bd662d0b0124fd623859bfcf11 Mon Sep 17 00:00:00 2001
From: Bevis Tseng 
Date: Wed, 10 Dec 2014 16:14:19 +0800
Subject: [PATCH 134/183] Bug 1108900 - Part 2: rename MmsService. r=echen

---
 dom/mobilemessage/MobileMessageManager.cpp                  | 2 +-
 dom/mobilemessage/gonk/MmsService.js                        | 6 +++---
 dom/mobilemessage/gonk/MmsService.manifest                  | 4 ++--
 dom/mobilemessage/gonk/MobileMessageDB.jsm                  | 2 +-
 .../tests/marionette/test_error_of_mms_manual_retrieval.js  | 2 +-
 dom/wappush/gonk/WapPushManager.js                          | 2 +-
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/dom/mobilemessage/MobileMessageManager.cpp b/dom/mobilemessage/MobileMessageManager.cpp
index 7357164ea291..9e95e2732225 100644
--- a/dom/mobilemessage/MobileMessageManager.cpp
+++ b/dom/mobilemessage/MobileMessageManager.cpp
@@ -745,7 +745,7 @@ NS_CreateMmsService()
     mmsService = SmsIPCService::GetSingleton();
   } else {
 #if defined(MOZ_WIDGET_GONK) && defined(MOZ_B2G_RIL)
-    mmsService = do_CreateInstance("@mozilla.org/mms/rilmmsservice;1");
+    mmsService = do_CreateInstance("@mozilla.org/mms/gonkmmsservice;1");
 #endif
   }
 
diff --git a/dom/mobilemessage/gonk/MmsService.js b/dom/mobilemessage/gonk/MmsService.js
index 042762d130bd..0256b9154799 100644
--- a/dom/mobilemessage/gonk/MmsService.js
+++ b/dom/mobilemessage/gonk/MmsService.js
@@ -13,8 +13,8 @@ Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
 Cu.import("resource://gre/modules/Promise.jsm");
 
-const RIL_MMSSERVICE_CONTRACTID = "@mozilla.org/mms/rilmmsservice;1";
-const RIL_MMSSERVICE_CID = Components.ID("{217ddd76-75db-4210-955d-8806cd8d87f9}");
+const GONK_MMSSERVICE_CONTRACTID = "@mozilla.org/mms/gonkmmsservice;1";
+const GONK_MMSSERVICE_CID = Components.ID("{9b069b8c-8697-11e4-a406-474f5190272b}");
 
 let DEBUG = false;
 function debug(s) {
@@ -1536,7 +1536,7 @@ function MmsService() {
 }
 MmsService.prototype = {
 
-  classID:   RIL_MMSSERVICE_CID,
+  classID:   GONK_MMSSERVICE_CID,
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIMmsService,
                                          Ci.nsIWapPushApplication,
                                          Ci.nsIObserver]),
diff --git a/dom/mobilemessage/gonk/MmsService.manifest b/dom/mobilemessage/gonk/MmsService.manifest
index 1fc736e1c2f8..5b7d87902a9e 100644
--- a/dom/mobilemessage/gonk/MmsService.manifest
+++ b/dom/mobilemessage/gonk/MmsService.manifest
@@ -1,3 +1,3 @@
 # MmsService.js
-component {217ddd76-75db-4210-955d-8806cd8d87f9} MmsService.js
-contract @mozilla.org/mms/rilmmsservice;1 {217ddd76-75db-4210-955d-8806cd8d87f9}
+component {9b069b8c-8697-11e4-a406-474f5190272b} MmsService.js
+contract @mozilla.org/mms/gonkmmsservice;1 {9b069b8c-8697-11e4-a406-474f5190272b}
diff --git a/dom/mobilemessage/gonk/MobileMessageDB.jsm b/dom/mobilemessage/gonk/MobileMessageDB.jsm
index a8fd33c54643..aed2431a3f0a 100644
--- a/dom/mobilemessage/gonk/MobileMessageDB.jsm
+++ b/dom/mobilemessage/gonk/MobileMessageDB.jsm
@@ -73,7 +73,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gMobileMessageService",
                                    "nsIMobileMessageService");
 
 XPCOMUtils.defineLazyServiceGetter(this, "gMMSService",
-                                   "@mozilla.org/mms/rilmmsservice;1",
+                                   "@mozilla.org/mms/gonkmmsservice;1",
                                    "nsIMmsService");
 
 XPCOMUtils.defineLazyGetter(this, "MMS", function() {
diff --git a/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js b/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
index 4ad692405c2e..14684c7ebbf8 100644
--- a/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
+++ b/dom/mobilemessage/tests/marionette/test_error_of_mms_manual_retrieval.js
@@ -20,7 +20,7 @@ let gUuidGenerator =
   Cc["@mozilla.org/uuid-generator;1"]
     .getService(Ci.nsIUUIDGenerator);
 
-let gMmsService = Cc["@mozilla.org/mms/rilmmsservice;1"]
+let gMmsService = Cc["@mozilla.org/mms/gonkmmsservice;1"]
                        .getService(Ci.nsIMmsService);
 
 function saveMmsNotification() {
diff --git a/dom/wappush/gonk/WapPushManager.js b/dom/wappush/gonk/WapPushManager.js
index 8c86bf14fc49..37d094bd3fac 100644
--- a/dom/wappush/gonk/WapPushManager.js
+++ b/dom/wappush/gonk/WapPushManager.js
@@ -84,7 +84,7 @@ this.WapPushManager = {
     let msg;
     let authInfo = null;
     if (contentType === "application/vnd.wap.mms-message") {
-      let mmsService = Cc["@mozilla.org/mms/rilmmsservice;1"]
+      let mmsService = Cc["@mozilla.org/mms/gonkmmsservice;1"]
                        .getService(Ci.nsIMmsService);
       mmsService.QueryInterface(Ci.nsIWapPushApplication)
                 .receiveWapPush(data.array, data.array.length, data.offset, options);

From d8cb1c196069118fbadd5117245c3e5aae7481bc Mon Sep 17 00:00:00 2001
From: Sean Lin 
Date: Thu, 18 Dec 2014 18:13:31 +0800
Subject: [PATCH 135/183] Bug 1078115 - Make the transaction of app update
 atomic. r=fabrice

---
 dom/apps/Webapps.jsm | 37 +++++++++++++++++++++++++++++++------
 1 file changed, 31 insertions(+), 6 deletions(-)

diff --git a/dom/apps/Webapps.jsm b/dom/apps/Webapps.jsm
index 432dfb3adb8d..8d50a1c97774 100755
--- a/dom/apps/Webapps.jsm
+++ b/dom/apps/Webapps.jsm
@@ -725,6 +725,18 @@ this.DOMApplicationRegistry = {
 
       yield this.loadCurrentRegistry();
 
+      // Sanity check and roll back previous incomplete app updates.
+      for (let id in this.webapps) {
+        let oldDir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id + ".old"], false, true);
+        if (oldDir.exists()) {
+          let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], false, true);
+          if (dir.exists()) {
+            dir.remove(true);
+          }
+          oldDir.moveTo(null, id);
+        }
+      }
+
       try {
         let systemManifestURL =
           Services.prefs.getCharPref("b2g.system_manifest_url");
@@ -1854,8 +1866,6 @@ this.DOMApplicationRegistry = {
     app.readyToApplyDownload = true;
     app.updateTime = Date.now();
 
-    yield this._saveApps();
-
     this.broadcastMessage("Webapps:UpdateState", {
       app: app,
       id: app.id
@@ -1890,18 +1900,33 @@ this.DOMApplicationRegistry = {
     let appFile = tmpDir.clone();
     appFile.append("application.zip");
 
-    let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
+    // In order to better control the potential inconsistency due to unexpected
+    // shutdown during the update process, a separate folder is used to accommodate
+    // the updated files and to replace the current one. Some sanity check and
+    // correspondent rollback logic may be necessary during the initialization
+    // of this component to recover it at next system boot-up.
+    let oldDir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
+    let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id + ".new"], true, true);
     appFile.moveTo(dir, "application.zip");
     manFile.moveTo(dir, "manifest.webapp");
 
-    // Move the staged update manifest to a non staged one.
-    let staged = dir.clone();
+    // Copy the staged update manifest to a non staged one.
+    let staged = oldDir.clone();
     staged.append("staged-update.webapp");
 
     // If we are applying after a restarted download, we have no
     // staged update manifest.
     if (staged.exists()) {
-      staged.moveTo(dir, "update.webapp");
+      staged.copyTo(dir, "update.webapp");
+    }
+
+    oldDir.moveTo(null, id + ".old");
+    dir.moveTo(null, id);
+
+    try {
+      oldDir.remove(true);
+    } catch(e) {
+      oldDir.moveTo(tmpDir, "old." + app.updateTime);
     }
 
     try {

From 27a342c3b5390416afbfff0c5e0031f186d34908 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabrice=20Desr=C3=A9?= 
Date: Thu, 18 Dec 2014 15:16:49 -0800
Subject: [PATCH 136/183] Bug 1113391 - Followup to bug 923897 r=me

---
 dom/apps/tests/addons/script2.js | 4 ++++
 dom/apps/tests/addons/style2.css | 3 +++
 2 files changed, 7 insertions(+)
 create mode 100644 dom/apps/tests/addons/script2.js
 create mode 100644 dom/apps/tests/addons/style2.css

diff --git a/dom/apps/tests/addons/script2.js b/dom/apps/tests/addons/script2.js
new file mode 100644
index 000000000000..a116f46d356d
--- /dev/null
+++ b/dom/apps/tests/addons/script2.js
@@ -0,0 +1,4 @@
+document.addEventListener("DOMContentLoaded", function() {
+  var head = document.getElementById("header2");
+  head.innerHTML = "Customized content";
+}, false);
\ No newline at end of file
diff --git a/dom/apps/tests/addons/style2.css b/dom/apps/tests/addons/style2.css
new file mode 100644
index 000000000000..0e5a21e1787e
--- /dev/null
+++ b/dom/apps/tests/addons/style2.css
@@ -0,0 +1,3 @@
+#header2 {
+  color: blue;
+}
\ No newline at end of file

From c1bc4843a5ce22bda9f7f75a5a6f1ebb7bedae93 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 15:57:22 -0800
Subject: [PATCH 137/183] Bumping gaia.json for 10 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/253e41862ab7
Author: Russ Nicoletti 
Desc: Merge pull request #26607 from russnicoletti/bug-1092972

Bug 1092972 - Video app to follow text selection pattern r=djf

========

https://hg.mozilla.org/integration/gaia-central/rev/b83514159acd
Author: Russ Nicoletti 
Desc: Bug 1092972 - Video app to follow text selection pattern

========

https://hg.mozilla.org/integration/gaia-central/rev/a9f399e36727
Author: Ryan VanderMeulen 
Desc: Merge pull request #26802 from charleyf/Bug1103192

Bug 1103192 - Replace Utils.extend with Object.assign in sms

========

https://hg.mozilla.org/integration/gaia-central/rev/ed3bc1e3c3a6
Author: Charley 
Desc: Bug 1103192 - Replace Utils.extend with Object.assign in sms
r=azasypkin, julien

Bug 1103192 - Replace Utils.extend with Object.assign in sms

Bug 1103192 - Replace Utils.extend with Object.assign in sms - Removed leftover parts of test

========

https://hg.mozilla.org/integration/gaia-central/rev/ec57861ac5ab
Author: Eli Perelman 
Desc: Merge pull request #26895 from mozilla-b2g/revert-26851-bug-1088118-calendar

Revert "Bug 1088118 - Adding User Timing markers for Calendar"

========

https://hg.mozilla.org/integration/gaia-central/rev/21060cdeb613
Author: Eli Perelman 
Desc: Revert "Bug 1088118 - Adding User Timing markers for Calendar"

========

https://hg.mozilla.org/integration/gaia-central/rev/25650102755b
Author: Ryan VanderMeulen 
Desc: Merge pull request #26795 from aosmond/bug1102431

Bug 1102431 - Fix how storage controller cannot assume settings are available if camera not loaded.

========

https://hg.mozilla.org/integration/gaia-central/rev/ab07a34da071
Author: Andrew Osmond 
Desc: Bug 1102431 - Fix how storage controller cannot assume settings are available if camera not loaded.

========

https://hg.mozilla.org/integration/gaia-central/rev/073cebfa1265
Author: Eli Perelman 
Desc: Merge pull request #26851 from eliperelman/bug-1088118-calendar

Bug 1088118 - Adding User Timing markers for Calendar

========

https://hg.mozilla.org/integration/gaia-central/rev/ba893a1025e8
Author: Eli Perelman 
Desc: Bug 1088118 - Adding User Timing markers to Calendar
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 80771b5f22e0..75f541d22ce7 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "9e971d42c915f999f3e352fe43fca7ba0a5245b4", 
+    "revision": "253e41862ab7a29e32d95c95bb8af6a3dcaac568", 
     "repo_path": "integration/gaia-central"
 }

From d987a4e633758eb00a7d1b65f0e052ada2498c80 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 16:02:01 -0800
Subject: [PATCH 138/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 9a86bd510c31..ef8fb3cd8455 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 63e5fc174d3e..128a123fc4bd 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index df313f49a0ee..3f7021d34653 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 310fe85e02b9..fa2cf80ca26a 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 63e5fc174d3e..128a123fc4bd 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index b33c35956211..0605910caa6e 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 0b7787e40148..73e864a0a16a 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index eae0673590e2..418631d80e21 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index b1c629d019b5..bb8fcf4616a0 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 938025589249..2ede0c132557 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 4a726ab83a20..9dfa5e19db85 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 5ad9a1b4901763557b75a907effe7fb53b889c13 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 16:57:16 -0800
Subject: [PATCH 139/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/bf8c2276705b
Author: James Burke 
Desc: Merge pull request #26890 from jrburke/bug1087066-email-rtl-checkbox

Bug 1087066 - Checkboxes should not overlap in message list r=asuth

========

https://hg.mozilla.org/integration/gaia-central/rev/c888457825c7
Author: jrburke 
Desc: Bug 1087066 - Checkboxes should not overlap in message list
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 75f541d22ce7..0ae97b992569 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "253e41862ab7a29e32d95c95bb8af6a3dcaac568", 
+    "revision": "bf8c2276705b4b479ee34244c0f43f18b1866f05", 
     "repo_path": "integration/gaia-central"
 }

From 5403ec44244863a01cb1e4453ee32e69adb1ad91 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 17:07:00 -0800
Subject: [PATCH 140/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index ef8fb3cd8455..de2e436d3a0e 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 128a123fc4bd..3dfbba28a826 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 3f7021d34653..7e0a7c8f2a97 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index fa2cf80ca26a..032ceb2dfbf5 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 128a123fc4bd..3dfbba28a826 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 0605910caa6e..141eb3cd45c9 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 73e864a0a16a..f860c23cf9c8 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 418631d80e21..4c00a9787948 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index bb8fcf4616a0..72342f719713 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 2ede0c132557..8febf59b0d11 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 9dfa5e19db85..b87c45180d0c 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 2c53b0b8ec28f98f2c874f5dd61ab176170fd01b Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 18:52:18 -0800
Subject: [PATCH 141/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/e9560ec06728
Author: Eli Perelman 
Desc: Merge pull request #26852 from eliperelman/bug-1088118-costcontrol

Bug 1088118 - Adding User Timing markers to Usage app

========

https://hg.mozilla.org/integration/gaia-central/rev/ce1e00300eb8
Author: Eli Perelman 
Desc: Bug 1088118 - Adding User Timing markers to Usage app
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 0ae97b992569..81f95a1cc127 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "bf8c2276705b4b479ee34244c0f43f18b1866f05", 
+    "revision": "e9560ec0672854101aa0dcfc2992ef6df27dcaa5", 
     "repo_path": "integration/gaia-central"
 }

From bdf8630ebb1cf7513d23b074e7ee0a56d6d2065d Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 18:56:57 -0800
Subject: [PATCH 142/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index de2e436d3a0e..d88a85be3148 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 3dfbba28a826..99b9d7f6cfad 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 7e0a7c8f2a97..593f187415e1 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 032ceb2dfbf5..84a5d44b85da 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 3dfbba28a826..99b9d7f6cfad 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 141eb3cd45c9..7cc7f0312435 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index f860c23cf9c8..95598b425aa6 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 4c00a9787948..8e205606d743 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 72342f719713..802b6feb6ba3 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 8febf59b0d11..f3e7fa3aa52d 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index b87c45180d0c..ff6dbd0f7d86 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 33385eb6d1ab59b5e14f5d22f83ab0ac5e459b60 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 19:07:18 -0800
Subject: [PATCH 143/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/332e1596ba16
Author: Rudy Lu 
Desc: Merge pull request #26781 from RudyLu/keyboard/Bug1105178-move_resize_out_2

Bug 1105178 - Separate resize out to LayoutPageView.  - Use flex box to layout..
r=timdream.

========

https://hg.mozilla.org/integration/gaia-central/rev/ef052f0d496b
Author: Rudy Lu 
Desc: Bug 1105178 - Separate resize out to LayoutPageView.
 - Use flex box to layout the keyboard.
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 81f95a1cc127..47907ed43df2 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "e9560ec0672854101aa0dcfc2992ef6df27dcaa5", 
+    "revision": "332e1596ba165b7cae4ddfc7e43e3530538a9e5d", 
     "repo_path": "integration/gaia-central"
 }

From 90833853b0b6bd2e0bc10e9f0a2c3297bbe7c185 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 19:11:57 -0800
Subject: [PATCH 144/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index d88a85be3148..aaba69ec2696 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 99b9d7f6cfad..71664e7f30d4 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 593f187415e1..217cba455c0a 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 84a5d44b85da..b9f0c265f9ce 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 99b9d7f6cfad..71664e7f30d4 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 7cc7f0312435..ea9baf07263c 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 95598b425aa6..438d838f9655 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 8e205606d743..ef120915300f 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 802b6feb6ba3..b172c934bb10 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index f3e7fa3aa52d..ae045541df07 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index ff6dbd0f7d86..14a4a5e0d89a 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 4cb966142eddacd230dddb7f76f79c248e4f3a37 Mon Sep 17 00:00:00 2001
From: Jamin Liu 
Date: Fri, 19 Dec 2014 11:12:33 +0800
Subject: [PATCH 145/183] Bug 1100818 - Launch bluetooth certified app by
 sending system message if it's not ready for receiving BluetoothPairingEvent.
 r=btian

---
 dom/bluetooth2/BluetoothAdapter.cpp           | 64 +++++++------------
 dom/bluetooth2/BluetoothAdapter.h             | 14 ++--
 dom/bluetooth2/BluetoothCommon.h              | 13 ++++
 dom/bluetooth2/BluetoothPairingListener.cpp   | 59 +++++++++++++++++
 dom/bluetooth2/BluetoothPairingListener.h     |  5 ++
 dom/bluetooth2/BluetoothService.cpp           | 26 +++++++-
 dom/bluetooth2/BluetoothService.h             |  3 +
 .../bluedroid/BluetoothServiceBluedroid.cpp   |  4 +-
 8 files changed, 137 insertions(+), 51 deletions(-)

diff --git a/dom/bluetooth2/BluetoothAdapter.cpp b/dom/bluetooth2/BluetoothAdapter.cpp
index 87a7e584ff64..16ffb395c6d4 100644
--- a/dom/bluetooth2/BluetoothAdapter.cpp
+++ b/dom/bluetooth2/BluetoothAdapter.cpp
@@ -6,8 +6,9 @@
 
 #include "BluetoothReplyRunnable.h"
 #include "BluetoothService.h"
-#include "BluetoothUtils.h"
 #include "DOMRequest.h"
+#include "nsIDocument.h"
+#include "nsIPrincipal.h"
 #include "nsTArrayHelpers.h"
 
 #include "mozilla/dom/BluetoothAdapter2Binding.h"
@@ -193,11 +194,15 @@ BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aWindow,
   , mState(BluetoothAdapterState::Disabled)
   , mDiscoverable(false)
   , mDiscovering(false)
+  , mPairingReqs(nullptr)
   , mDiscoveryHandleInUse(nullptr)
 {
   MOZ_ASSERT(aWindow);
 
-  mPairingReqs = BluetoothPairingListener::Create(aWindow);
+  // Only allow certified bluetooth application to receive pairing requests
+  if (IsBluetoothCertifiedApp()) {
+    mPairingReqs = BluetoothPairingListener::Create(aWindow);
+  }
 
   const InfallibleTArray& values =
     aValue.get_ArrayOfBluetoothNamedValue();
@@ -329,8 +334,6 @@ BluetoothAdapter::Notify(const BluetoothSignal& aData)
     if (mDiscoveryHandleInUse) {
       HandleDeviceFound(v);
     }
-  } else if (aData.name().EqualsLiteral("PairingRequest")) {
-    HandlePairingRequest(v);
   } else if (aData.name().EqualsLiteral(DEVICE_PAIRED_ID)) {
     HandleDevicePaired(aData.value());
   } else if (aData.name().EqualsLiteral(DEVICE_UNPAIRED_ID)) {
@@ -762,6 +765,23 @@ BluetoothAdapter::IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
   }
 }
 
+bool
+BluetoothAdapter::IsBluetoothCertifiedApp()
+{
+  // Retrieve the app status and origin for permission checking
+  nsCOMPtr doc = GetOwner()->GetExtantDoc();
+  NS_ENSURE_TRUE(doc, false);
+
+  uint16_t appStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
+  nsAutoCString appOrigin;
+
+  doc->NodePrincipal()->GetAppStatus(&appStatus);
+  doc->NodePrincipal()->GetOrigin(getter_Copies(appOrigin));
+
+  return appStatus == nsIPrincipal::APP_STATUS_CERTIFIED &&
+         appOrigin.EqualsLiteral(BLUETOOTH_APP_ORIGIN);
+}
+
 void
 BluetoothAdapter::SetAdapterState(BluetoothAdapterState aState)
 {
@@ -831,42 +851,6 @@ BluetoothAdapter::HandleDeviceFound(const BluetoothValue& aValue)
   mDiscoveryHandleInUse->DispatchDeviceEvent(discoveredDevice);
 }
 
-void
-BluetoothAdapter::HandlePairingRequest(const BluetoothValue& aValue)
-{
-  MOZ_ASSERT(mPairingReqs);
-  MOZ_ASSERT(aValue.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
-
-  const InfallibleTArray& arr =
-    aValue.get_ArrayOfBluetoothNamedValue();
-
-  MOZ_ASSERT(arr.Length() == 3 &&
-             arr[0].value().type() == BluetoothValue::TnsString && // address
-             arr[1].value().type() == BluetoothValue::TnsString && // passkey
-             arr[2].value().type() == BluetoothValue::TnsString);  // type
-
-  nsString deviceAddress = arr[0].value().get_nsString();
-  nsString passkey = arr[1].value().get_nsString();
-  nsString type = arr[2].value().get_nsString();
-
-  // Create a temporary device with deviceAddress for searching
-  InfallibleTArray props;
-  BT_APPEND_NAMED_VALUE(props, "Address", deviceAddress);
-  nsRefPtr device =
-    BluetoothDevice::Create(GetOwner(), props);
-
-  // Find the remote device by address
-  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);
-}
-
 void
 BluetoothAdapter::DispatchAttributeEvent(const nsTArray& aTypes)
 {
diff --git a/dom/bluetooth2/BluetoothAdapter.h b/dom/bluetooth2/BluetoothAdapter.h
index 063fa0b069dc..5c65ede7702a 100644
--- a/dom/bluetooth2/BluetoothAdapter.h
+++ b/dom/bluetooth2/BluetoothAdapter.h
@@ -248,13 +248,6 @@ private:
    */
   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.
    */
@@ -287,6 +280,13 @@ private:
   bool IsAdapterAttributeChanged(BluetoothAdapterAttribute aType,
                                  const BluetoothValue& aValue);
 
+  /**
+   * Check whether this adapter is owned by Bluetooth certified app.
+   *
+   * @return a boolean value to indicate whether it's owned by Bluetooth app.
+   */
+  bool IsBluetoothCertifiedApp();
+
   /****************************************************************************
    * Variables
    ***************************************************************************/
diff --git a/dom/bluetooth2/BluetoothCommon.h b/dom/bluetooth2/BluetoothCommon.h
index d70cb0d15893..e7ddb7c28e4e 100644
--- a/dom/bluetooth2/BluetoothCommon.h
+++ b/dom/bluetooth2/BluetoothCommon.h
@@ -143,6 +143,7 @@ extern bool gBluetoothDebugFlag;
 #define KEY_REMOTE_AGENT      "/B2G/bluetooth/remote_device_agent"
 #define KEY_MANAGER           "/B2G/bluetooth/manager"
 #define KEY_ADAPTER           "/B2G/bluetooth/adapter"
+#define KEY_PAIRING_LISTENER  "/B2G/bluetooth/pairing_listener"
 
 /**
  * When the connection status of a Bluetooth profile is changed, we'll notify
@@ -170,6 +171,18 @@ extern bool gBluetoothDebugFlag;
 #define PAIRING_REQ_TYPE_CONFIRMATION         "pairingconfirmationreq"
 #define PAIRING_REQ_TYPE_CONSENT              "pairingconsentreq"
 
+/**
+ * System message to launch bluetooth app if no pairing listener is ready to
+ * receive pairing requests.
+ */
+#define SYS_MSG_BT_PAIRING_REQ                "bluetooth-pairing-request"
+
+/**
+ * The app origin of bluetooth app, which is responsible for listening pairing
+ * requests.
+ */
+#define BLUETOOTH_APP_ORIGIN                  "app://bluetooth.gaiamobile.org"
+
 /**
  * When a remote device gets paired / unpaired with local bluetooth adapter,
  * we'll dispatch an event.
diff --git a/dom/bluetooth2/BluetoothPairingListener.cpp b/dom/bluetooth2/BluetoothPairingListener.cpp
index 305cf9fe2923..b0d31aad1c4a 100644
--- a/dom/bluetooth2/BluetoothPairingListener.cpp
+++ b/dom/bluetooth2/BluetoothPairingListener.cpp
@@ -6,8 +6,10 @@
 
 #include "mozilla/dom/bluetooth/BluetoothPairingListener.h"
 #include "mozilla/dom/bluetooth/BluetoothPairingHandle.h"
+#include "mozilla/dom/bluetooth/BluetoothTypes.h"
 #include "mozilla/dom/BluetoothPairingEvent.h"
 #include "mozilla/dom/BluetoothPairingListenerBinding.h"
+#include "BluetoothService.h"
 
 USING_BLUETOOTH_NAMESPACE
 
@@ -21,6 +23,11 @@ BluetoothPairingListener::BluetoothPairingListener(nsPIDOMWindow* aWindow)
   : DOMEventTargetHelper(aWindow)
 {
   MOZ_ASSERT(aWindow);
+
+  BluetoothService* bs = BluetoothService::Get();
+  NS_ENSURE_TRUE_VOID(bs);
+  bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
+                                     this);
 }
 
 already_AddRefed
@@ -37,6 +44,11 @@ BluetoothPairingListener::Create(nsPIDOMWindow* aWindow)
 
 BluetoothPairingListener::~BluetoothPairingListener()
 {
+  BluetoothService* bs = BluetoothService::Get();
+  // It can be nullptr on shutdown.
+  NS_ENSURE_TRUE_VOID(bs);
+  bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
+                                       this);
 }
 
 void
@@ -67,8 +79,55 @@ BluetoothPairingListener::DispatchPairingEvent(BluetoothDevice* aDevice,
   DispatchTrustedEvent(event);
 }
 
+void
+BluetoothPairingListener::Notify(const BluetoothSignal& aData)
+{
+  InfallibleTArray arr;
+
+  BluetoothValue value = aData.value();
+  if (aData.name().EqualsLiteral("PairingRequest")) {
+
+    MOZ_ASSERT(value.type() == BluetoothValue::TArrayOfBluetoothNamedValue);
+
+    const InfallibleTArray& arr =
+      value.get_ArrayOfBluetoothNamedValue();
+
+    MOZ_ASSERT(arr.Length() == 3 &&
+               arr[0].value().type() == BluetoothValue::TnsString && // address
+               arr[1].value().type() == BluetoothValue::TnsString && // passkey
+               arr[2].value().type() == BluetoothValue::TnsString);  // type
+
+    nsString deviceAddress = arr[0].value().get_nsString();
+    nsString passkey = arr[1].value().get_nsString();
+    nsString type = arr[2].value().get_nsString();
+
+    // Create a temporary device with deviceAddress for searching
+    InfallibleTArray props;
+    BT_APPEND_NAMED_VALUE(props, "Address", deviceAddress);
+    nsRefPtr device =
+      BluetoothDevice::Create(GetOwner(), props);
+
+    // Notify pairing listener of pairing requests
+    DispatchPairingEvent(device, passkey, type);
+  } else {
+    BT_WARNING("Not handling pairing listener signal: %s",
+               NS_ConvertUTF16toUTF8(aData.name()).get());
+  }
+}
+
 JSObject*
 BluetoothPairingListener::WrapObject(JSContext* aCx)
 {
   return BluetoothPairingListenerBinding::Wrap(aCx, this);
 }
+
+void
+BluetoothPairingListener::DisconnectFromOwner()
+{
+  DOMEventTargetHelper::DisconnectFromOwner();
+
+  BluetoothService* bs = BluetoothService::Get();
+  NS_ENSURE_TRUE_VOID(bs);
+  bs->UnregisterBluetoothSignalHandler(NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
+                                       this);
+}
diff --git a/dom/bluetooth2/BluetoothPairingListener.h b/dom/bluetooth2/BluetoothPairingListener.h
index 9958d2fc7b74..909fbc0e6952 100644
--- a/dom/bluetooth2/BluetoothPairingListener.h
+++ b/dom/bluetooth2/BluetoothPairingListener.h
@@ -14,8 +14,10 @@
 BEGIN_BLUETOOTH_NAMESPACE
 
 class BluetoothDevice;
+class BluetoothSignal;
 
 class BluetoothPairingListener MOZ_FINAL : public DOMEventTargetHelper
+                                         , public BluetoothSignalObserver
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
@@ -27,12 +29,15 @@ public:
                             const nsAString& aPasskey,
                             const nsAString& aType);
 
+  void Notify(const BluetoothSignal& aParam); // BluetoothSignalObserver
+
   nsPIDOMWindow* GetParentObject() const
   {
     return GetOwner();
   }
 
   virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
+  virtual void DisconnectFromOwner() MOZ_OVERRIDE;
 
   IMPL_EVENT_HANDLER(displaypasskeyreq);
   IMPL_EVENT_HANDLER(enterpincodereq);
diff --git a/dom/bluetooth2/BluetoothService.cpp b/dom/bluetooth2/BluetoothService.cpp
index 1a95101cd14b..e422d7cdd724 100644
--- a/dom/bluetooth2/BluetoothService.cpp
+++ b/dom/bluetooth2/BluetoothService.cpp
@@ -273,6 +273,17 @@ BluetoothService::RegisterBluetoothSignalHandler(
   }
 
   ol->AddObserver(aHandler);
+
+  // Distribute pending pairing requests when pairing listener has been added
+  // to signal observer table.
+  if (IsMainProcess() &&
+      !mPendingPairReqSignals.IsEmpty() &&
+      aNodeName.EqualsLiteral(KEY_PAIRING_LISTENER)) {
+    for (uint32_t i = 0; i < mPendingPairReqSignals.Length(); ++i) {
+      DistributeSignal(mPendingPairReqSignals[i]);
+    }
+    mPendingPairReqSignals.Clear();
+  }
 }
 
 void
@@ -331,8 +342,19 @@ BluetoothService::DistributeSignal(const BluetoothSignal& aSignal)
 
   BluetoothSignalObserverList* ol;
   if (!mBluetoothSignalObserverTable.Get(aSignal.path(), &ol)) {
-    BT_WARNING("No observer registered for path %s",
-               NS_ConvertUTF16toUTF8(aSignal.path()).get());
+    // If there is no BluetoohPairingListener in observer table, put the signal
+    // into a pending queue of pairing requests and send a system message to
+    // launch bluetooth certified app.
+    if (aSignal.path().EqualsLiteral(KEY_PAIRING_LISTENER)) {
+      mPendingPairReqSignals.AppendElement(aSignal);
+
+      BT_ENSURE_TRUE_VOID_BROADCAST_SYSMSG(
+        NS_LITERAL_STRING(SYS_MSG_BT_PAIRING_REQ),
+        BluetoothValue(EmptyString()));
+    } else {
+      BT_WARNING("No observer registered for path %s",
+                 NS_ConvertUTF16toUTF8(aSignal.path()).get());
+    }
     return;
   }
 
diff --git a/dom/bluetooth2/BluetoothService.h b/dom/bluetooth2/BluetoothService.h
index 56092a432865..8879ea3f8194 100644
--- a/dom/bluetooth2/BluetoothService.h
+++ b/dom/bluetooth2/BluetoothService.h
@@ -8,6 +8,7 @@
 #define mozilla_dom_bluetooth_bluetootheventservice_h__
 
 #include "BluetoothCommon.h"
+#include "BluetoothInterface.h"
 #include "BluetoothProfileManagerBase.h"
 #include "nsAutoPtr.h"
 #include "nsClassHashtable.h"
@@ -401,6 +402,8 @@ protected:
 
   BluetoothSignalObserverTable mBluetoothSignalObserverTable;
 
+  nsTArray mPendingPairReqSignals;
+
   bool mEnabled;
 };
 
diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
index c734833400b3..8a17df692d4a 100644
--- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
+++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp
@@ -1473,7 +1473,7 @@ BluetoothServiceBluedroid::PinRequestNotification(const nsAString& aRemoteBdAddr
                         NS_LITERAL_STRING(PAIRING_REQ_TYPE_ENTERPINCODE));
 
   DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PairingRequest"),
-                                   NS_LITERAL_STRING(KEY_ADAPTER),
+                                   NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                                    BluetoothValue(propertiesArray)));
 }
 
@@ -1518,7 +1518,7 @@ BluetoothServiceBluedroid::SspRequestNotification(
   BT_APPEND_NAMED_VALUE(propertiesArray, "type", pairingType);
 
   DistributeSignal(BluetoothSignal(NS_LITERAL_STRING("PairingRequest"),
-                                   NS_LITERAL_STRING(KEY_ADAPTER),
+                                   NS_LITERAL_STRING(KEY_PAIRING_LISTENER),
                                    BluetoothValue(propertiesArray)));
 }
 

From 0b13bbf455c5e97de2accd334b63a72c8625d8d3 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 22:27:17 -0800
Subject: [PATCH 146/183] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/724943c2c3e2
Author: EragonJ (E.J.) 
Desc: Merge pull request #26898 from EragonJ/bug-1111903-update

Bug 1111903 - [Settings] Refactor Dialog Service with l10n best practice...

========

https://hg.mozilla.org/integration/gaia-central/rev/40636bd7b8a0
Author: EragonJ 
Desc: Bug 1111903 - [Settings] Refactor Dialog Service with l10n best practices

========

https://hg.mozilla.org/integration/gaia-central/rev/833c5a6e423c
Author: Arthur Chen 
Desc: Merge pull request #26878 from crh0716/1111712

Bug 1111712 - Check the existence of the bluetooth item r=eragonj

========

https://hg.mozilla.org/integration/gaia-central/rev/0537e5552c0c
Author: Arthur Chen 
Desc: Bug 1111712 - Check the existence of the bluetooth item
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 47907ed43df2..d31989993871 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "332e1596ba165b7cae4ddfc7e43e3530538a9e5d", 
+    "revision": "724943c2c3e2384b5ca4ef5cfa978c733913fd03", 
     "repo_path": "integration/gaia-central"
 }

From 4e66b9065f89b930fe0e5960761f70015d9293a8 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 22:31:55 -0800
Subject: [PATCH 147/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index aaba69ec2696..f5c143415639 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 71664e7f30d4..120d86d39041 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 217cba455c0a..929210b5c2e5 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index b9f0c265f9ce..220081f0c9f1 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 71664e7f30d4..120d86d39041 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index ea9baf07263c..35fac560f4ca 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 438d838f9655..2a1af018f2e8 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index ef120915300f..79fe23f2c2f5 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index b172c934bb10..e1c832a57b94 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index ae045541df07..79a8382ba08f 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 14a4a5e0d89a..8658eee769d6 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From d859d8d0f951ad29cfc0003e085f6a93c063c81f Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Thu, 18 Dec 2014 23:57:17 -0800
Subject: [PATCH 148/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/20dd907f4298
Author: Tzu-Lin Huang 
Desc: Merge pull request #26872 from dwi2/bug1106844

Bug 1106844 - [Stingray] prevent focus stays on disabled elements in order to receive keyboard event

========

https://hg.mozilla.org/integration/gaia-central/rev/c46b7184aef1
Author: Tzu-Lin Huang 
Desc: Bug 1106844 - [Stingray] prevent focus stays on disabled elements in order to receive keyboard event
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index d31989993871..886d361032fc 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "724943c2c3e2384b5ca4ef5cfa978c733913fd03", 
+    "revision": "20dd907f42986f522233b523edd12064991a09ea", 
     "repo_path": "integration/gaia-central"
 }

From dfdba1ea633b1a51dfff5cb454880c5a802c7d9f Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 00:06:56 -0800
Subject: [PATCH 149/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index f5c143415639..64bcfb4b8866 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 120d86d39041..02ace38d61db 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 929210b5c2e5..2403ca196315 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 220081f0c9f1..e73808620e65 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 120d86d39041..02ace38d61db 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 35fac560f4ca..5538776ba0f9 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 2a1af018f2e8..2864961c1da2 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 79fe23f2c2f5..31b488a8101d 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index e1c832a57b94..82395ad39781 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 79a8382ba08f..1c109efe4aeb 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 8658eee769d6..b0a7faf39a2d 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 7c9ca8778574e9b67ec2efbcb3311aab1337f046 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 00:47:28 -0800
Subject: [PATCH 150/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/67ed88a68635
Author: Ricky Chien 
Desc: Merge pull request #26843 from RickyChien/bug-1111352

Bug 1111352 - Add keyboard test for build script r=@cctuan

========

https://hg.mozilla.org/integration/gaia-central/rev/ba9d6a0b48ab
Author: Ricky Chien 
Desc: Bug 1111352 - Add keyboard test for build script
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index c4ebb32a8f4e..1845831b4e33 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "5ec3ded83868cfc6904e0ad11714f7c3b9dc20f1", 
+    "revision": "67ed88a6863592bd8552242688ad93caa58d0b83", 
     "repo_path": "integration/gaia-central"
 }

From 0f03c71c8d2834e72b744cec2738660c2c39badf Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 00:52:07 -0800
Subject: [PATCH 151/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index b8907569aaa5..2693797f8be2 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index ef494c3c51b8..1a91afd13556 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 3f71896321f8..c3bd44df39ce 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index fde362480852..9e50ab85c12b 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index ef494c3c51b8..1a91afd13556 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index f3e85af2cf17..65fd136a9367 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 1b356ef8763d..e8ac70a5e59f 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 9e7b329decd7..89a347d2647c 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 8b3a37fac7d5..e0c205f39714 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index ee217d9d9c48..9ef5d2a3157b 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 63eae9191343..478078286ac6 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From ca25b3af3f8b75515a20935b651c6e9f44998f14 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 01:32:33 -0800
Subject: [PATCH 152/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/dbc726a9105a
Author: Timothy Guan-tin Chien 
Desc: Merge pull request #26909 from mozilla-b2g/revert-26755-revert-26708-Patch_1046900

Reland bug 1046900, Adding telugu keyboard to FxOS

========

https://hg.mozilla.org/integration/gaia-central/rev/0ed304c7948a
Author: Timothy Guan-tin Chien 
Desc: Revert "Revert "Fixes bug 1046900, Adding telugu keyboard to FxOS""
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 1845831b4e33..26c57dfebd9d 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "67ed88a6863592bd8552242688ad93caa58d0b83", 
+    "revision": "dbc726a9105abd2d6d26fdca5e9508af5df50d6b", 
     "repo_path": "integration/gaia-central"
 }

From 896c38d097466fafb0fe293531965de0622d9585 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 01:41:42 -0800
Subject: [PATCH 153/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 2693797f8be2..380c3f8d8fb1 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 1a91afd13556..f855d62be77b 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index c3bd44df39ce..ada78d3e87e9 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 9e50ab85c12b..f09caf84bafd 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 1a91afd13556..f855d62be77b 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 65fd136a9367..b549367f1900 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index e8ac70a5e59f..cf9ed1a06cac 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 89a347d2647c..fe7ec3e18593 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index e0c205f39714..2ccf6a0eb99e 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 9ef5d2a3157b..f802ce844c4d 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 478078286ac6..9be64115ffff 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 872beeac365326273f1b29ff878dcef9d0b95479 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 01:47:27 -0800
Subject: [PATCH 154/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

========

https://hg.mozilla.org/integration/gaia-central/rev/530b13055e35
Author: Fernando Rodríguez Sela 
Desc: Merge pull request #26108 from mancas/bug1095802

Bug 1095802 - Piped STK messages results in no Terminal Responses, r=anshulj, r=kgrandon

========

https://hg.mozilla.org/integration/gaia-central/rev/c8488614a6a6
Author: Manuel 
Desc: Bug 1095802 - Piped STK messages results in no Terminal Responses
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 26c57dfebd9d..753f367216c8 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "dbc726a9105abd2d6d26fdca5e9508af5df50d6b", 
+    "revision": "530b13055e359a9af6fafd0384ea65a4ec8dfc5c", 
     "repo_path": "integration/gaia-central"
 }

From 567b736d38f5669687ee710e8f0fc662db66a173 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 01:57:07 -0800
Subject: [PATCH 155/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 380c3f8d8fb1..81f12498e773 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index f855d62be77b..555d50a07fca 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index ada78d3e87e9..6ba3f3714867 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index f09caf84bafd..fd8f71241685 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index f855d62be77b..555d50a07fca 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index b549367f1900..effc153e5250 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index cf9ed1a06cac..efb19f26aba5 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index fe7ec3e18593..91257c80e76f 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 2ccf6a0eb99e..10b4d307af48 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index f802ce844c4d..53881cb4eb59 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 9be64115ffff..d520f1744561 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From a4bfcf1ff8e5753def8ce2684a06ee54356daf72 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 02:17:23 -0800
Subject: [PATCH 156/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/4235e9c7c548
Author: Greg Weng 
Desc: Merge pull request #26760 from snowmantw/bug1110960

Bug 1110960 - Device slowing down after more than one day of uptime

========

https://hg.mozilla.org/integration/gaia-central/rev/2f29ae88d423
Author: Greg Weng 
Desc: Bug 1110960 - Device slowing down after more than one day of uptime
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 753f367216c8..02b5949fda3f 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "530b13055e359a9af6fafd0384ea65a4ec8dfc5c", 
+    "revision": "4235e9c7c5480b13870fa9d7640560debaf5e2e3", 
     "repo_path": "integration/gaia-central"
 }

From 0fa0e33275604cf858737cd6ff4a779214513db3 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 02:27:03 -0800
Subject: [PATCH 157/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 81f12498e773..62679f153ab3 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 555d50a07fca..2eaa60d54fa4 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 6ba3f3714867..f9beda879321 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index fd8f71241685..6d8f73d22d5a 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 555d50a07fca..2eaa60d54fa4 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index effc153e5250..8e3e8e07a615 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index efb19f26aba5..b61afc2af134 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 91257c80e76f..0ec82badc4f7 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 10b4d307af48..ae584e61757d 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 53881cb4eb59..6c9dec04cff9 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index d520f1744561..b372f399892e 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From f064006f9dc85ab4dea91d74750f3df494311da9 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 02:47:25 -0800
Subject: [PATCH 158/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/6b43ac014f87
Author: Alive.Kuo 
Desc: Merge pull request #26837 from alivedise/bugzilla/1106855/do-not-block-system-resize-on-rocketbar

Bug 1106855 - Resize on orientationchange on active window +autoland, r=etienne

========

https://hg.mozilla.org/integration/gaia-central/rev/5d78038e9143
Author: Alive Kuo 
Desc: Bug 1106855 - Resize on orientationchange on active window
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 02b5949fda3f..4d17ec6ec631 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "4235e9c7c5480b13870fa9d7640560debaf5e2e3", 
+    "revision": "6b43ac014f87ddd058eabd056d68a03da9f4ebcd", 
     "repo_path": "integration/gaia-central"
 }

From 62f83dea152d721597ea851a3c459d7cf4d393d8 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 02:57:06 -0800
Subject: [PATCH 159/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 62679f153ab3..3f735d0c76f4 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 2eaa60d54fa4..a514519cef35 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index f9beda879321..4e3357da8632 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 6d8f73d22d5a..27aa1e1e6f04 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 2eaa60d54fa4..a514519cef35 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 8e3e8e07a615..b9a574da0ca5 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index b61afc2af134..2e5eeb3af184 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 0ec82badc4f7..b93f7924987a 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index ae584e61757d..0b2d8d7bc532 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 6c9dec04cff9..fa1485b24c2a 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index b372f399892e..ecf0f48ef3ca 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 28e47f2f5c23d7fdc88e265ed31dc46ad1b43420 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 03:22:18 -0800
Subject: [PATCH 160/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/c1377da26c31
Author: Ricky Chien 
Desc: Merge pull request #26900 from RickyChien/bug-1059449

Bug 1059449 - Add MOZ_DISABLE_NONLOCAL_CONNECTIONS for build tests r=@cctuan

========

https://hg.mozilla.org/integration/gaia-central/rev/adebaf3d03f5
Author: Ricky Chien 
Desc: Bug 1059449 - Add MOZ_DISABLE_NONLOCAL_CONNECTIONS for build tests
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 4d17ec6ec631..0df82c34ea91 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "6b43ac014f87ddd058eabd056d68a03da9f4ebcd", 
+    "revision": "c1377da26c318bf4b4ba763356de98d407f1d07d", 
     "repo_path": "integration/gaia-central"
 }

From dd08f06f0e5b0fcb615cc155f00969a868cd7eb4 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 03:26:57 -0800
Subject: [PATCH 161/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 3f735d0c76f4..fcb292930952 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index a514519cef35..3357f812ea9b 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 4e3357da8632..193cfb524fca 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 27aa1e1e6f04..7b0c1a41d38a 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index a514519cef35..3357f812ea9b 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index b9a574da0ca5..250391d9d43c 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 2e5eeb3af184..9996d9a65085 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index b93f7924987a..6ba3cfde3d1e 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 0b2d8d7bc532..243cee822574 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index fa1485b24c2a..d67ad906ef33 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index ecf0f48ef3ca..01aac1e4d193 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From b3bb9434e6d463b195803284c77f7ae5c3a13b1e Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 06:12:18 -0800
Subject: [PATCH 162/183] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/3c7a9041d94d
Author: Florin Strugariu 
Desc: Merge pull request #26885 from viorelaioia/bug_1110218

Bug 1110218 - Investigate intermittent failure in test_redial_last_numbe...

========

https://hg.mozilla.org/integration/gaia-central/rev/9ef859b524c0
Author: Viorela Ioia 
Desc: Bug 1110218 - Investigate intermittent failure in test_redial_last_number.py

========

https://hg.mozilla.org/integration/gaia-central/rev/3c6d71b5fd4c
Author: Florin Strugariu 
Desc: Merge pull request #26886 from npark-mozilla/1112758

Bug 1112758 - Create a new test case for the switching to camera from gallery's list view

========

https://hg.mozilla.org/integration/gaia-central/rev/0235d0de2061
Author: No-Jun 
Desc: Bug 1112758 - Create a new test case for the switching to camera from gallery's list view
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 0df82c34ea91..d5a458c9014c 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "c1377da26c318bf4b4ba763356de98d407f1d07d", 
+    "revision": "3c7a9041d94d689a0b0533670b073c26bd1e879b", 
     "repo_path": "integration/gaia-central"
 }

From 6fdf71867c804f1f7acd9b7b53d912bdb0d0d1dd Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 06:17:03 -0800
Subject: [PATCH 163/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index fcb292930952..18455316cd95 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 3357f812ea9b..1d9ce4a7f49c 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 193cfb524fca..eac3e49c6aab 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 7b0c1a41d38a..553b896d06a4 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 3357f812ea9b..1d9ce4a7f49c 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 250391d9d43c..e2bd9c9b3d06 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 9996d9a65085..93b15dd2f7f3 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 6ba3cfde3d1e..4ebac724e980 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 243cee822574..ddf16cceb8b3 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index d67ad906ef33..832faab040ef 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 01aac1e4d193..297f4b00ade5 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From c077c1aeef9193e99e912c8bf38b3c679b596127 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 07:12:22 -0800
Subject: [PATCH 164/183] Bumping gaia.json for 4 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/18bf2612187b
Author: Ricky Chien 
Desc: Merge pull request #26905 from RickyChien/bug-1112490

Bug 1112490 - Parallel build should output a make error r=@cctuan

========

https://hg.mozilla.org/integration/gaia-central/rev/8599f609fba7
Author: Ricky Chien 
Desc: Bug 1112490 - Parallel build should output a make error

========

https://hg.mozilla.org/integration/gaia-central/rev/d0e0c81e056d
Author: Miller Medeiros 
Desc: Merge pull request #25948 from millermedeiros/1084014-month-view-day-observer

Bug 1084014 - [Calendar] update Month view to use DayObserver r=gaye

========

https://hg.mozilla.org/integration/gaia-central/rev/061255136be9
Author: Miller Medeiros 
Desc: Bug 1084014 - [Calendar] update Month view to use DayObserver
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index d5a458c9014c..8db14a3d07c4 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "3c7a9041d94d689a0b0533670b073c26bd1e879b", 
+    "revision": "18bf2612187b613bbfbb21cc5700cf7b0d251971", 
     "repo_path": "integration/gaia-central"
 }

From 2df24d14844648347f93f8cd4cd40281a73ffb34 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 07:22:02 -0800
Subject: [PATCH 165/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 18455316cd95..1504dc3d3af7 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 1d9ce4a7f49c..73f6e75bc7e1 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index eac3e49c6aab..286ffb0a9c33 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 553b896d06a4..5d708757358e 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 1d9ce4a7f49c..73f6e75bc7e1 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index e2bd9c9b3d06..5f25aafa5881 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 93b15dd2f7f3..2ee4bbd4a94f 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 4ebac724e980..97faa5c3d916 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index ddf16cceb8b3..81c1da33408b 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 832faab040ef..9e0d33bff431 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 297f4b00ade5..44db94ebf856 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From ec80c5a9029b1d65e3743014737559d39ee303d5 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 07:27:17 -0800
Subject: [PATCH 166/183] Bumping gaia.json for 2 gaia revision(s) a=gaia-bump

========

https://hg.mozilla.org/integration/gaia-central/rev/0928af6ba801
Author: autolander 
Desc: Bug 1111871 - merge pull request #26853 from etiennesegonzac:bug-1111871 to mozilla-b2g:master

========

https://hg.mozilla.org/integration/gaia-central/rev/7c31adeeb72e
Author: Etienne Segonzac 
Desc: Bug 1111871 - Properly exiting the tabs view on lock events. r=sfoster
---
 b2g/config/gaia.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index 8db14a3d07c4..b3c4c1b09909 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
         "remote": "", 
         "branch": ""
     }, 
-    "revision": "18bf2612187b613bbfbb21cc5700cf7b0d251971", 
+    "revision": "0928af6ba8010181592fc8eedae9550ac8597f53", 
     "repo_path": "integration/gaia-central"
 }

From ee6e6a751a1aa75b55d9e4a03e877ed7b81a5226 Mon Sep 17 00:00:00 2001
From: B2G Bumper Bot 
Date: Fri, 19 Dec 2014 07:36:57 -0800
Subject: [PATCH 167/183] Bumping manifests a=b2g-bump

---
 b2g/config/dolphin/sources.xml      | 2 +-
 b2g/config/emulator-ics/sources.xml | 2 +-
 b2g/config/emulator-jb/sources.xml  | 2 +-
 b2g/config/emulator-kk/sources.xml  | 2 +-
 b2g/config/emulator/sources.xml     | 2 +-
 b2g/config/flame-kk/sources.xml     | 2 +-
 b2g/config/flame/sources.xml        | 2 +-
 b2g/config/hamachi/sources.xml      | 2 +-
 b2g/config/helix/sources.xml        | 2 +-
 b2g/config/nexus-4/sources.xml      | 2 +-
 b2g/config/wasabi/sources.xml       | 2 +-
 11 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml
index 1504dc3d3af7..aff28e8c6e2d 100644
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 73f6e75bc7e1..d4fb914b7098 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 286ffb0a9c33..af6a072e14bf 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 5d708757358e..1bb8741d4735 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 73f6e75bc7e1..d4fb914b7098 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,7 +19,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml
index 5f25aafa5881..5a018c6f335a 100644
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -15,7 +15,7 @@
   
     
   
-  
+  
   
   
   
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 2ee4bbd4a94f..24e59db19738 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index 97faa5c3d916..cf73e3496011 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 81c1da33408b..34f304163307 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
     
   
   
-  
+  
   
   
   
diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml
index 9e0d33bff431..5b7f49802e77 100644
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -17,7 +17,7 @@
   
   
   
-  
+  
   
   
   
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index 44db94ebf856..3e3572f12be0 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,7 +17,7 @@
     
   
   
-  
+  
   
   
   

From 94d613426b05b67bfabea21cb141d3cf863fc83d Mon Sep 17 00:00:00 2001
From: Mason Chang 
Date: Fri, 19 Dec 2014 10:47:56 -0500
Subject: [PATCH 168/183] Bug 1097792. Further tweak fling curving prefs.
 r=kats

---
 b2g/app/b2g.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js
index e97b74bb2771..86cce513e05b 100644
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -995,10 +995,10 @@ pref("apz.pan_repaint_interval", 16);
 // APZ physics settings, tuned by UX designers
 pref("apz.fling_curve_function_x1", "0.41");
 pref("apz.fling_curve_function_y1", "0.0");
-pref("apz.fling_curve_function_x2", "0.76");
+pref("apz.fling_curve_function_x2", "0.80");
 pref("apz.fling_curve_function_y2", "1.0");
 pref("apz.fling_curve_threshold_inches_per_ms", "0.01");
-pref("apz.fling_friction", "0.0024");
+pref("apz.fling_friction", "0.00238");
 pref("apz.max_velocity_inches_per_ms", "0.07");
 
 // Tweak default displayport values to reduce the risk of running out of

From 8c9918d2b5893129de88be93a822b4b1493aa682 Mon Sep 17 00:00:00 2001
From: Geoff Brown 
Date: Fri, 19 Dec 2014 09:22:07 -0700
Subject: [PATCH 169/183] Bug 1085837 - Fix robocop testAppMenuPathways on
 Android 2.3; r=mcomella

---
 .../base/tests/components/AppMenuComponent.java     | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/mobile/android/base/tests/components/AppMenuComponent.java b/mobile/android/base/tests/components/AppMenuComponent.java
index a45868998c0d..b0da439e70b9 100644
--- a/mobile/android/base/tests/components/AppMenuComponent.java
+++ b/mobile/android/base/tests/components/AppMenuComponent.java
@@ -20,6 +20,7 @@ import org.mozilla.gecko.tests.helpers.WaitHelper;
 import org.mozilla.gecko.util.HardwareUtils;
 
 import android.view.View;
+import android.widget.TextView;
 
 import com.jayway.android.robotium.solo.Condition;
 import com.jayway.android.robotium.solo.RobotiumUtils;
@@ -174,6 +175,18 @@ public class AppMenuComponent extends BaseComponent {
             }
         }
 
+        // On Android 2.3, menu items may be instances of
+        // com.android.internal.view.menu.ListMenuItemView, each with a child
+        // android.widget.RelativeLayout which in turn has a child
+        // TextView with the appropriate text.
+        final List textViewList = RobotiumUtils.filterViews(TextView.class, views);
+        for (TextView textView : textViewList) {
+            if (textView.getText().equals(text)) {
+                View relativeLayout = (View) textView.getParent();
+                View listMenuItemView = (View)relativeLayout.getParent();
+                return listMenuItemView;
+            }
+        }
         return null;
     }
 

From 5480fb59180daa059ee2b3e9444c3c8e386cfa09 Mon Sep 17 00:00:00 2001
From: Geoff Brown 
Date: Fri, 19 Dec 2014 09:22:08 -0700
Subject: [PATCH 170/183] Bug 1107002 - Update check for home banner not
 visible; r=mcomella

---
 .../tests/components/AboutHomeComponent.java  | 20 ++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/mobile/android/base/tests/components/AboutHomeComponent.java b/mobile/android/base/tests/components/AboutHomeComponent.java
index 871393439a78..d7ab229b4b67 100644
--- a/mobile/android/base/tests/components/AboutHomeComponent.java
+++ b/mobile/android/base/tests/components/AboutHomeComponent.java
@@ -17,6 +17,7 @@ import org.mozilla.gecko.tests.UITestContext;
 import org.mozilla.gecko.tests.helpers.WaitHelper;
 import org.mozilla.gecko.util.HardwareUtils;
 
+import android.os.Build;
 import android.support.v4.view.ViewPager;
 import android.view.View;
 import android.widget.TextView;
@@ -99,11 +100,20 @@ public class AboutHomeComponent extends BaseComponent {
 
     public AboutHomeComponent assertBannerNotVisible() {
         View banner = getHomeBannerView();
-        fAssertTrue("The HomeBanner is not visible",
-                    getHomePagerContainer().getVisibility() != View.VISIBLE ||
-                    banner == null ||
-                    banner.getVisibility() != View.VISIBLE ||
-                    banner.getTranslationY() == banner.getHeight());
+        if (Build.VERSION.SDK_INT >= 11) {
+            fAssertTrue("The HomeBanner is not visible",
+                        getHomePagerContainer().getVisibility() != View.VISIBLE ||
+                        banner == null ||
+                        banner.getVisibility() != View.VISIBLE ||
+                        banner.getTranslationY() == banner.getHeight());
+        } else {
+            // getTranslationY is not available before api 11.
+            // This check is a little less specific.
+            fAssertTrue("The HomeBanner is not visible",
+                        getHomePagerContainer().getVisibility() != View.VISIBLE ||
+                        banner == null ||
+                        banner.isShown() == false);
+        }
         return this;
     }
 

From 656789838257f86997c6d303157018d4064592fe Mon Sep 17 00:00:00 2001
From: Ben Turner 
Date: Fri, 19 Dec 2014 08:27:03 -0800
Subject: [PATCH 171/183] Bug 1113429 - Optimize NUWA idle notifications on
 workers, r=froydnj.

---
 dom/workers/WorkerPrivate.cpp | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp
index d583dc2d2eae..fefc1b959e88 100644
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -73,7 +73,6 @@
 #include "nsProxyRelease.h"
 #include "nsSandboxFlags.h"
 #include "prthread.h"
-#include "nsThread.h"
 #include "xpcpublic.h"
 
 #ifdef ANDROID
@@ -4333,17 +4332,6 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
     {
       MutexAutoLock lock(mMutex);
 
-#ifdef MOZ_NUWA_PROCESS
-      {
-        nsThread *thr = static_cast(NS_GetCurrentThread());
-        ReentrantMonitorAutoEnter mon(thr->ThreadStatusMonitor());
-        if (mControlQueue.IsEmpty() &&
-            !(normalRunnablesPending = NS_HasPendingEvents(mThread))) {
-          thr->SetIdle();
-        }
-      }
-#endif // MOZ_NUWA_PROCESS
-
       while (mControlQueue.IsEmpty() &&
              !(normalRunnablesPending = NS_HasPendingEvents(mThread))) {
         WaitForWorkerEvents();
@@ -4853,6 +4841,15 @@ WorkerPrivate::WaitForWorkerEvents(PRIntervalTime aInterval)
   // The main thread may be waiting so we must notify.
   mMemoryReportCondVar.Notify();
 
+#ifdef MOZ_NUWA_PROCESS
+  {
+    MOZ_ASSERT(mThread);
+
+    ReentrantMonitorAutoEnter mon(mThread->ThreadStatusMonitor());
+    mThread->SetIdle();
+  }
+#endif // MOZ_NUWA_PROCESS
+
   // Now wait for an actual worker event.
   mCondVar.Wait(aInterval);
 

From 68517749771828e8b6d3192ae2410faf199afc38 Mon Sep 17 00:00:00 2001
From: Mats Palmgren 
Date: Fri, 19 Dec 2014 16:28:42 +0000
Subject: [PATCH 172/183] Bug 1111360 - Remove the unused NS_IS_REFLOW_ERROR
 macro and an obsolete comment.  r=roc

---
 layout/generic/nsIFrame.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 81ea730b73b6..8dbeecfd5650 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -247,14 +247,6 @@ typedef uint32_t nsReflowStatus;
 #define NS_FRAME_SET_OVERFLOW_INCOMPLETE(status) \
   status = (status & ~NS_FRAME_NOT_COMPLETE) | NS_FRAME_OVERFLOW_INCOMPLETE
 
-// This macro tests to see if an nsReflowStatus is an error value
-// or just a regular return value
-#define NS_IS_REFLOW_ERROR(_status) (int32_t(_status) < 0)
-
-/**
- * Extensions to the reflow status bits defined by nsIFrameReflow
- */
-
 // This bit is set, when a break is requested. This bit is orthogonal
 // to the nsIFrame::nsReflowStatus completion bits.
 #define NS_INLINE_BREAK              0x0100

From 5e7f3b9df5ffe9589d1a37c5c2f5e3d75cd1b1b9 Mon Sep 17 00:00:00 2001
From: Mats Palmgren 
Date: Fri, 19 Dec 2014 16:28:43 +0000
Subject: [PATCH 173/183] Bug 447660 part 1 - Replace the #define
 DISABLE_FLOAT_BREAKING_IN_COLUMNS with a pref to enable fragmenting of floats
 inside columns.  Set the pref enabled by default in non-RELEASE builds only. 
 r=roc

---
 layout/generic/crashtests/crashtests.list          |  3 ++-
 layout/generic/nsBlockFrame.cpp                    |  5 +----
 layout/generic/nsBlockReflowState.cpp              | 14 +++++++++++++-
 layout/generic/nsBlockReflowState.h                |  4 +++-
 .../bugs/563584-6-columns-ref-enabled.html         |  8 ++++++++
 layout/reftests/bugs/reftest.list                  |  6 ++++--
 layout/reftests/pagination/reftest.list            |  6 ++++--
 modules/libpref/init/all.js                        |  7 +++++++
 8 files changed, 42 insertions(+), 11 deletions(-)
 create mode 100644 layout/reftests/bugs/563584-6-columns-ref-enabled.html

diff --git a/layout/generic/crashtests/crashtests.list b/layout/generic/crashtests/crashtests.list
index c2a8eb51cd93..7e5917c24723 100644
--- a/layout/generic/crashtests/crashtests.list
+++ b/layout/generic/crashtests/crashtests.list
@@ -425,7 +425,8 @@ asserts(0-1) load 592118.html
 load 594808-1.html
 load 595435-1.xhtml
 load 595740-1.html
-load 600100.xhtml
+pref(layout.float-fragments-inside-column.enabled,true) asserts(1) load 600100.xhtml # bug 866955
+pref(layout.float-fragments-inside-column.enabled,false) load 600100.xhtml
 load 603490-1.html
 load 603510-1.html
 load 604314-1.html
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 08ec8d5abffc..10af9c0c4b2c 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -58,8 +58,6 @@ static const int MIN_LINES_NEEDING_CURSOR = 20;
 
 static const char16_t kDiscCharacter = 0x2022;
 
-#define DISABLE_FLOAT_BREAKING_IN_COLUMNS
-
 using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::layout;
@@ -5862,8 +5860,8 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
                        ? NS_UNCONSTRAINEDSIZE
                        : std::max(0, aState.ContentBEnd() - aState.mBCoord);
 
-#ifdef DISABLE_FLOAT_BREAKING_IN_COLUMNS
   if (availBSize != NS_UNCONSTRAINEDSIZE &&
+      !aState.GetFlag(BRS_FLOAT_FRAGMENTS_INSIDE_COLUMN_ENABLED) &&
       nsLayoutUtils::GetClosestFrameOfType(this, nsGkAtoms::columnSetFrame)) {
     // Tell the float it has unrestricted block-size, so it won't break.
     // If the float doesn't actually fit in the column it will fail to be
@@ -5871,7 +5869,6 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
     // overflow.
     availBSize = NS_UNCONSTRAINEDSIZE;
   }
-#endif
 
   return LogicalRect(wm, aState.ContentIStart(), aState.ContentBStart(),
                      availISize, availBSize);
diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp
index 9ed818c14491..bcb9c53cb501 100644
--- a/layout/generic/nsBlockReflowState.cpp
+++ b/layout/generic/nsBlockReflowState.cpp
@@ -15,6 +15,7 @@
 #include "nsPresContext.h"
 #include "nsIFrameInlines.h"
 #include "mozilla/AutoRestore.h"
+#include "mozilla/Preferences.h"
 #include 
 
 #ifdef DEBUG
@@ -24,6 +25,9 @@
 using namespace mozilla;
 using namespace mozilla::layout;
 
+static bool sFloatFragmentsInsideColumnEnabled;
+static bool sFloatFragmentsInsideColumnPrefCached;
+
 nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
                                        nsPresContext* aPresContext,
                                        nsBlockFrame* aFrame,
@@ -46,6 +50,13 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
     mFloatBreakType(NS_STYLE_CLEAR_NONE),
     mConsumedBSize(aConsumedBSize)
 {
+  if (!sFloatFragmentsInsideColumnPrefCached) {
+    sFloatFragmentsInsideColumnPrefCached = true;
+    Preferences::AddBoolVarCache(&sFloatFragmentsInsideColumnEnabled,
+                                 "layout.float-fragments-inside-column.enabled");
+  }
+  SetFlag(BRS_FLOAT_FRAGMENTS_INSIDE_COLUMN_ENABLED, sFloatFragmentsInsideColumnEnabled);
+  
   WritingMode wm = aReflowState.GetWritingMode();
   SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nullptr);
   SetFlag(BRS_ISOVERFLOWCONTAINER, IS_TRUE_OVERFLOW_CONTAINER(aFrame));
@@ -859,12 +870,13 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
 
   // In the case that we're in columns and not splitting floats, we need
   // to check here that the float's height fit, and if it didn't, bail.
-  // (This code is only for DISABLE_FLOAT_BREAKING_IN_COLUMNS .)
+  // (controlled by the pref "layout.float-fragments-inside-column.enabled")
   //
   // Likewise, if none of the float fit, and it needs to be pushed in
   // its entirety to the next page (NS_FRAME_IS_TRUNCATED or
   // NS_INLINE_IS_BREAK_BEFORE), we need to do the same.
   if ((ContentBSize() != NS_UNCONSTRAINEDSIZE &&
+       !GetFlag(BRS_FLOAT_FRAGMENTS_INSIDE_COLUMN_ENABLED) &&
        adjustedAvailableSpace.BSize(wm) == NS_UNCONSTRAINEDSIZE &&
        !mustPlaceFloat &&
        aFloat->BSize(wm) + floatMargin.BStartEnd(wm) >
diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h
index 9bb060db1b78..3b13a328ada9 100644
--- a/layout/generic/nsBlockReflowState.h
+++ b/layout/generic/nsBlockReflowState.h
@@ -32,7 +32,9 @@ class nsOverflowContinuationTracker;
 #define BRS_ISOVERFLOWCONTAINER   0x00000100
 // Our mPushedFloats list is stored on the blocks' proptable
 #define BRS_PROPTABLE_FLOATCLIST  0x00000200
-#define BRS_LASTFLAG              BRS_PROPTABLE_FLOATCLIST
+// Set when the pref layout.float-fragments-inside-column.enabled is true.
+#define BRS_FLOAT_FRAGMENTS_INSIDE_COLUMN_ENABLED 0x00000400
+#define BRS_LASTFLAG              BRS_FLOAT_FRAGMENTS_INSIDE_COLUMN_ENABLED
 
 class nsBlockReflowState {
 public:
diff --git a/layout/reftests/bugs/563584-6-columns-ref-enabled.html b/layout/reftests/bugs/563584-6-columns-ref-enabled.html
new file mode 100644
index 000000000000..56ecf414f79d
--- /dev/null
+++ b/layout/reftests/bugs/563584-6-columns-ref-enabled.html
@@ -0,0 +1,8 @@
+
+Testcase for float breaking
+
+  
+
+
+
+
diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 884758254948..68c79c360090 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -742,7 +742,8 @@ fails == 385823-2b.html 385823-2-ref.html == 386014-1c.html 386014-1-ref.html == 386065-1.html 386065-1-ref.html == 386065-2.html about:blank -skip-if(B2G) fails == 386147-1.html 386147-1-ref.html # bug 447460 +test-pref(layout.float-fragments-inside-column.enabled,false) skip-if(B2G) fails == 386147-1.html 386147-1-ref.html +test-pref(layout.float-fragments-inside-column.enabled,true) skip-if(B2G) == 386147-1.html 386147-1-ref.html == 386310-1a.html 386310-1-ref.html == 386310-1b.html 386310-1-ref.html == 386310-1c.html 386310-1-ref.html @@ -1522,7 +1523,8 @@ skip-if(B2G) == 563584-2.html 563584-2-ref.html skip-if(B2G) == 563584-3.html 563584-3-ref.html skip-if(B2G) == 563584-4.html 563584-4-ref.html == 563584-5.html 563584-5-ref.html -== 563584-6-columns.html 563584-6-columns-ref.html +test-pref(layout.float-fragments-inside-column.enabled,false) == 563584-6-columns.html 563584-6-columns-ref.html +test-pref(layout.float-fragments-inside-column.enabled,true) == 563584-6-columns.html 563584-6-columns-ref-enabled.html skip-if(B2G) == 563584-6-printing.html 563584-6-printing-ref.html skip-if(B2G) == 563584-7.html 563584-7-ref.html # FIXME: It would be nice to have variants of these -8 tests for the diff --git a/layout/reftests/pagination/reftest.list b/layout/reftests/pagination/reftest.list index 8227a1370dd7..2e0eadb80dd5 100644 --- a/layout/reftests/pagination/reftest.list +++ b/layout/reftests/pagination/reftest.list @@ -31,9 +31,11 @@ fails == border-breaking-004-cols.xhtml border-breaking-002-cols.ref.xhtml == content-inserted-008.xhtml content-inserted-001.ref.xhtml == content-inserted-009.xhtml content-inserted-002.ref.xhtml == dynamic-abspos-overflow-01-cols.xhtml dynamic-abspos-overflow-01-cols.ref.xhtml -fails == float-clear-000.html float-clear-000.ref.html +test-pref(layout.float-fragments-inside-column.enabled,false) fails == float-clear-000.html float-clear-000.ref.html +test-pref(layout.float-fragments-inside-column.enabled,true) == float-clear-000.html float-clear-000.ref.html fails == float-clear-001.html float-clear-000.ref.html -fails == float-clear-002.html float-clear-000.ref.html +test-pref(layout.float-fragments-inside-column.enabled,false) fails == float-clear-002.html float-clear-000.ref.html +test-pref(layout.float-fragments-inside-column.enabled,true) == float-clear-002.html float-clear-000.ref.html fails == float-clear-003.html float-clear-000.ref.html == float-clear-000-print.html float-clear-000-print.ref.html == float-clear-001-print.html float-clear-000-print.ref.html diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index f532dccadef6..fb7e30a77b19 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2247,6 +2247,13 @@ pref("layout.frame_rate.precise", false); // pref to control whether layout warnings that are hit quite often are enabled pref("layout.spammy_warnings.enabled", true); +// Should we fragment floats inside CSS column layout? +#ifdef RELEASE_BUILD +pref("layout.float-fragments-inside-column.enabled", false); +#else +pref("layout.float-fragments-inside-column.enabled", true); +#endif + // Is support for the Web Animations API enabled? #ifdef RELEASE_BUILD pref("dom.animations-api.core.enabled", false); From 4bd859f70844ad3c45df3f2b019572d482c2772d Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Fri, 19 Dec 2014 16:28:43 +0000 Subject: [PATCH 174/183] Bug 447660 part 2 - Mark an existing next-in-flow of a float that is split due to it being NOT_COMPLETE as NOT being an overflow container. r=roc --- layout/generic/nsBlockFrame.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 10af9c0c4b2c..6a63078ae0c7 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -4066,6 +4066,9 @@ nsBlockFrame::SplitFloat(nsBlockReflowState& aState, if (oldParent != this) { ReparentFrame(nextInFlow, oldParent, this); } + if (!NS_FRAME_OVERFLOW_IS_INCOMPLETE(aFloatStatus)) { + nextInFlow->RemoveStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); + } } else { nextInFlow = aState.mPresContext->PresShell()->FrameConstructor()-> CreateContinuingFrame(aState.mPresContext, aFloat, this); @@ -7223,10 +7226,11 @@ nsBlockFrame::ComputeFinalBSize(const nsHTMLReflowState& aReflowState, computedBSizeLeftOver), aBorderPadding.BEnd(wm)); - if (NS_FRAME_IS_NOT_COMPLETE(*aStatus) - && aFinalSize.BSize(wm) < aReflowState.AvailableBSize()) { - // We ran out of height on this page but we're incomplete - // Set status to complete except for overflow + if (NS_FRAME_IS_NOT_COMPLETE(*aStatus) && + aFinalSize.BSize(wm) < aReflowState.AvailableBSize()) { + // We fit in the available space - change status to OVERFLOW_INCOMPLETE. + // XXXmats why didn't Reflow report OVERFLOW_INCOMPLETE in the first place? + // XXXmats and why exclude the case when our size == AvailableBSize? NS_FRAME_SET_OVERFLOW_INCOMPLETE(*aStatus); } From 5f0c10b686a1f2c42bbaab98e79ff1011a687275 Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Fri, 19 Dec 2014 16:28:43 +0000 Subject: [PATCH 175/183] Bug 447660 part 3 - When collecting / pushing a float, make sure to also pick up its next-in-flows that are in same block. r=roc Move the AssertNoDuplicateContinuations in DrainPushedFloats earlier because DrainOverflowLines() sometimes picks up overflow line with a placeholder for a float that has a next-in-flow in this block and unmark those floats as pushed floats because they aren't anymore. Change AppendPushedFloat to push any next-in-flows that are in the same block as the given float too. Make DoCollectFloats collect next-in-flows in the same block. Make VerifyOverflowSituation check some float list invariants too. --- layout/generic/nsBlockFrame.cpp | 92 ++++++++++++++++++++++----- layout/generic/nsBlockReflowState.cpp | 19 ++++-- layout/generic/nsBlockReflowState.h | 10 ++- 3 files changed, 97 insertions(+), 24 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 6a63078ae0c7..ff0820860417 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -1101,6 +1101,15 @@ nsBlockFrame::Reflow(nsPresContext* aPresContext, AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN); } +#ifdef DEBUG + // Between when we drain pushed floats and when we complete reflow, + // we're allowed to have multiple continuations of the same float on + // our floats list, since a first-in-flow might get pushed to a later + // continuation of its containing block. But it's not permitted + // outside that time. + nsLayoutUtils::AssertNoDuplicateContinuations(this, mFloats); +#endif + // ALWAYS drain overflow. We never want to leave the previnflow's // overflow lines hanging around; block reflow depends on the // overflow line lists being cleared out between reflow passes. @@ -4058,6 +4067,10 @@ nsBlockFrame::SplitFloat(nsBlockReflowState& aState, nsIFrame* aFloat, nsReflowStatus aFloatStatus) { + MOZ_ASSERT(!NS_FRAME_IS_FULLY_COMPLETE(aFloatStatus), + "why split the frame if it's fully complete?"); + MOZ_ASSERT(aState.mBlock == this); + nsIFrame* nextInFlow = aFloat->GetNextInFlow(); if (nextInFlow) { nsContainerFrame *oldParent = nextInFlow->GetParent(); @@ -4073,11 +4086,9 @@ nsBlockFrame::SplitFloat(nsBlockReflowState& aState, nextInFlow = aState.mPresContext->PresShell()->FrameConstructor()-> CreateContinuingFrame(aState.mPresContext, aFloat, this); } - if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aFloatStatus)) - aFloat->GetNextInFlow()->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); - - // The containing block is now overflow-incomplete. - NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); + if (NS_FRAME_OVERFLOW_IS_INCOMPLETE(aFloatStatus)) { + nextInFlow->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER); + } if (aFloat->StyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) { aState.mFloatManager->SetSplitLeftFloatAcrossBreak(); @@ -4087,7 +4098,8 @@ nsBlockFrame::SplitFloat(nsBlockReflowState& aState, aState.mFloatManager->SetSplitRightFloatAcrossBreak(); } - aState.AppendPushedFloat(nextInFlow); + aState.AppendPushedFloatChain(nextInFlow); + NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus); return NS_OK; } @@ -4538,6 +4550,15 @@ nsBlockFrame::DrainOverflowLines() // Make the overflow out-of-flow frames mine too. nsAutoOOFFrameList oofs(prevBlock); if (oofs.mList.NotEmpty()) { + // In case we own a next-in-flow of any of the drained frames, then + // those are now not PUSHED_FLOATs anymore. + for (nsFrameList::Enumerator e(oofs.mList); !e.AtEnd(); e.Next()) { + nsIFrame* nif = e.get()->GetNextInFlow(); + for (; nif && nif->GetParent() == this; nif = nif->GetNextInFlow()) { + MOZ_ASSERT(mFloats.ContainsFrame(nif)); + nif->RemoveStateBits(NS_FRAME_IS_PUSHED_FLOAT); + } + } ReparentFrames(oofs.mList, prevBlock, this); mFloats.InsertFrames(nullptr, nullptr, oofs.mList); } @@ -4583,6 +4604,10 @@ nsBlockFrame::DrainSelfOverflowList() mFrames.AppendFrames(nullptr, ourOverflowLines->mFrames); mLines.splice(mLines.end(), ourOverflowLines->mLines); } + +#ifdef DEBUG + VerifyOverflowSituation(); +#endif return true; } @@ -4610,15 +4635,6 @@ nsBlockFrame::DrainSelfOverflowList() void nsBlockFrame::DrainPushedFloats(nsBlockReflowState& aState) { -#ifdef DEBUG - // Between when we drain pushed floats and when we complete reflow, - // we're allowed to have multiple continuations of the same float on - // our floats list, since a first-in-flow might get pushed to a later - // continuation of its containing block. But it's not permitted - // outside that time. - nsLayoutUtils::AssertNoDuplicateContinuations(this, mFloats); -#endif - // If we're getting reflowed multiple times without our // next-continuation being reflowed, we might need to pull back floats // that we just put in the list to be pushed to our next-in-flow. @@ -6086,7 +6102,7 @@ nsBlockFrame::ReflowPushedFloats(nsBlockReflowState& aState, nsIFrame *prevContinuation = f->GetPrevContinuation(); if (prevContinuation && prevContinuation->GetParent() == f->GetParent()) { mFloats.RemoveFrame(f); - aState.AppendPushedFloat(f); + aState.AppendPushedFloatChain(f); f = !prev ? mFloats.FirstChild() : prev->GetNextSibling(); continue; } @@ -7014,9 +7030,10 @@ nsBlockFrame::DoCollectFloats(nsIFrame* aFrame, nsFrameList& aList, nsIFrame *outOfFlowFrame = aFrame->GetType() == nsGkAtoms::placeholderFrame ? nsLayoutUtils::GetFloatFromPlaceholder(aFrame) : nullptr; - if (outOfFlowFrame && outOfFlowFrame->GetParent() == this) { + while (outOfFlowFrame && outOfFlowFrame->GetParent() == this) { RemoveFloat(outOfFlowFrame); aList.AppendFrame(nullptr, outOfFlowFrame); + outOfFlowFrame = outOfFlowFrame->GetNextInFlow(); // FIXME: By not pulling floats whose parent is one of our // later siblings, are we risking the pushed floats getting // out-of-order? @@ -7345,6 +7362,47 @@ nsBlockFrame::VerifyLines(bool aFinalCheckOK) void nsBlockFrame::VerifyOverflowSituation() { + // Overflow out-of-flows must not have a next-in-flow in mFloats or mFrames. + nsFrameList* oofs = GetOverflowOutOfFlows() ; + if (oofs) { + for (nsFrameList::Enumerator e(*oofs); !e.AtEnd(); e.Next()) { + nsIFrame* nif = e.get()->GetNextInFlow(); + MOZ_ASSERT(!nif || (!mFloats.ContainsFrame(nif) && !mFrames.ContainsFrame(nif))); + } + } + + // Pushed floats must not have a next-in-flow in mFloats or mFrames. + oofs = GetPushedFloats(); + if (oofs) { + for (nsFrameList::Enumerator e(*oofs); !e.AtEnd(); e.Next()) { + nsIFrame* nif = e.get()->GetNextInFlow(); + MOZ_ASSERT(!nif || (!mFloats.ContainsFrame(nif) && !mFrames.ContainsFrame(nif))); + } + } + + // A child float next-in-flow's parent must be |this| or a next-in-flow of |this|. + // Later next-in-flows must have the same or later parents. + nsIFrame::ChildListID childLists[] = { nsIFrame::kFloatList, + nsIFrame::kPushedFloatsList }; + for (size_t i = 0; i < ArrayLength(childLists); ++i) { + nsFrameList children(GetChildList(childLists[i])); + for (nsFrameList::Enumerator e(children); !e.AtEnd(); e.Next()) { + nsIFrame* parent = this; + nsIFrame* nif = e.get()->GetNextInFlow(); + for (; nif; nif = nif->GetNextInFlow()) { + bool found = false; + for (nsIFrame* p = parent; p; p = p->GetNextInFlow()) { + if (nif->GetParent() == p) { + parent = p; + found = true; + break; + } + } + MOZ_ASSERT(found, "next-in-flow is a child of parent earlier in the frame tree?"); + } + } + } + nsBlockFrame* flow = static_cast(FirstInFlow()); while (flow) { FrameLines* overflowLines = flow->GetOverflowLines(); diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index bcb9c53cb501..aa8a6fd7780f 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -433,11 +433,19 @@ nsBlockReflowState::SetupPushedFloatList() } void -nsBlockReflowState::AppendPushedFloat(nsIFrame* aFloatCont) +nsBlockReflowState::AppendPushedFloatChain(nsIFrame* aFloatCont) { SetupPushedFloatList(); - aFloatCont->AddStateBits(NS_FRAME_IS_PUSHED_FLOAT); - mPushedFloats->AppendFrame(mBlock, aFloatCont); + while (true) { + aFloatCont->AddStateBits(NS_FRAME_IS_PUSHED_FLOAT); + mPushedFloats->AppendFrame(mBlock, aFloatCont); + aFloatCont = aFloatCont->GetNextInFlow(); + if (!aFloatCont || aFloatCont->GetParent() != mBlock) { + break; + } + DebugOnly rv = mBlock->StealFrame(aFloatCont); + NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame should succeed"); + } } /** @@ -966,6 +974,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat) if (!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus)) { mBlock->SplitFloat(*this, aFloat, reflowStatus); + } else { + MOZ_ASSERT(!aFloat->GetNextInFlow()); } #ifdef NOISY_FLOATMANAGER @@ -1017,8 +1027,7 @@ nsBlockReflowState::PushFloatPastBreak(nsIFrame *aFloat) // isn't actually a continuation. DebugOnly rv = mBlock->StealFrame(aFloat); NS_ASSERTION(NS_SUCCEEDED(rv), "StealFrame should succeed"); - AppendPushedFloat(aFloat); - + AppendPushedFloatChain(aFloat); NS_FRAME_SET_OVERFLOW_INCOMPLETE(mReflowStatus); } diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h index 3b13a328ada9..d10f23d17aa1 100644 --- a/layout/generic/nsBlockReflowState.h +++ b/layout/generic/nsBlockReflowState.h @@ -216,8 +216,14 @@ public: // This method makes sure pushed floats are accessible to // StealFrame. Call it before adding any frames to mPushedFloats. void SetupPushedFloatList(); - // Use this method to append to mPushedFloats. - void AppendPushedFloat(nsIFrame* aFloatCont); + /** + * Append aFloatCont and its next-in-flows within the same block to + * mPushedFloats. aFloatCont should not be on any child list when + * making this call. Its next-in-flows will be removed from + * mBlock using StealFrame() before being added to mPushedFloats. + * All appended frames will be marked NS_FRAME_IS_PUSHED_FLOAT. + */ + void AppendPushedFloatChain(nsIFrame* aFloatCont); // Track child overflow continuations. nsOverflowContinuationTracker* mOverflowTracker; From a42b39e7f54eec150c1074001e386eabb4046edf Mon Sep 17 00:00:00 2001 From: Mats Palmgren Date: Fri, 19 Dec 2014 16:28:43 +0000 Subject: [PATCH 176/183] Bug 1111292 - Include the column gap(s) in the minimum width calculation when the number of columns is non-auto. r=roc --- layout/generic/nsColumnSetFrame.cpp | 5 +- layout/reftests/columns/min-width-1a.html | 6 +- layout/reftests/columns/min-width-2-ref.html | 43 ++++++++++++ layout/reftests/columns/min-width-2.html | 74 ++++++++++++++++++++ layout/reftests/columns/reftest.list | 3 +- 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 layout/reftests/columns/min-width-2-ref.html create mode 100644 layout/reftests/columns/min-width-2.html diff --git a/layout/generic/nsColumnSetFrame.cpp b/layout/generic/nsColumnSetFrame.cpp index 39a7cd70c99d..e5a93d0a97b0 100644 --- a/layout/generic/nsColumnSetFrame.cpp +++ b/layout/generic/nsColumnSetFrame.cpp @@ -389,9 +389,12 @@ nsColumnSetFrame::GetMinISize(nsRenderingContext *aRenderingContext) NS_ASSERTION(colStyle->mColumnCount > 0, "column-count and column-width can't both be auto"); // As available width reduces to zero, we still have mColumnCount columns, - // so multiply the child's min-width by the number of columns. + // so multiply the child's min-width by the number of columns (n) and + // include n-1 column gaps. colISize = iSize; iSize *= colStyle->mColumnCount; + nscoord colGap = GetColumnGap(this, colStyle); + iSize += colGap * (colStyle->mColumnCount - 1); // The multiplication above can make 'width' negative (integer overflow), // so use std::max to protect against that. iSize = std::max(iSize, colISize); diff --git a/layout/reftests/columns/min-width-1a.html b/layout/reftests/columns/min-width-1a.html index fca8db6cf6f1..4bbd82c3a6a9 100644 --- a/layout/reftests/columns/min-width-1a.html +++ b/layout/reftests/columns/min-width-1a.html @@ -4,14 +4,14 @@ -
+
-
+
diff --git a/layout/reftests/columns/min-width-2-ref.html b/layout/reftests/columns/min-width-2-ref.html new file mode 100644 index 000000000000..93e915da1736 --- /dev/null +++ b/layout/reftests/columns/min-width-2-ref.html @@ -0,0 +1,43 @@ + + + + Testcase for bug 1109571 + + + + + +
+
    xxxxxxxx
xxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+
    xxxxxxxx
xxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+ +
+
    xxxx
xxxxxxxx
xxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+ +
+
    xxxx
xxxxxxxx
xxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+ + + diff --git a/layout/reftests/columns/min-width-2.html b/layout/reftests/columns/min-width-2.html new file mode 100644 index 000000000000..f30d86bbdab7 --- /dev/null +++ b/layout/reftests/columns/min-width-2.html @@ -0,0 +1,74 @@ + + + + Testcase for bug + + + + + +
+
xxxx xxxx xxxx xxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+
+
xxxx xxxx xxxx xxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+ +
+
xxxx xxxx xxxx xxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+ +
+
xxxx xxxx xxxx xxxx
xxxxxxxxxxxxxxxxxxxxxxxxx
+
+ + + + + diff --git a/layout/reftests/columns/reftest.list b/layout/reftests/columns/reftest.list index add8d8ddb37c..da20f920b7d5 100644 --- a/layout/reftests/columns/reftest.list +++ b/layout/reftests/columns/reftest.list @@ -2,9 +2,10 @@ == pref-width-1a.html pref-width-1-ref.html == pref-width-1b.html pref-width-1-ref.html == pref-width-1c.html pref-width-1-ref.html -== min-width-1a.html min-width-1-ref.html +== min-width-1a.html pref-width-1-ref.html == min-width-1b.html min-width-1-ref.html == min-width-1c.html min-width-1-ref.html +== min-width-2.html min-width-2-ref.html == column-balancing-overflow-000.html column-balancing-overflow-000.ref.html == column-balancing-overflow-001.html column-balancing-overflow-000.ref.html == column-balancing-overflow-002.html column-balancing-overflow-002.ref.html From 76bc957f3e3ca7372ea954547b6686448a4588c1 Mon Sep 17 00:00:00 2001 From: "Nicolas B. Pierron" Date: Fri, 19 Dec 2014 17:32:48 +0100 Subject: [PATCH 177/183] Bug 1073033 part 2.5 - Fix rooting analysis in computeScopeChain. r=jandem CLOSED TREE --- js/src/jit/JitFrames.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index f02a555d576e..32a6c92ef997 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -2411,8 +2411,17 @@ InlineFrameIterator::computeScopeChain(Value scopeChainValue, MaybeReadFallback bool *hasCallObj) const { if (scopeChainValue.isObject()) { - if (hasCallObj) - *hasCallObj = isFunctionFrame() && callee(fallback)->isHeavyweight(); + if (hasCallObj) { + if (fallback.canRecoverResults()) { + RootedObject obj(fallback.maybeCx, &scopeChainValue.toObject()); + *hasCallObj = isFunctionFrame() && callee(fallback)->isHeavyweight(); + return obj; + } else { + JS::AutoSuppressGCAnalysis nogc; // If we cannot recover then we cannot GC. + *hasCallObj = isFunctionFrame() && callee(fallback)->isHeavyweight(); + } + } + return &scopeChainValue.toObject(); } From 6cfa91ef9bb9bccfd17c47cfdef8b30757e8def3 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 19 Dec 2014 11:37:26 -0500 Subject: [PATCH 178/183] Backed out changeset 70d9f3f8aaf1 (bug 1078975) for jsreftest failures. CLOSED TREE --- .../ecma_6/TypedArray/find-and-findIndex.js | 70 ------------------- 1 file changed, 70 deletions(-) delete mode 100644 js/src/tests/ecma_6/TypedArray/find-and-findIndex.js diff --git a/js/src/tests/ecma_6/TypedArray/find-and-findIndex.js b/js/src/tests/ecma_6/TypedArray/find-and-findIndex.js deleted file mode 100644 index 1e1b70fea264..000000000000 --- a/js/src/tests/ecma_6/TypedArray/find-and-findIndex.js +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Any copyright is dedicated to the Public Domain. - * https://creativecommons.org/publicdomain/zero/1.0/ - */ - -var BUGNUMBER = 1078975; -var summary = "Implement %TypedArray%.prototype.{find, findIndex}"; -print(BUGNUMBER + ": " + summary); - -const constructors = [ - Int8Array, - Uint8Array, - Uint8ClampedArray, - Int16Array, - Uint16Array, - Int32Array, - Uint32Array, - Float32Array, - Float64Array -]; - -const methods = ["find", "findIndex"]; - -constructors.forEach(constructor => { - methods.forEach(method => { - var arr = new constructor([0, 1, 2, 3, 4, 5]); - // test that this.length is never called - Object.defineProperty(arr, "length", { - get() { - throw new Error("length accessor called"); - } - }); - assertEq(arr[method].length, 1); - assertEq(arr[method](v => v === 3), 3); - assertEq(arr[method](v => v === 6), method === "find" ? undefined : -1); - - var thisValues = [undefined, null, true, 1, "foo", [], {}]; - if (typeof Symbol == "function") - thisValues.push(Symbol()); - - thisValues.forEach(thisArg => - assertThrowsInstanceOf(() => arr[method].call(thisArg, () => true), TypeError) - ); - - assertThrowsInstanceOf(() => arr[method](), TypeError); - assertThrowsInstanceOf(() => arr[method](1), TypeError); - - // ToDo neutering - arr = new constructor([1, 2, 3]); - assertEq(arr[method](v => v === 2), method === "find" ? 2 : 1); - neuter(arr.buffer, "change-data"); - assertEq(arr[method](v => v === 2), method === "find" ? undefined : -1); - }); -}); - -[Float32Array, Float64Array].forEach(constructor => { - var arr = new constructor([-0, 0, 1, 5, NaN, 6]); - assertEq(arr.find(v => Number.isNaN(v)), NaN); - assertEq(arr.findIndex(v => Number.isNaN(v)), 4); - - assertEq(arr.find(v => Object.is(v, 0)), 0); - assertEq(arr.findIndex(v => Object.is(v, 0)), 1); - - assertEq(arr.find(v => Object.is(v, -0)), -0); - assertEq(arr.findIndex(v => Object.is(v, -0)), 0); -}) - - -if (typeof reportCompare === "function") - reportCompare(true, true); From 08c961589b741381059fb84df7c4a2e5ff5e2e73 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Fri, 19 Dec 2014 12:06:59 -0500 Subject: [PATCH 179/183] Bug 1112059 - disable ts_paint_cold from talos. r=rvitillo --- testing/talos/talos.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testing/talos/talos.json b/testing/talos/talos.json index 86521822196c..84cb3a4ef74f 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -92,7 +92,7 @@ } }, "xperf": { - "tests": ["tp5n", "ts_paint_cold"], + "tests": ["tp5n"], "pagesets_url": "http://talos-bundles.pvt.build.mozilla.org/zips/tp5n.zip", "pagesets_parent_dir_path": "talos/page_load_test/", "pagesets_manifest_path": "talos/page_load_test/tp5n/tp5n.manifest", @@ -107,7 +107,7 @@ ] }, "xperf-e10s": { - "tests": ["tp5n", "ts_paint_cold"], + "tests": ["tp5n"], "pagesets_url": "http://talos-bundles.pvt.build.mozilla.org/zips/tp5n.zip", "pagesets_parent_dir_path": "talos/page_load_test/", "pagesets_manifest_path": "talos/page_load_test/tp5n/tp5n.manifest", From f33e0b3f59160800c606dd579f20f4480e1f59d0 Mon Sep 17 00:00:00 2001 From: Joel Maher Date: Fri, 19 Dec 2014 12:07:00 -0500 Subject: [PATCH 180/183] Bug 1113713 - deploy talos to the latest version [fix tests for e10s]. r=dminor --- testing/talos/talos.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/talos/talos.json b/testing/talos/talos.json index 84cb3a4ef74f..bf19b406e119 100644 --- a/testing/talos/talos.json +++ b/testing/talos/talos.json @@ -5,7 +5,7 @@ }, "global": { "talos_repo": "https://hg.mozilla.org/build/talos", - "talos_revision": "f21edb5a25b5" + "talos_revision": "ebc4327b8cb8" }, "extra_options": { "android": [ "--apkPath=%(apk_path)s" ] From c54bf723267233ec052030fc345963f788aebb2f Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Fri, 19 Dec 2014 12:07:20 -0500 Subject: [PATCH 181/183] Backed out changesets 6bd00fa70b00, 4e2f8f3b8f6b, and c89fec9c8b55 (bug 879717) for introducting multiple new intermittent failures. --HG-- extra : rebase_source : 4aad9383081f256484dd06e87f14cc82ecf186b5 --- dom/html/HTMLMediaElement.cpp | 118 ++++---------------- dom/html/HTMLMediaElement.h | 9 -- dom/media/test/manifest.js | 2 +- dom/media/test/mochitest.ini | 2 - dom/media/test/test_bug879717.html | 119 --------------------- dom/media/test/test_streams_srcObject.html | 2 - dom/media/test/test_video_dimensions.html | 67 ------------ 7 files changed, 21 insertions(+), 298 deletions(-) delete mode 100644 dom/media/test/test_bug879717.html delete mode 100644 dom/media/test/test_video_dimensions.html diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index 91650070698b..27d7e88c1e75 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -71,8 +71,6 @@ #include "mozilla/dom/MediaSource.h" #include "MediaMetadataManager.h" #include "MediaSourceDecoder.h" -#include "AudioStreamTrack.h" -#include "VideoStreamTrack.h" #include "AudioChannelService.h" @@ -665,10 +663,7 @@ void HTMLMediaElement::AbortExistingLoads() mHaveQueuedSelectResource = false; mSuspendedForPreloadNone = false; mDownloadSuspendedByCache = false; - mHasAudio = false; - mHasVideo = false; mSourcePointer = nullptr; - mLastNextFrameStatus = NEXT_FRAME_UNINITIALIZED; mTags = nullptr; @@ -902,30 +897,6 @@ void HTMLMediaElement::NotifyMediaTrackEnabled(MediaTrack* aTrack) } } -void HTMLMediaElement::NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream) -{ - if (!mSrcStream || mSrcStream != aStream) { - return; - } - - bool oldHasVideo = mHasVideo; - - nsAutoTArray,1> audioTracks; - mSrcStream->GetAudioTracks(audioTracks); - nsAutoTArray,1> videoTracks; - mSrcStream->GetVideoTracks(videoTracks); - - mHasAudio = !audioTracks.IsEmpty(); - mHasVideo = !videoTracks.IsEmpty(); - - if (IsVideo() && oldHasVideo != mHasVideo) { - // We are a video element and mHasVideo changed so update the screen wakelock - NotifyOwnerDocumentActivityChanged(); - } - - UpdateReadyStateForData(mLastNextFrameStatus); -} - void HTMLMediaElement::LoadFromSourceChildren() { NS_ASSERTION(mDelayingLoadEvent, @@ -2010,7 +1981,6 @@ HTMLMediaElement::HTMLMediaElement(already_AddRefed& aNo mCurrentLoadID(0), mNetworkState(nsIDOMHTMLMediaElement::NETWORK_EMPTY), mReadyState(nsIDOMHTMLMediaElement::HAVE_NOTHING), - mLastNextFrameStatus(NEXT_FRAME_UNINITIALIZED), mLoadWaitStatus(NOT_WAITING), mVolume(1.0), mPreloadAction(PRELOAD_UNDEFINED), @@ -2848,25 +2818,6 @@ private: bool mPendingNotifyOutput; }; -class HTMLMediaElement::MediaStreamTracksAvailableCallback: - public DOMMediaStream::OnTracksAvailableCallback -{ -public: - explicit MediaStreamTracksAvailableCallback(HTMLMediaElement* aElement, - DOMMediaStream::TrackTypeHints aExpectedTracks = 0): - DOMMediaStream::OnTracksAvailableCallback(aExpectedTracks), - mElement(aElement) - {} - virtual void NotifyTracksAvailable(DOMMediaStream* aStream) - { - NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); - - mElement->NotifyMediaStreamTracksAvailable(aStream); - } -private: - HTMLMediaElement* mElement; -}; - void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream) { NS_ASSERTION(!mSrcStream && !mSrcStreamListener, "Should have been ended already"); @@ -2888,26 +2839,22 @@ void HTMLMediaElement::SetupSrcMediaStreamPlayback(DOMMediaStream* aStream) if (mPausedForInactiveDocumentOrChannel) { GetSrcMediaStream()->ChangeExplicitBlockerCount(1); } - - mSrcStream->OnTracksAvailable(new MediaStreamTracksAvailableCallback(this, DOMMediaStream::HINT_CONTENTS_AUDIO)); - mSrcStream->OnTracksAvailable(new MediaStreamTracksAvailableCallback(this, DOMMediaStream::HINT_CONTENTS_VIDEO)); - - ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE); - ChangeDelayLoadStatus(false); GetSrcMediaStream()->AddAudioOutput(this); - SetVolumeInternal(); + GetSrcMediaStream()->SetAudioOutputVolume(this, float(mMuted ? 0.0 : mVolume)); VideoFrameContainer* container = GetVideoFrameContainer(); if (container) { GetSrcMediaStream()->AddVideoOutput(container); } - CheckAutoplayDataReady(); - // Note: we must call DisconnectTrackListListeners(...) before dropping // mSrcStream mSrcStream->ConstructMediaTracks(AudioTracks(), VideoTracks()); + ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); + DispatchAsyncEvent(NS_LITERAL_STRING("durationchange")); + DispatchAsyncEvent(NS_LITERAL_STRING("loadedmetadata")); + ChangeNetworkState(nsIDOMHTMLMediaElement::NETWORK_IDLE); AddRemoveSelfReference(); // FirstFrameLoaded() will be called when the stream has current data. } @@ -2988,11 +2935,6 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo, } else { UpdateMediaSize(aInfo->mVideo.mDisplay); } - - if (IsVideo() && aInfo->HasVideo()) { - // We are a video element playing video so update the screen wakelock - NotifyOwnerDocumentActivityChanged(); - } } void HTMLMediaElement::FirstFrameLoaded() @@ -3253,47 +3195,18 @@ bool HTMLMediaElement::ShouldCheckAllowOrigin() void HTMLMediaElement::UpdateReadyStateForData(MediaDecoderOwner::NextFrameStatus aNextFrame) { - mLastNextFrameStatus = aNextFrame; - - if (mDecoder && mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) { + if (mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) { // aNextFrame might have a next frame because the decoder can advance // on its own thread before MetadataLoaded gets a chance to run. // The arrival of more data can't change us out of this readyState. return; } - if (mSrcStream && mReadyState < nsIDOMHTMLMediaElement::HAVE_METADATA) { - if ((!mHasAudio && !mHasVideo) || - (IsVideo() && mHasVideo && mMediaSize == nsIntSize(-1, -1))) { - return; - } - - // We are playing a stream that has video and a video frame is now set. - // This means we have all metadata needed to change ready state. - MediaInfo mediaInfo; - mediaInfo.mAudio.mHasAudio = mHasAudio; - mediaInfo.mVideo.mHasVideo = mHasVideo; - if (mHasVideo) { - mediaInfo.mVideo.mDisplay = mMediaSize; - } - MetadataLoaded(&mediaInfo, nsAutoPtr(nullptr)); - } - if (aNextFrame == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE_SEEKING) { ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); return; } - if (IsVideo() && mHasVideo && !IsPlaybackEnded() && - GetImageContainer() && !GetImageContainer()->HasCurrentImage()) { - // Don't advance if we are playing video, but don't have a video frame. - // Also, if video became available after advancing to HAVE_CURRENT_DATA - // while we are still playing, we need to revert to HAVE_METADATA until - // a video frame is available. - ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA); - return; - } - if (mDownloadSuspendedByCache && mDecoder && !mDecoder->IsEnded()) { // The decoder has signaled that the download has been suspended by the // media cache. So move readyState into HAVE_ENOUGH_DATA, in case there's @@ -3441,14 +3354,14 @@ void HTMLMediaElement::ChangeNetworkState(nsMediaNetworkState aState) bool HTMLMediaElement::CanActivateAutoplay() { - // For stream inputs, we activate autoplay on HAVE_NOTHING because + // For stream inputs, we activate autoplay on HAVE_CURRENT_DATA because // this element itself might be blocking the stream from making progress by // being paused. return !mPausedForInactiveDocumentOrChannel && mAutoplaying && mPaused && ((mDecoder && mReadyState >= nsIDOMHTMLMediaElement::HAVE_ENOUGH_DATA) || - mSrcStream) && + (mSrcStream && mReadyState >= nsIDOMHTMLMediaElement::HAVE_CURRENT_DATA)) && HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) && mAutoplayEnabled && !IsEditable(); @@ -3477,14 +3390,24 @@ void HTMLMediaElement::CheckAutoplayDataReady() VideoFrameContainer* HTMLMediaElement::GetVideoFrameContainer() { - if (mVideoFrameContainer) - return mVideoFrameContainer; + // If we have loaded the metadata, and the size of the video is still + // (-1, -1), the media has no video. Don't go a create a video frame + // container. + if (mReadyState >= nsIDOMHTMLMediaElement::HAVE_METADATA && + mMediaSize == nsIntSize(-1, -1)) { + return nullptr; + } // Only video frames need an image container. if (!IsVideo()) { return nullptr; } + mHasVideo = true; + + if (mVideoFrameContainer) + return mVideoFrameContainer; + mVideoFrameContainer = new VideoFrameContainer(this, LayerManager::CreateAsynchronousImageContainer()); @@ -3597,7 +3520,6 @@ void HTMLMediaElement::NotifyDecoderPrincipalChanged() void HTMLMediaElement::UpdateMediaSize(nsIntSize size) { mMediaSize = size; - UpdateReadyStateForData(mLastNextFrameStatus); } void HTMLMediaElement::SuspendOrResumeElement(bool aPauseElement, bool aSuspendEvents) diff --git a/dom/html/HTMLMediaElement.h b/dom/html/HTMLMediaElement.h index ace9f320852e..413424d088ed 100644 --- a/dom/html/HTMLMediaElement.h +++ b/dom/html/HTMLMediaElement.h @@ -281,11 +281,6 @@ public: void NotifyMediaTrackEnabled(MediaTrack* aTrack); - /** - * Called when tracks become available to the source media stream. - */ - void NotifyMediaStreamTracksAvailable(DOMMediaStream* aStream); - virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE; /** @@ -617,7 +612,6 @@ protected: virtual ~HTMLMediaElement(); class MediaLoadListener; - class MediaStreamTracksAvailableCallback; class StreamListener; virtual void GetItemValueText(nsAString& text) MOZ_OVERRIDE; @@ -1042,9 +1036,6 @@ protected: nsMediaNetworkState mNetworkState; nsMediaReadyState mReadyState; - // Last value passed from codec or stream source to UpdateReadyStateForData. - NextFrameStatus mLastNextFrameStatus; - enum LoadAlgorithmState { // No load algorithm instance is waiting for a source to be added to the // media in order to continue loading. diff --git a/dom/media/test/manifest.js b/dom/media/test/manifest.js index 973bb3a8c21e..28c25f261640 100644 --- a/dom/media/test/manifest.js +++ b/dom/media/test/manifest.js @@ -14,7 +14,7 @@ var gSmallTests = [ { name:"seek.webm", type:"video/webm", width:320, height:240, duration:3.966 }, { name:"vp9.webm", type:"video/webm", width:320, height:240, duration:4 }, { name:"detodos.opus", type:"audio/ogg; codecs=opus", duration:2.9135 }, - { name:"gizmo.mp4", type:"video/mp4", width:560, height:320, duration:5.56 }, + { name:"gizmo.mp4", type:"video/mp4", duration:5.56 }, { name:"bogus.duh", type:"bogus/duh" } ]; diff --git a/dom/media/test/mochitest.ini b/dom/media/test/mochitest.ini index 236fe8a5490c..0b242c697c95 100644 --- a/dom/media/test/mochitest.ini +++ b/dom/media/test/mochitest.ini @@ -332,7 +332,6 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 [test_bug726904.html] [test_bug874897.html] -[test_bug879717.html] [test_bug883173.html] [test_bug895091.html] [test_bug895305.html] @@ -470,7 +469,6 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 914439 [test_reset_events_async.html] [test_reset_src.html] -[test_video_dimensions.html] [test_resume.html] skip-if = true # bug 1021673 [test_seek_out_of_range.html] diff --git a/dom/media/test/test_bug879717.html b/dom/media/test/test_bug879717.html deleted file mode 100644 index 35e68fb2860f..000000000000 --- a/dom/media/test/test_bug879717.html +++ /dev/null @@ -1,119 +0,0 @@ - - - - Test for bug 879717, check that a video element can be drawn into a canvas at various states of playback - - - - - -
-
-
- - diff --git a/dom/media/test/test_streams_srcObject.html b/dom/media/test/test_streams_srcObject.html index ed9c5866783e..446c5466b41a 100644 --- a/dom/media/test/test_streams_srcObject.html +++ b/dom/media/test/test_streams_srcObject.html @@ -45,8 +45,6 @@ function doTest() { } ++step; }); - a.play(); - b.play(); } diff --git a/dom/media/test/test_video_dimensions.html b/dom/media/test/test_video_dimensions.html deleted file mode 100644 index 30cb959c9bc6..000000000000 --- a/dom/media/test/test_video_dimensions.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - Test that a video element has set video dimensions on loadedmetadata - - - - - -
-
-
- - From 83b87ab7f17686101b4c3347a6a9043ff557c450 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Fri, 19 Dec 2014 12:07:04 -0500 Subject: [PATCH 182/183] Bug 1113313 - Rename these functions to better reflect what they do. r=billm --HG-- extra : rebase_source : ae61b3dd6dd5ce50a131a640060d7be57e562e4d --- dom/ipc/ContentParent.cpp | 14 +++++++------- dom/ipc/ContentParent.h | 10 +++++----- dom/ipc/PContent.ipdl | 11 ++++++----- .../manager/ssl/src/nsKeygenHandlerContent.cpp | 10 ++++++---- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 6fba7bf4e462..7cfd823bf1c2 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -4266,11 +4266,11 @@ ContentParent::RecvOpenAnonymousTemporaryFile(FileDescriptor *aFD) static NS_DEFINE_CID(kFormProcessorCID, NS_FORMPROCESSOR_CID); bool -ContentParent::RecvFormProcessValue(const nsString& oldValue, - const nsString& challenge, - const nsString& keytype, - const nsString& keyparams, - nsString* newValue) +ContentParent::RecvKeygenProcessValue(const nsString& oldValue, + const nsString& challenge, + const nsString& keytype, + const nsString& keyparams, + nsString* newValue) { nsCOMPtr formProcessor = do_GetService(kFormProcessorCID); @@ -4285,8 +4285,8 @@ ContentParent::RecvFormProcessValue(const nsString& oldValue, } bool -ContentParent::RecvFormProvideContent(nsString* aAttribute, - nsTArray* aContent) +ContentParent::RecvKeygenProvideContent(nsString* aAttribute, + nsTArray* aContent) { nsCOMPtr formProcessor = do_GetService(kFormProcessorCID); diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 38b2016c7f2e..70f88647d4fc 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -722,13 +722,13 @@ private: RecvOpenAnonymousTemporaryFile(FileDescriptor* aFD) MOZ_OVERRIDE; virtual bool - RecvFormProcessValue(const nsString& oldValue, const nsString& challenge, - const nsString& keytype, const nsString& keyparams, - nsString* newValue) MOZ_OVERRIDE; + RecvKeygenProcessValue(const nsString& oldValue, const nsString& challenge, + const nsString& keytype, const nsString& keyparams, + nsString* newValue) MOZ_OVERRIDE; virtual bool - RecvFormProvideContent(nsString* aAttribute, - nsTArray* aContent) MOZ_OVERRIDE; + RecvKeygenProvideContent(nsString* aAttribute, + nsTArray* aContent) MOZ_OVERRIDE; virtual PFileDescriptorSetParent* AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor&) MOZ_OVERRIDE; diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 4ee89e32db55..cd49ba903215 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -798,16 +798,17 @@ parent: * before one is submitted. This is urgent because an extension might use * a CPOW to synchronously submit a keygen element. */ - prio(urgent) sync FormProcessValue(nsString oldValue, - nsString challenge, - nsString keytype, - nsString keyparams) + prio(urgent) sync KeygenProcessValue(nsString oldValue, + nsString challenge, + nsString keytype, + nsString keyparams) returns (nsString newValue); /** * Called to provide the options for elements. */ - sync FormProvideContent() returns (nsString aAttribute, nsString[] aContent); + sync KeygenProvideContent() + returns (nsString aAttribute, nsString[] aContent); // Use only for testing! sync GetFileReferences(PersistenceType persistenceType, diff --git a/security/manager/ssl/src/nsKeygenHandlerContent.cpp b/security/manager/ssl/src/nsKeygenHandlerContent.cpp index 38329e84e623..3f3b422fe8ee 100644 --- a/security/manager/ssl/src/nsKeygenHandlerContent.cpp +++ b/security/manager/ssl/src/nsKeygenHandlerContent.cpp @@ -45,9 +45,9 @@ nsKeygenFormProcessorContent::ProcessValue(nsIDOMHTMLElement* aElement, nsString oldValue(aValue); nsString newValue; - unused << child->SendFormProcessValue(oldValue, challengeValue, - keyTypeValue, keyParamsValue, - &newValue); + unused << child->SendKeygenProcessValue(oldValue, challengeValue, + keyTypeValue, keyParamsValue, + &newValue); aValue.Assign(newValue); return NS_OK; @@ -70,7 +70,9 @@ nsKeygenFormProcessorContent::ProvideContent(const nsAString& aFormType, nsAString& aAttribute) { nsString attribute; - unused << ContentChild::GetSingleton()->SendFormProvideContent(&attribute, &aContent); + unused << + ContentChild::GetSingleton()->SendKeygenProvideContent(&attribute, + &aContent); aAttribute.Assign(attribute); return NS_OK; } From 02b0b22c1413df2eb94f0c743341f38b8baba423 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Fri, 19 Dec 2014 09:22:05 -0800 Subject: [PATCH 183/183] Bug 1087117 - Disable test_bug457672.html in e10s for intermittent failures --- dom/events/test/mochitest.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/events/test/mochitest.ini b/dom/events/test/mochitest.ini index f37ab466b6c7..72dea7a1175b 100644 --- a/dom/events/test/mochitest.ini +++ b/dom/events/test/mochitest.ini @@ -53,7 +53,7 @@ skip-if = buildapp == 'mulet' skip-if = buildapp == 'mulet' [test_bug456273.html] [test_bug457672.html] -skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' #CRASH_DUMP, RANDOM +skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s #CRASH_DUMP, RANDOM [test_bug489671.html] [test_bug493251.html] skip-if = buildapp == 'mulet' || (buildapp == 'b2g' && toolkit != 'gonk') #Bug 931116, b2g desktop specific, initial triage