author | Ryan VanderMeulen <ryanvm@gmail.com> |
Wed, 30 Jul 2014 17:13:20 -0400 | |
changeset 196928 | 005424a764da20705e205aeb0083b2ae7f4b559d |
parent 196927 | e71c55ff7219584f5920698244ffe2ed709692dd (current diff) |
parent 196837 | 44d47b88f3c2219cbec714af8bc6d2dd39ab3dce (diff) |
child 196929 | 81f81a4777f1b7c0db87b03b4bb9383aa101e128 |
child 197003 | 60eeadfddc0e9bd15fc899ae7a1a9b2b1483e279 |
child 197022 | b4771f70160177c1ea7566b64213b80c7f390f28 |
push id | 46994 |
push user | ryanvm@gmail.com |
push date | Wed, 30 Jul 2014 21:16:15 +0000 |
treeherder | mozilla-inbound@81f81a4777f1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 34.0a1 |
first release with | nightly linux32
005424a764da
/
34.0a1
/
20140731030206
/
files
nightly linux64
005424a764da
/
34.0a1
/
20140731030206
/
files
nightly mac
005424a764da
/
34.0a1
/
20140731030206
/
files
nightly win32
005424a764da
/
34.0a1
/
20140731030206
/
files
nightly win64
005424a764da
/
34.0a1
/
20140731030206
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
34.0a1
/
20140731030206
/
pushlog to previous
nightly linux64
34.0a1
/
20140731030206
/
pushlog to previous
nightly mac
34.0a1
/
20140731030206
/
pushlog to previous
nightly win32
34.0a1
/
20140731030206
/
pushlog to previous
nightly win64
34.0a1
/
20140731030206
/
pushlog to previous
|
--- a/accessible/jsat/moz.build +++ b/accessible/jsat/moz.build @@ -1,17 +1,15 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/accessibility' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.accessibility += [ 'AccessFu.jsm', 'Constants.jsm', 'ContentControl.jsm', 'EventManager.jsm', 'Gestures.jsm', 'OutputGenerator.jsm', 'PointerAdapter.jsm', 'Presentation.jsm',
--- a/addon-sdk/moz.build +++ b/addon-sdk/moz.build @@ -3,13 +3,11 @@ # 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/. BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] DIRS += ["source/modules/system"] -JS_MODULES_PATH = 'modules/sdk' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.sdk += [ 'source/app-extension/bootstrap.js', ]
--- a/addon-sdk/source/modules/system/moz.build +++ b/addon-sdk/source/modules/system/moz.build @@ -1,11 +1,9 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/sdk/system' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.sdk.system += [ 'XulApp.js', ]
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -2531,17 +2531,17 @@ let BrowserOnClick = { secHistogram.add(nsISecTel[bucketName + "WHY_BLOCKED"]); if (isMalware) { // Get the stop badware "why is this blocked" report url, // append the current url, and go there. try { let reportURL = formatURL("browser.safebrowsing.malware.reportURL", true); reportURL += location; - content.location = reportURL; + gBrowser.loadURI(reportURL); } catch (e) { Components.utils.reportError("Couldn't get malware report URL: " + e); } } else { // It's a phishing site, not malware openHelpLink("phishing-malware", false, "current"); } break; @@ -2556,26 +2556,27 @@ let BrowserOnClick = { /** * This functions prevents navigation from happening directly through the <a> * link in about:newtab (which is loaded in the parent and therefore would load * the next page also in the parent) and instructs the browser to open the url * in the current tab which will make it update the remoteness of the tab. */ onE10sAboutNewTab: function(event, ownerDoc) { let isTopFrame = (ownerDoc.defaultView.parent === ownerDoc.defaultView); - if (!isTopFrame || event.button != 0) { + if (!isTopFrame) { return; } let anchorTarget = event.originalTarget.parentNode; if (anchorTarget instanceof HTMLAnchorElement && anchorTarget.classList.contains("newtab-link")) { event.preventDefault(); - openUILinkIn(anchorTarget.href, "current"); + let where = whereToOpenLink(event, false, false); + openUILinkIn(anchorTarget.href, where); } }, /** * The about:tabcrashed can't do window.reload() because that * would reload the page but not use a remote browser. */ onAboutTabCrashed: function(event, ownerDoc) { @@ -2596,21 +2597,21 @@ let BrowserOnClick = { TabCrashReporter.reloadCrashedTabs(); } }, ignoreWarningButton: function (isMalware) { // Allow users to override and continue through to the site, // but add a notify bar as a reminder, so that they don't lose // track after, e.g., tab switching. - gBrowser.loadURIWithFlags(content.location.href, + gBrowser.loadURIWithFlags(gBrowser.currentURI.spec, nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER, null, null, null); - Services.perms.add(makeURI(content.location.href), "safe-browsing", + Services.perms.add(gBrowser.currentURI, "safe-browsing", Ci.nsIPermissionManager.ALLOW_ACTION, Ci.nsIPermissionManager.EXPIRE_SESSION); let buttons = [{ label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"), accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"), callback: function() { getMeOutOfHere(); } }]; @@ -2672,17 +2673,17 @@ function getMeOutOfHere() { url = prefs.getComplexValue("browser.startup.homepage", Ci.nsIPrefLocalizedString).data; // If url is a pipe-delimited set of pages, just take the first one. if (url.contains("|")) url = url.split("|")[0]; } catch(e) { Components.utils.reportError("Couldn't get homepage pref: " + e); } - content.location = url; + gBrowser.loadURI(url); } function BrowserFullScreen() { window.fullScreen = !window.fullScreen; } function _checkDefaultAndSwitchToMetro() {
--- a/browser/components/loop/.gitignore +++ b/browser/components/loop/.gitignore @@ -1,2 +1,1 @@ .module-cache -standalone/content/config.js
rename from browser/components/loop/content/libs/sdk-content/css/ot.css rename to browser/components/loop/content/shared/libs/sdk-content/css/ot.css
rename from browser/components/loop/content/libs/sdk-content/images/rtc/access-denied-chrome.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/access-denied-chrome.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/access-denied-copy-firefox.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/access-denied-copy-firefox.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/access-denied-firefox.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/access-denied-firefox.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/access-predenied-chrome.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/access-predenied-chrome.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/access-prompt-chrome.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/access-prompt-chrome.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/audioonly-publisher.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/audioonly-publisher.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/audioonly-subscriber.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/audioonly-subscriber.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/buttons.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/buttons.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/loader.gif rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/loader.gif
rename from browser/components/loop/content/libs/sdk-content/images/rtc/mic-off.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/mic-off.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/mic-on.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/mic-on.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/speaker-off.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/speaker-off.png
rename from browser/components/loop/content/libs/sdk-content/images/rtc/speaker-on.png rename to browser/components/loop/content/shared/libs/sdk-content/images/rtc/speaker-on.png
rename from browser/components/loop/content/libs/sdk-content/js/dynamic_config.min.js rename to browser/components/loop/content/shared/libs/sdk-content/js/dynamic_config.min.js
rename from browser/components/loop/content/libs/sdk.js rename to browser/components/loop/content/shared/libs/sdk.js
--- a/browser/components/loop/jar.mn +++ b/browser/components/loop/jar.mn @@ -48,24 +48,24 @@ browser.jar: content/browser/loop/shared/libs/lodash-2.4.1.js (content/shared/libs/lodash-2.4.1.js) content/browser/loop/shared/libs/jquery-2.1.0.js (content/shared/libs/jquery-2.1.0.js) content/browser/loop/shared/libs/backbone-1.1.2.js (content/shared/libs/backbone-1.1.2.js) # Shared sounds content/browser/loop/shared/sounds/Firefox-Long.ogg (content/shared/sounds/Firefox-Long.ogg) # Partner SDK assets - content/browser/loop/libs/sdk.js (content/libs/sdk.js) - content/browser/loop/sdk-content/css/ot.css (content/libs/sdk-content/css/ot.css) - content/browser/loop/sdk-content/js/dynamic_config.min.js (content/libs/sdk-content/js/dynamic_config.min.js) - content/browser/loop/sdk-content/images/rtc/access-denied-chrome.png (content/libs/sdk-content/images/rtc/access-denied-chrome.png) - content/browser/loop/sdk-content/images/rtc/access-denied-copy-firefox.png (content/libs/sdk-content/images/rtc/access-denied-copy-firefox.png) - content/browser/loop/sdk-content/images/rtc/access-denied-firefox.png (content/libs/sdk-content/images/rtc/access-denied-firefox.png) - content/browser/loop/sdk-content/images/rtc/access-predenied-chrome.png (content/libs/sdk-content/images/rtc/access-predenied-chrome.png) - content/browser/loop/sdk-content/images/rtc/access-prompt-chrome.png (content/libs/sdk-content/images/rtc/access-prompt-chrome.png) - content/browser/loop/sdk-content/images/rtc/audioonly-publisher.png (content/libs/sdk-content/images/rtc/audioonly-publisher.png) - content/browser/loop/sdk-content/images/rtc/audioonly-subscriber.png (content/libs/sdk-content/images/rtc/audioonly-subscriber.png) - content/browser/loop/sdk-content/images/rtc/buttons.png (content/libs/sdk-content/images/rtc/buttons.png) - content/browser/loop/sdk-content/images/rtc/loader.gif (content/libs/sdk-content/images/rtc/loader.gif) - content/browser/loop/sdk-content/images/rtc/mic-off.png (content/libs/sdk-content/images/rtc/mic-off.png) - content/browser/loop/sdk-content/images/rtc/mic-on.png (content/libs/sdk-content/images/rtc/mic-on.png) - content/browser/loop/sdk-content/images/rtc/speaker-off.png (content/libs/sdk-content/images/rtc/speaker-off.png) - content/browser/loop/sdk-content/images/rtc/speaker-on.png (content/libs/sdk-content/images/rtc/speaker-on.png) + content/browser/loop/libs/sdk.js (content/shared/libs/sdk.js) + content/browser/loop/sdk-content/css/ot.css (content/shared/libs/sdk-content/css/ot.css) + content/browser/loop/sdk-content/js/dynamic_config.min.js (content/shared/libs/sdk-content/js/dynamic_config.min.js) + content/browser/loop/sdk-content/images/rtc/access-denied-chrome.png (content/shared/libs/sdk-content/images/rtc/access-denied-chrome.png) + content/browser/loop/sdk-content/images/rtc/access-denied-copy-firefox.png (content/shared/libs/sdk-content/images/rtc/access-denied-copy-firefox.png) + content/browser/loop/sdk-content/images/rtc/access-denied-firefox.png (content/shared/libs/sdk-content/images/rtc/access-denied-firefox.png) + content/browser/loop/sdk-content/images/rtc/access-predenied-chrome.png (content/shared/libs/sdk-content/images/rtc/access-predenied-chrome.png) + content/browser/loop/sdk-content/images/rtc/access-prompt-chrome.png (content/shared/libs/sdk-content/images/rtc/access-prompt-chrome.png) + content/browser/loop/sdk-content/images/rtc/audioonly-publisher.png (content/shared/libs/sdk-content/images/rtc/audioonly-publisher.png) + content/browser/loop/sdk-content/images/rtc/audioonly-subscriber.png (content/shared/libs/sdk-content/images/rtc/audioonly-subscriber.png) + content/browser/loop/sdk-content/images/rtc/buttons.png (content/shared/libs/sdk-content/images/rtc/buttons.png) + content/browser/loop/sdk-content/images/rtc/loader.gif (content/shared/libs/sdk-content/images/rtc/loader.gif) + content/browser/loop/sdk-content/images/rtc/mic-off.png (content/shared/libs/sdk-content/images/rtc/mic-off.png) + content/browser/loop/sdk-content/images/rtc/mic-on.png (content/shared/libs/sdk-content/images/rtc/mic-on.png) + content/browser/loop/sdk-content/images/rtc/speaker-off.png (content/shared/libs/sdk-content/images/rtc/speaker-off.png) + content/browser/loop/sdk-content/images/rtc/speaker-on.png (content/shared/libs/sdk-content/images/rtc/speaker-on.png)
--- a/browser/components/loop/moz.build +++ b/browser/components/loop/moz.build @@ -1,22 +1,20 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. JAR_MANIFESTS += ['jar.mn'] -JS_MODULES_PATH = 'modules/loop' - XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] BROWSER_CHROME_MANIFESTS += [ 'test/mochitest/browser.ini', ] -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.loop += [ 'MozLoopAPI.jsm', 'MozLoopPushHandler.jsm', 'MozLoopService.jsm', 'MozLoopWorker.js', ]
--- a/browser/components/loop/standalone/.gitignore +++ b/browser/components/loop/standalone/.gitignore @@ -1,2 +1,5 @@ +.module-cache node_modules *.pyc +content/config.js +content/VERSION.txt
--- a/browser/components/loop/standalone/Makefile +++ b/browser/components/loop/standalone/Makefile @@ -16,13 +16,28 @@ lint: @$(NODE_LOCAL_BIN)/jshint *.js content test runserver: config @node server.js frontend: @echo "Not implemented yet." +# Try hg first, if not fall back to git. +SOURCE_STAMP := $(shell hg parent --template '{node|short}\n' 2> /dev/null) +ifndef SOURCE_STAMP +SOURCE_STAMP := $(shell git describe --always --tag) +endif + +SOURCE_DATE := $(shell hg parent --template '{date|date}\n' 2> /dev/null) +ifndef SOURCE_DATE +SOURCE_DATE := $(shell git log -1 --format="%H%n%aD") +endif + +version: + @echo $(SOURCE_STAMP) > content/VERSION.txt + @echo $(SOURCE_DATE) >> content/VERSION.txt + config: @echo "var loop = loop || {};" > content/config.js @echo "loop.config = loop.config || {};" >> content/config.js @echo "loop.config.serverUrl = '`echo $(LOOP_SERVER_URL)`';" >> content/config.js @echo "loop.config.pendingCallTimeout = `echo $(LOOP_PENDING_CALL_TIMEOUT)`;" >> content/config.js
--- a/browser/components/loop/standalone/content/index.html +++ b/browser/components/loop/standalone/content/index.html @@ -17,17 +17,25 @@ <h1>Loop</h1> </header> <div id="messages"></div> <div id="main"></div> <!-- libs --> - <script src="https://static.opentok.com/webrtc/v2.2/js/opentok.min.js"></script> + <script> + window.OTProperties = { + cdnURL: 'shared/libs/', + }; + window.OTProperties.assetURL = window.OTProperties.cdnURL + 'sdk-content/'; + window.OTProperties.configURL = window.OTProperties.assetURL + 'js/dynamic_config.min.js'; + window.OTProperties.cssURL = window.OTProperties.assetURL + 'css/ot.css'; + </script> + <script type="text/javascript" src="shared/libs/sdk.js"></script> <script type="text/javascript" src="libs/webl10n-20130617.js"></script> <script type="text/javascript" src="shared/libs/react-0.10.0.js"></script> <script type="text/javascript" src="shared/libs/jquery-2.1.0.js"></script> <script type="text/javascript" src="shared/libs/lodash-2.4.1.js"></script> <script type="text/javascript" src="shared/libs/backbone-1.1.2.js"></script> <!-- app scripts --> <script type="text/javascript" src="config.js"></script>
--- a/browser/components/sessionstore/moz.build +++ b/browser/components/sessionstore/moz.build @@ -17,19 +17,17 @@ XPIDL_SOURCES += [ XPIDL_MODULE = 'sessionstore' EXTRA_COMPONENTS += [ 'nsSessionStartup.js', 'nsSessionStore.js', 'nsSessionStore.manifest', ] -JS_MODULES_PATH = 'modules/sessionstore' - -EXTRA_JS_MODULES = [ +EXTRA_JS_MODULES.sessionstore = [ 'ContentRestore.jsm', 'DocShellCapabilities.jsm', 'FrameTree.jsm', 'GlobalState.jsm', 'PageStyle.jsm', 'PrivacyFilter.jsm', 'PrivacyLevel.jsm', 'RecentlyClosedTabsAndWindowsMenuUtils.jsm', @@ -41,13 +39,13 @@ EXTRA_JS_MODULES = [ 'SessionWorker.js', 'SessionWorker.jsm', 'TabAttributes.jsm', 'TabState.jsm', 'TabStateCache.jsm', 'Utils.jsm', ] -EXTRA_PP_JS_MODULES += [ +EXTRA_PP_JS_MODULES.sessionstore += [ 'SessionSaver.jsm', 'SessionStore.jsm', ]
--- a/browser/components/tabview/moz.build +++ b/browser/components/tabview/moz.build @@ -1,14 +1,12 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -EXTRA_JS_MODULES = ['modules/utils.jsm'] -JS_MODULES_PATH = 'modules/tabview' - +EXTRA_JS_MODULES.tabview = ['modules/utils.jsm'] BROWSER_CHROME_MANIFESTS += [ 'test/browser.ini', ] JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
--- a/browser/components/translation/moz.build +++ b/browser/components/translation/moz.build @@ -1,15 +1,13 @@ # 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/. -JS_MODULES_PATH = 'modules/translation' - -EXTRA_JS_MODULES = [ +EXTRA_JS_MODULES.translation = [ 'BingTranslator.jsm', 'cld2/cld-worker.js', 'cld2/cld-worker.js.mem', 'LanguageDetector.jsm', 'Translation.jsm', 'TranslationContentHandler.jsm', 'TranslationDocument.jsm' ]
--- a/browser/devtools/app-manager/moz.build +++ b/browser/devtools/app-manager/moz.build @@ -2,19 +2,17 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini'] -JS_MODULES_PATH = 'modules/devtools/app-manager' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools["app-manager"] += [ 'app-projects.js', 'app-validator.js', 'builtin-adb-store.js', 'connection-store.js', 'device-store.js', 'simulators-store.js', 'webapps-store.js', ]
--- a/browser/devtools/canvasdebugger/moz.build +++ b/browser/devtools/canvasdebugger/moz.build @@ -1,12 +1,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/canvasdebugger' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.canvasdebugger += [ 'panel.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/commandline/moz.build +++ b/browser/devtools/commandline/moz.build @@ -1,11 +1,9 @@ # 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/. -JS_MODULES_PATH = 'modules/devtools/commandline' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.commandline += [ 'commands-index.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/debugger/moz.build +++ b/browser/devtools/debugger/moz.build @@ -1,13 +1,11 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/debugger' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.debugger += [ 'debugger-commands.js', 'panel.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/eyedropper/moz.build +++ b/browser/devtools/eyedropper/moz.build @@ -1,14 +1,12 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/eyedropper' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.eyedropper += [ 'commands.js', 'eyedropper.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/inspector/moz.build +++ b/browser/devtools/inspector/moz.build @@ -1,14 +1,12 @@ # 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/. -JS_MODULES_PATH = 'modules/devtools/inspector' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.inspector += [ 'breadcrumbs.js', 'inspector-commands.js', 'inspector-panel.js', 'selector-search.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/markupview/moz.build +++ b/browser/devtools/markupview/moz.build @@ -1,14 +1,12 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] -JS_MODULES_PATH = 'modules/devtools/markupview' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.markupview += [ 'html-editor.js', 'markup-view.js', ]
--- a/browser/devtools/moz.build +++ b/browser/devtools/moz.build @@ -33,13 +33,11 @@ DIRS += [ EXTRA_COMPONENTS += [ 'devtools-clhandler.js', 'devtools-clhandler.manifest', ] JAR_MANIFESTS += ['jar.mn'] -JS_MODULES_PATH = 'modules/devtools' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools += [ 'main.js', ]
--- a/browser/devtools/netmonitor/moz.build +++ b/browser/devtools/netmonitor/moz.build @@ -1,12 +1,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/netmonitor' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.netmonitor += [ 'panel.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/profiler/moz.build +++ b/browser/devtools/profiler/moz.build @@ -1,18 +1,16 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] -JS_MODULES_PATH = 'modules/devtools/profiler' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.profiler += [ 'cleopatra.js', 'commands.js', 'consts.js', 'controller.js', 'panel.js', 'sidebar.js', ]
--- a/browser/devtools/responsivedesign/moz.build +++ b/browser/devtools/responsivedesign/moz.build @@ -1,11 +1,9 @@ # 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/. -JS_MODULES_PATH = 'modules/devtools' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools += [ 'resize-commands.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/scratchpad/moz.build +++ b/browser/devtools/scratchpad/moz.build @@ -1,14 +1,12 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/scratchpad' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.scratchpad += [ 'scratchpad-commands.js', 'scratchpad-panel.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/shadereditor/moz.build +++ b/browser/devtools/shadereditor/moz.build @@ -1,12 +1,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/shadereditor' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.shadereditor += [ 'panel.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/sourceeditor/moz.build +++ b/browser/devtools/sourceeditor/moz.build @@ -1,17 +1,15 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/sourceeditor' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.sourceeditor += [ 'autocomplete.js', 'css-autocompleter.js', 'css-tokenizer.js', 'debugger.js', 'editor.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/styleinspector/moz.build +++ b/browser/devtools/styleinspector/moz.build @@ -2,17 +2,15 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] -JS_MODULES_PATH = 'modules/devtools/styleinspector' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.styleinspector += [ 'computed-view.js', 'css-parsing-utils.js', 'rule-view.js', 'style-inspector-overlays.js', 'style-inspector.js', ]
--- a/browser/devtools/tilt/moz.build +++ b/browser/devtools/tilt/moz.build @@ -1,15 +1,13 @@ # 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/. -JS_MODULES_PATH = 'modules/devtools/tilt' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.tilt += [ 'tilt-commands.js', 'tilt-gl.js', 'tilt-math.js', 'tilt-utils.js', 'tilt-visualizer-style.js', 'tilt-visualizer.js', 'tilt.js', 'TiltWorkerCrafter.js',
--- a/browser/devtools/webaudioeditor/moz.build +++ b/browser/devtools/webaudioeditor/moz.build @@ -1,12 +1,10 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/webaudioeditor' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.webaudioeditor += [ 'panel.js' ] BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
--- a/browser/devtools/webconsole/moz.build +++ b/browser/devtools/webconsole/moz.build @@ -1,18 +1,16 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. BROWSER_CHROME_MANIFESTS += ['test/browser.ini'] -JS_MODULES_PATH = 'modules/devtools/webconsole' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.webconsole += [ 'console-commands.js', 'console-output.js', 'hudservice.js', 'network-panel.js', 'panel.js', 'webconsole.js', ]
--- a/browser/devtools/webide/moz.build +++ b/browser/devtools/webide/moz.build @@ -7,16 +7,14 @@ DIRS += [ 'content', 'components', 'themes', ] MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini'] -JS_MODULES_PATH = 'modules/devtools/webide' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.webide += [ 'modules/addons.js', 'modules/app-manager.js', 'modules/remote-resources.js', 'modules/runtimes.js' ]
--- a/browser/experiments/moz.build +++ b/browser/experiments/moz.build @@ -2,17 +2,15 @@ # 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/. EXTRA_COMPONENTS += [ 'Experiments.manifest', 'ExperimentsService.js', ] -JS_MODULES_PATH = 'modules/experiments' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.experiments += [ 'Experiments.jsm', ] XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] SPHINX_TREES['experiments'] = 'docs'
--- a/build/automationutils.py +++ b/build/automationutils.py @@ -72,16 +72,28 @@ DEBUGGER_INFO = { }, "lldb": { "interactive": True, "args": "--", "requiresEscapedArgs": True }, + # Visual Studio Debugger Support + "devenv.exe": { + "interactive": True, + "args": "-debugexe" + }, + + # Visual C++ Express Debugger Support + "wdexpress.exe": { + "interactive": True, + "args": "-debugexe" + }, + # valgrind doesn't explain much about leaks unless you set the # '--leak-check=full' flag. But there are a lot of objects that are # semi-deliberately leaked, so we set '--show-possibly-lost=no' to avoid # uninteresting output from those objects. We set '--smc-check==all-non-file' # and '--vex-iropt-register-updates=allregs-at-mem-access' so that valgrind # deals properly with JIT'd JavaScript code. "valgrind": { "interactive": False,
--- a/config/config.mk +++ b/config/config.mk @@ -50,17 +50,16 @@ endif HOST_CSRCS \ HOST_CMMSRCS \ HOST_LIBRARY_NAME \ HOST_PROGRAM \ HOST_SIMPLE_PROGRAMS \ IS_COMPONENT \ JAR_MANIFEST \ JAVA_JAR_TARGETS \ - JS_MODULES_PATH \ LD_VERSION_SCRIPT \ LIBRARY_NAME \ LIBS \ MAKE_FRAMEWORK \ MODULE \ MSVC_ENABLE_PGO \ NO_DIST_INSTALL \ PARALLEL_DIRS \
--- a/config/rules.mk +++ b/config/rules.mk @@ -1216,20 +1216,18 @@ endif EXTRA_MANIFESTS = $(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS)) ifneq (,$(EXTRA_MANIFESTS)) libs:: $(call mkdir_deps,$(FINAL_TARGET)) $(call py_action,buildlist,$(FINAL_TARGET)/chrome.manifest $(patsubst %,'manifest components/%',$(notdir $(EXTRA_MANIFESTS)))) endif ################################################################################ # Copy each element of EXTRA_JS_MODULES to -# $(FINAL_TARGET)/$(JS_MODULES_PATH). JS_MODULES_PATH defaults to "modules" -# if it is undefined. -JS_MODULES_PATH ?= modules -FINAL_JS_MODULES_PATH := $(FINAL_TARGET)/$(JS_MODULES_PATH) +# $(FINAL_TARGET)/modules. +FINAL_JS_MODULES_PATH := $(FINAL_TARGET)/modules ifdef EXTRA_JS_MODULES ifndef NO_DIST_INSTALL EXTRA_JS_MODULES_FILES := $(EXTRA_JS_MODULES) EXTRA_JS_MODULES_DEST := $(FINAL_JS_MODULES_PATH) INSTALL_TARGETS += EXTRA_JS_MODULES endif endif
--- a/configure.in +++ b/configure.in @@ -3839,17 +3839,16 @@ MOZ_LOCALE_SWITCHER= MOZ_ANDROID_SEARCH_ACTIVITY= MOZ_ANDROID_MLS_STUMBLER= ACCESSIBILITY=1 MOZ_TIME_MANAGER= MOZ_PAY= MOZ_AUDIO_CHANNEL_MANAGER= NSS_NO_LIBPKIX= MOZ_CONTENT_SANDBOX= -MOZ_GMP_SANDBOX= JSGC_USE_EXACT_ROOTING=1 JSGC_GENERATIONAL= case "$target_os" in mingw*) NS_ENABLE_TSF=1 AC_DEFINE(NS_ENABLE_TSF) ;; @@ -5079,16 +5078,30 @@ MOZ_ARG_DISABLE_BOOL(webm, MOZ_WEBM=1) if test -n "$MOZ_WEBM"; then AC_DEFINE(MOZ_WEBM) MOZ_VPX=1 fi; dnl ======================================================== +dnl = Apple platform decoder support +dnl ======================================================== +if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then + MOZ_APPLEMEDIA=1 +fi + +if test -n "$MOZ_APPLEMEDIA"; then + AC_DEFINE(MOZ_APPLEMEDIA) + # hack in frameworks for fmp4 - see bug 1029974 + # We load VideoToolbox and CoreMedia dynamically, so they don't appear here. + LDFLAGS="$LDFLAGS -framework AudioToolbox" +fi + +dnl ======================================================== dnl = DirectShow support dnl ======================================================== if test "$OS_ARCH" = "WINNT"; then dnl Enable DirectShow support by default. MOZ_DIRECTSHOW=1 fi MOZ_ARG_DISABLE_BOOL(directshow, @@ -5138,20 +5151,18 @@ MOZ_ARG_DISABLE_BOOL(ffmpeg, if test -n "$MOZ_FFMPEG"; then AC_DEFINE(MOZ_FFMPEG) fi; dnl ======================================================== dnl = Built-in fragmented MP4 support. dnl ======================================================== -if test -n "$MOZ_WMF" -o -n "$MOZ_FFMPEG"; then - dnl Enable fragmented MP4 parser on Windows by default. - dnl We will also need to enable it on other platforms as we implement - dnl platform decoder support there too. +if test -n "$MOZ_WMF" -o -n "$MOZ_FFMPEG" -o -n "$MOZ_APPLEMEDIA"; then + dnl Enable fragmented MP4 parser on platforms with decoder support. MOZ_FMP4=1 fi MOZ_ARG_DISABLE_BOOL(fmp4, [ --disable-fmp4 Disable support for in built Fragmented MP4 parsing], MOZ_FMP4=, MOZ_FMP4=1) @@ -5185,32 +5196,16 @@ MOZ_ARG_ENABLE_BOOL(android-omx, MOZ_ANDROID_OMX=1, MOZ_ANDROID_OMX=) if test -n "$MOZ_ANDROID_OMX"; then AC_DEFINE(MOZ_ANDROID_OMX) fi dnl ======================================================== -dnl = Disable platform MP3 decoder on OSX -dnl ======================================================== -if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then - MOZ_APPLEMEDIA=1 -fi - -MOZ_ARG_DISABLE_BOOL(apple-media, -[ --disable-apple-media Disable support for Apple AudioToolbox/VideoToolbox], - MOZ_APPLEMEDIA=, - MOZ_APPLEMEDIA=1) - -if test -n "$MOZ_APPLEMEDIA"; then - AC_DEFINE(MOZ_APPLEMEDIA) -fi - -dnl ======================================================== dnl = Enable getUserMedia support dnl ======================================================== MOZ_ARG_ENABLE_BOOL(media-navigator, [ --enable-media-navigator Enable support for getUserMedia], MOZ_MEDIA_NAVIGATOR=1, MOZ_MEDIA_NAVIGATOR=) if test -n "$MOZ_MEDIA_NAVIGATOR"; then @@ -6402,38 +6397,16 @@ MOZ_ARG_ENABLE_BOOL(content-sandbox, if test -n "$MOZ_CONTENT_SANDBOX"; then AC_DEFINE(MOZ_CONTENT_SANDBOX) fi AC_SUBST(MOZ_CONTENT_SANDBOX) dnl ======================================================== -dnl = Gecko Media Plugin sandboxing -dnl ======================================================== -case $OS_TARGET in -WINNT) - MOZ_GMP_SANDBOX=1 - ;; -Linux) - case $CPU_ARCH in - x86_64|x86) - MOZ_GMP_SANDBOX=1 - ;; - esac - ;; -esac - -if test -n "$MOZ_GMP_SANDBOX"; then - AC_DEFINE(MOZ_GMP_SANDBOX) -fi - -AC_SUBST(MOZ_GMP_SANDBOX) - -dnl ======================================================== dnl = dnl = Module specific options dnl = dnl ======================================================== MOZ_ARG_HEADER(Individual module options) dnl ======================================================== dnl = Disable feed handling components
--- a/content/base/public/nsDOMFile.h +++ b/content/base/public/nsDOMFile.h @@ -743,26 +743,16 @@ private: nsCOMPtr<nsIFile> mFile; bool mWholeFile; bool mStoredFile; }; } // dom namespace } // file namespace -class MOZ_STACK_CLASS nsDOMFileInternalUrlHolder { -public: - nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, nsIPrincipal* aPrincipal - MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~nsDOMFileInternalUrlHolder(); - nsAutoString mUrl; -private: - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - class nsDOMFileList MOZ_FINAL : public nsIDOMFileList, public nsWrapperCache { ~nsDOMFileList() {} public: nsDOMFileList(nsISupports *aParent) : mParent(aParent) {
--- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -1059,26 +1059,8 @@ nsDOMFileList::GetLength(uint32_t* aLeng NS_IMETHODIMP nsDOMFileList::Item(uint32_t aIndex, nsIDOMFile **aFile) { NS_IF_ADDREF(*aFile = Item(aIndex)); return NS_OK; } - -//////////////////////////////////////////////////////////////////////////// -// nsDOMFileInternalUrlHolder implementation - -nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile, - nsIPrincipal* aPrincipal - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) { - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - aFile->GetInternalUrl(aPrincipal, mUrl); -} - -nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() { - if (!mUrl.IsEmpty()) { - nsAutoCString narrowUrl; - CopyUTF16toUTF8(mUrl, narrowUrl); - nsBlobProtocolHandler::RemoveDataEntry(narrowUrl); - } -}
--- a/content/media/fmp4/MP4Decoder.cpp +++ b/content/media/fmp4/MP4Decoder.cpp @@ -12,16 +12,20 @@ #include "prlog.h" #ifdef XP_WIN #include "mozilla/WindowsVersion.h" #endif #ifdef MOZ_FFMPEG #include "FFmpegRuntimeLinker.h" #endif +#ifdef MOZ_APPLEMEDIA +#include "apple/AppleCMLinker.h" +#include "apple/AppleVTLinker.h" +#endif namespace mozilla { MediaDecoderStateMachine* MP4Decoder::CreateStateMachine() { return new MediaDecoderStateMachine(this, new MP4Reader(this)); } @@ -98,24 +102,50 @@ IsFFmpegAvailable() // If we can link to FFmpeg, then we can almost certainly play H264 and AAC // with it. return FFmpegRuntimeLinker::Link(); #endif } static bool +IsAppleAvailable() +{ +#ifndef MOZ_APPLEMEDIA + // Not the right platform. + return false; +#else + if (!Preferences::GetBool("media.apple.mp4.enabled", false)) { + // Disabled by preference. + return false; + } + // Attempt to load the required frameworks. + bool haveCoreMedia = AppleCMLinker::Link(); + if (!haveCoreMedia) { + return false; + } + bool haveVideoToolbox = AppleVTLinker::Link(); + if (!haveVideoToolbox) { + return false; + } + // All hurdles cleared! + return true; +#endif +} + +static bool HavePlatformMPEGDecoders() { return Preferences::GetBool("media.fragmented-mp4.use-blank-decoder") || #ifdef XP_WIN // We have H.264/AAC platform decoders on Windows Vista and up. IsVistaOrLater() || #endif IsFFmpegAvailable() || + IsAppleAvailable() || // TODO: Other platforms... false; } /* static */ bool MP4Decoder::IsEnabled() {
--- a/content/media/fmp4/PlatformDecoderModule.cpp +++ b/content/media/fmp4/PlatformDecoderModule.cpp @@ -6,16 +6,19 @@ #include "PlatformDecoderModule.h" #ifdef XP_WIN #include "WMFDecoderModule.h" #endif #ifdef MOZ_FFMPEG #include "FFmpegRuntimeLinker.h" #endif +#ifdef MOZ_APPLEMEDIA +#include "AppleDecoderModule.h" +#endif #include "mozilla/Preferences.h" #include "EMEDecoderModule.h" #include "mozilla/CDMProxy.h" #include "SharedThreadPool.h" #include "MediaTaskQueue.h" namespace mozilla { @@ -37,16 +40,19 @@ PlatformDecoderModule::Init() Preferences::AddBoolVarCache(&sUseBlankDecoder, "media.fragmented-mp4.use-blank-decoder"); Preferences::AddBoolVarCache(&sFFmpegDecoderEnabled, "media.fragmented-mp4.ffmpeg.enabled", false); #ifdef XP_WIN WMFDecoderModule::Init(); #endif +#ifdef MOZ_APPLEMEDIA + AppleDecoderModule::Init(); +#endif } class CreateTaskQueueTask : public nsRunnable { public: NS_IMETHOD Run() { MOZ_ASSERT(NS_IsMainThread()); mTaskQueue = new MediaTaskQueue(GetMediaDecodeThreadPool()); return NS_OK; @@ -112,12 +118,18 @@ PlatformDecoderModule::Create() return m.forget(); } #endif #ifdef MOZ_FFMPEG if (sFFmpegDecoderEnabled) { return FFmpegRuntimeLinker::CreateDecoderModule(); } #endif +#ifdef MOZ_APPLEMEDIA + nsAutoPtr<AppleDecoderModule> m(new AppleDecoderModule()); + if (NS_SUCCEEDED(m->Startup())) { + return m.forget(); + } +#endif return nullptr; } } // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleATDecoder.cpp @@ -0,0 +1,354 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <AudioToolbox/AudioToolbox.h> +#include "AppleUtils.h" +#include "MP4Reader.h" +#include "MP4Decoder.h" +#include "mozilla/RefPtr.h" +#include "mozilla/ReentrantMonitor.h" +#include "mp4_demuxer/DecoderData.h" +#include "nsIThread.h" +#include "AppleATDecoder.h" +#include "prlog.h" + +#ifdef PR_LOGGING +PRLogModuleInfo* GetDemuxerLog(); +#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__)) +#else +#define LOG(...) +#endif + +namespace mozilla { + +AppleATDecoder::AppleATDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* anAudioTaskQueue, + MediaDataDecoderCallback* aCallback) + : mConfig(aConfig) + , mTaskQueue(anAudioTaskQueue) + , mCallback(aCallback) + , mConverter(nullptr) + , mStream(nullptr) + , mCurrentAudioFrame(0) + , mSamplePosition(0) + , mHaveOutput(false) +{ + MOZ_COUNT_CTOR(AppleATDecoder); + LOG("Creating Apple AudioToolbox AAC decoder"); + LOG("Audio Decoder configuration: %s %d Hz %d channels %d bits per channel", + mConfig.mime_type, + mConfig.samples_per_second, + mConfig.channel_count, + mConfig.bits_per_sample); + // TODO: Verify aConfig.mime_type. +} + +AppleATDecoder::~AppleATDecoder() +{ + MOZ_COUNT_DTOR(AppleATDecoer); + MOZ_ASSERT(!mConverter); + MOZ_ASSERT(!mStream); +} + +static void +_MetadataCallback(void *aDecoder, + AudioFileStreamID aStream, + AudioFileStreamPropertyID aProperty, + UInt32 *aFlags) +{ + LOG("AppleATDecoder metadata callback"); + AppleATDecoder* decoder = static_cast<AppleATDecoder*>(aDecoder); + decoder->MetadataCallback(aStream, aProperty, aFlags); +} + +static void +_SampleCallback(void *aDecoder, + UInt32 aNumBytes, UInt32 aNumPackets, + const void *aData, + AudioStreamPacketDescription *aPackets) +{ + LOG("AppleATDecoder sample callback %u bytes %u packets", + aNumBytes, aNumPackets); + AppleATDecoder* decoder = static_cast<AppleATDecoder*>(aDecoder); + decoder->SampleCallback(aNumBytes, aNumPackets, aData, aPackets); +} + +nsresult +AppleATDecoder::Init() +{ + LOG("Initializing Apple AudioToolbox AAC decoder"); + AudioFileTypeID fileType = kAudioFileAAC_ADTSType; + OSStatus rv = AudioFileStreamOpen(this, + _MetadataCallback, + _SampleCallback, + fileType, + &mStream); + if (rv) { + NS_ERROR("Couldn't open AudioFileStream"); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult +AppleATDecoder::Input(mp4_demuxer::MP4Sample* aSample) +{ + LOG("mp4 input sample %p %lld us %lld pts%s %llu bytes audio", + aSample, + aSample->duration, + aSample->composition_timestamp, + aSample->is_sync_point ? " keyframe" : "", + (unsigned long long)aSample->size); + + // Queue a task to perform the actual decoding on a separate thread. + mTaskQueue->Dispatch( + NS_NewRunnableMethodWithArg<nsAutoPtr<mp4_demuxer::MP4Sample>>( + this, + &AppleATDecoder::SubmitSample, + nsAutoPtr<mp4_demuxer::MP4Sample>(aSample))); + + return NS_OK; +} + +nsresult +AppleATDecoder::Flush() +{ + LOG("Flushing AudioToolbox AAC decoder"); + OSStatus rv = AudioConverterReset(mConverter); + if (rv) { + LOG("Error %d resetting AudioConverter", rv); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult +AppleATDecoder::Drain() +{ + LOG("Draining AudioToolbox AAC decoder"); + mTaskQueue->AwaitIdle(); + return Flush(); +} + +nsresult +AppleATDecoder::Shutdown() +{ + LOG("Shutdown: Apple AudioToolbox AAC decoder"); + OSStatus rv1 = AudioConverterDispose(mConverter); + if (rv1) { + LOG("error %d disposing of AudioConverter", rv1); + } else { + mConverter = nullptr; + } + + OSStatus rv2 = AudioFileStreamClose(mStream); + if (rv2) { + LOG("error %d closing AudioFileStream", rv2); + } else { + mStream = nullptr; + } + + return (rv1 && rv2) ? NS_OK : NS_ERROR_FAILURE; +} + +void +AppleATDecoder::MetadataCallback(AudioFileStreamID aFileStream, + AudioFileStreamPropertyID aPropertyID, + UInt32* aFlags) +{ + if (aPropertyID == kAudioFileStreamProperty_ReadyToProducePackets) { + SetupDecoder(); + } +} + +struct PassthroughUserData { + AppleATDecoder* mDecoder; + UInt32 mNumPackets; + UInt32 mDataSize; + const void *mData; + AudioStreamPacketDescription *mPacketDesc; + bool mDone; +}; + +// Error value we pass through the decoder to signal that nothing +// has gone wrong during decoding, but more data is needed. +const uint32_t kNeedMoreData = 'MOAR'; + +static OSStatus +_PassthroughInputDataCallback(AudioConverterRef aAudioConverter, + UInt32 *aNumDataPackets /* in/out */, + AudioBufferList *aData /* in/out */, + AudioStreamPacketDescription **aPacketDesc, + void *aUserData) +{ + PassthroughUserData *userData = (PassthroughUserData *)aUserData; + if (userData->mDone) { + // We make sure this callback is run _once_, with all the data we received + // from |AudioFileStreamParseBytes|. When we return an error, the decoder + // simply passes the return value on to the calling method, + // |SampleCallback|; and flushes all of the audio frames it had + // buffered. It does not change the decoder's state. + LOG("requested too much data; returning\n"); + *aNumDataPackets = 0; + return kNeedMoreData; + } + + userData->mDone = true; + + LOG("AudioConverter wants %u packets of audio data\n", *aNumDataPackets); + + *aNumDataPackets = userData->mNumPackets; + *aPacketDesc = userData->mPacketDesc; + + aData->mBuffers[0].mNumberChannels = userData->mDecoder->mConfig.channel_count; + aData->mBuffers[0].mDataByteSize = userData->mDataSize; + aData->mBuffers[0].mData = const_cast<void *>(userData->mData); + + return noErr; +} + +void +AppleATDecoder::SampleCallback(uint32_t aNumBytes, + uint32_t aNumPackets, + const void* aData, + AudioStreamPacketDescription* aPackets) +{ + // Pick a multiple of the frame size close to a power of two + // for efficient allocation. + const uint32_t MAX_AUDIO_FRAMES = 128; + const uint32_t decodedSize = MAX_AUDIO_FRAMES * mConfig.channel_count * + sizeof(AudioDataValue); + + // Descriptions for _decompressed_ audio packets. ignored. + nsAutoArrayPtr<AudioStreamPacketDescription> + packets(new AudioStreamPacketDescription[MAX_AUDIO_FRAMES]); + + // This API insists on having packets spoon-fed to it from a callback. + // This structure exists only to pass our state and the result of the + // parser on to the callback above. + PassthroughUserData userData = + { this, aNumPackets, aNumBytes, aData, aPackets, false }; + + do { + // Decompressed audio buffer + nsAutoArrayPtr<uint8_t> decoded(new uint8_t[decodedSize]); + + AudioBufferList decBuffer; + decBuffer.mNumberBuffers = 1; + decBuffer.mBuffers[0].mNumberChannels = mConfig.channel_count; + decBuffer.mBuffers[0].mDataByteSize = decodedSize; + decBuffer.mBuffers[0].mData = decoded.get(); + + // in: the max number of packets we can handle from the decoder. + // out: the number of packets the decoder is actually returning. + UInt32 numFrames = MAX_AUDIO_FRAMES; + + OSStatus rv = AudioConverterFillComplexBuffer(mConverter, + _PassthroughInputDataCallback, + &userData, + &numFrames /* in/out */, + &decBuffer, + packets.get()); + + if (rv && rv != kNeedMoreData) { + LOG("Error decoding audio stream: %#x\n", rv); + mCallback->Error(); + break; + } + LOG("%d frames decoded", numFrames); + + // If we decoded zero frames then AudioConverterFillComplexBuffer is out + // of data to provide. We drained its internal buffer completely on the + // last pass. + if (numFrames == 0 && rv == kNeedMoreData) { + LOG("FillComplexBuffer out of data exactly\n"); + mCallback->InputExhausted(); + break; + } + + const int rate = mConfig.samples_per_second; + int64_t time = FramesToUsecs(mCurrentAudioFrame, rate).value(); + int64_t duration = FramesToUsecs(numFrames, rate).value(); + + LOG("pushed audio at time %lfs; duration %lfs\n", + (double)time / USECS_PER_S, (double)duration / USECS_PER_S); + + AudioData *audio = new AudioData(mSamplePosition, + time, duration, numFrames, + reinterpret_cast<AudioDataValue *>(decoded.forget()), + rate); + mCallback->Output(audio); + mHaveOutput = true; + + mCurrentAudioFrame += numFrames; + + if (rv == kNeedMoreData) { + // No error; we just need more data. + LOG("FillComplexBuffer out of data\n"); + mCallback->InputExhausted(); + break; + } + } while (true); +} + +void +AppleATDecoder::SetupDecoder() +{ + AudioStreamBasicDescription inputFormat, outputFormat; + // Fill in the input format description from the stream. + AppleUtils::GetProperty(mStream, + kAudioFileStreamProperty_DataFormat, &inputFormat); + + // Fill in the output format manually. + PodZero(&outputFormat); + outputFormat.mFormatID = kAudioFormatLinearPCM; + outputFormat.mSampleRate = inputFormat.mSampleRate; + outputFormat.mChannelsPerFrame = inputFormat.mChannelsPerFrame; +#if defined(MOZ_SAMPLE_TYPE_FLOAT32) + outputFormat.mBitsPerChannel = 32; + outputFormat.mFormatFlags = + kLinearPCMFormatFlagIsFloat | + 0; +#else +# error Unknown audio sample type +#endif + // Set up the decoder so it gives us one sample per frame + outputFormat.mFramesPerPacket = 1; + outputFormat.mBytesPerPacket = outputFormat.mBytesPerFrame + = outputFormat.mChannelsPerFrame * outputFormat.mBitsPerChannel / 8; + + OSStatus rv = AudioConverterNew(&inputFormat, &outputFormat, &mConverter); + if (rv) { + LOG("Error %d constructing AudioConverter", rv); + mConverter = nullptr; + mCallback->Error(); + } + mHaveOutput = false; +} + +void +AppleATDecoder::SubmitSample(nsAutoPtr<mp4_demuxer::MP4Sample> aSample) +{ + mSamplePosition = aSample->byte_offset; + OSStatus rv = AudioFileStreamParseBytes(mStream, + aSample->size, + aSample->data, + 0); + if (rv != noErr) { + LOG("Error %d parsing audio data", rv); + mCallback->Error(); + } + + // Sometimes we need multiple input samples before AudioToolbox + // starts decoding. If we haven't seen any output yet, ask for + // more data here. + if (!mHaveOutput) { + mCallback->InputExhausted(); + } +} + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleATDecoder.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_AppleATDecoder_h +#define mozilla_AppleATDecoder_h + +#include <AudioToolbox/AudioToolbox.h> +#include "PlatformDecoderModule.h" +#include "mozilla/RefPtr.h" +#include "mozilla/ReentrantMonitor.h" +#include "nsIThread.h" + +namespace mozilla { + +class MediaTaskQueue; +class MediaDataDecoderCallback; + +class AppleATDecoder : public MediaDataDecoder { +public: + AppleATDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback); + ~AppleATDecoder(); + + virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + virtual nsresult Flush() MOZ_OVERRIDE; + virtual nsresult Drain() MOZ_OVERRIDE; + virtual nsresult Shutdown() MOZ_OVERRIDE; + + + // Internal callbacks for the platform C api. Don't call externally. + void MetadataCallback(AudioFileStreamID aFileStream, + AudioFileStreamPropertyID aPropertyID, + UInt32* aFlags); + void SampleCallback(uint32_t aNumBytes, + uint32_t aNumPackets, + const void* aData, + AudioStreamPacketDescription* aPackets); + + // Callbacks also need access to the config. + const mp4_demuxer::AudioDecoderConfig& mConfig; + +private: + RefPtr<MediaTaskQueue> mTaskQueue; + MediaDataDecoderCallback* mCallback; + AudioConverterRef mConverter; + AudioFileStreamID mStream; + uint64_t mCurrentAudioFrame; + int64_t mSamplePosition; + bool mHaveOutput; + + void SetupDecoder(); + void SubmitSample(nsAutoPtr<mp4_demuxer::MP4Sample> aSample); +}; + +} // namespace mozilla + +#endif // mozilla_AppleATDecoder_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleCMFunctions.h @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Construct references to each of the CoreMedia symbols we use. + +LINK_FUNC(CMVideoFormatDescriptionCreate) +LINK_FUNC(CMBlockBufferCreateWithMemoryBlock) +LINK_FUNC(CMSampleBufferCreate) +LINK_FUNC(CMTimeMake)
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleCMLinker.cpp @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <dlfcn.h> + +#include "AppleCMLinker.h" +#include "MainThreadUtils.h" +#include "nsDebug.h" + +#ifdef PR_LOGGING +PRLogModuleInfo* GetDemuxerLog(); +#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__)) +#else +#define LOG(...) +#endif + +namespace mozilla { + +AppleCMLinker::LinkStatus +AppleCMLinker::sLinkStatus = LinkStatus_INIT; + +void* AppleCMLinker::sLink = nullptr; +nsrefcnt AppleCMLinker::sRefCount = 0; + +#define LINK_FUNC(func) typeof(func) func; +#include "AppleCMFunctions.h" +#undef LINK_FUNC + +/* static */ bool +AppleCMLinker::Link() +{ + // Bump our reference count every time we're called. + // Add a lock or change the thread assertion if + // you need to call this off the main thread. + MOZ_ASSERT(NS_IsMainThread()); + ++sRefCount; + + if (sLinkStatus) { + return sLinkStatus == LinkStatus_SUCCEEDED; + } + + const char* dlname = + "/System/Library/Frameworks/CoreMedia.framework/CoreMedia"; + if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) { + NS_WARNING("Couldn't load CoreMedia framework"); + goto fail; + } + +#define LINK_FUNC(func) \ + func = (typeof(func))dlsym(sLink, #func); \ + if (!func) { \ + NS_WARNING("Couldn't load CoreMedia function " #func ); \ + goto fail; \ + } +#include "AppleCMFunctions.h" +#undef LINK_FUNC + + LOG("Loaded CoreMedia framework."); + sLinkStatus = LinkStatus_SUCCEEDED; + return true; + +fail: + Unlink(); + + sLinkStatus = LinkStatus_FAILED; + return false; +} + +/* static */ void +AppleCMLinker::Unlink() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(sLink && sRefCount > 0, "Unbalanced Unlink()"); + --sRefCount; + if (sLink && sRefCount < 1) { + LOG("Unlinking CoreMedia framework."); + dlclose(sLink); + sLink = nullptr; + } +} + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleCMLinker.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef AppleCMLinker_h +#define AppleCMLinker_h + +extern "C" { +#pragma GCC visibility push(default) +#include <CoreMedia/CoreMedia.h> +#pragma GCC visibility pop +} + +#include "nscore.h" + +namespace mozilla { + +class AppleCMLinker +{ +public: + static bool Link(); + static void Unlink(); + +private: + static void* sLink; + static nsrefcnt sRefCount; + + static enum LinkStatus { + LinkStatus_INIT = 0, + LinkStatus_FAILED, + LinkStatus_SUCCEEDED + } sLinkStatus; +}; + +#define LINK_FUNC(func) extern typeof(func)* func; +#include "AppleCMFunctions.h" +#undef LINK_FUNC + +} // namespace mozilla + +#endif // AppleCMLinker_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleDecoderModule.cpp @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "AppleATDecoder.h" +#include "AppleCMLinker.h" +#include "AppleDecoderModule.h" +#include "AppleVTDecoder.h" +#include "AppleVTLinker.h" +#include "mozilla/Preferences.h" +#include "mozilla/DebugOnly.h" + +namespace mozilla { + +bool AppleDecoderModule::sIsEnabled = false; + +AppleDecoderModule::AppleDecoderModule() +{ +} + +AppleDecoderModule::~AppleDecoderModule() +{ +} + +/* static */ +void +AppleDecoderModule::Init() +{ + MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); + sIsEnabled = Preferences::GetBool("media.apple.mp4.enabled", false); + if (!sIsEnabled) { + return; + } + + // dlopen CoreMedia.framework if it's available. + sIsEnabled = AppleCMLinker::Link(); + if (!sIsEnabled) { + return; + } + + // dlopen VideoToolbox.framework if it's available. + sIsEnabled = AppleVTLinker::Link(); +} + +nsresult +AppleDecoderModule::Startup() +{ + // We don't have any per-instance initialization to do. + // Check whether ::Init() above succeeded to know if + // we're functional. + if (!sIsEnabled) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult +AppleDecoderModule::Shutdown() +{ + MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); + AppleVTLinker::Unlink(); + AppleCMLinker::Unlink(); + + return NS_OK; +} + +MediaDataDecoder* +AppleDecoderModule::CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + mozilla::layers::LayersBackend aLayersBackend, + mozilla::layers::ImageContainer* aImageContainer, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback) +{ + return new AppleVTDecoder(aConfig, aVideoTaskQueue, aCallback, aImageContainer); +} + +MediaDataDecoder* +AppleDecoderModule::CreateAACDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) +{ + return new AppleATDecoder(aConfig, aAudioTaskQueue, aCallback); +} + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleDecoderModule.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_AppleDecoderModule_h +#define mozilla_AppleDecoderModule_h + +#include "PlatformDecoderModule.h" + +namespace mozilla { + +class AppleDecoderModule : public PlatformDecoderModule { +public: + AppleDecoderModule(); + virtual ~AppleDecoderModule(); + + // Perform any per-instance initialization. + // Main thread only. + nsresult Startup(); + + // Called when the decoders have shutdown. Main thread only. + // Does this really need to be main thread only???? + virtual nsresult Shutdown() MOZ_OVERRIDE; + + // Decode thread. + virtual MediaDataDecoder* + CreateH264Decoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + mozilla::layers::LayersBackend aLayersBackend, + mozilla::layers::ImageContainer* aImageContainer, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE; + + // Decode thread. + virtual MediaDataDecoder* CreateAACDecoder( + const mp4_demuxer::AudioDecoderConfig& aConfig, + MediaTaskQueue* aAudioTaskQueue, + MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE; + + static void Init(); +private: + static bool sIsEnabled; +}; + +} // namespace mozilla + +#endif // mozilla_AppleDecoderModule_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleUtils.cpp @@ -0,0 +1,84 @@ +/* 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/. */ + +// Utility functions to help with Apple API calls. + +#include <AudioToolbox/AudioToolbox.h> +#include "AppleUtils.h" +#include "prlog.h" + +#ifdef PR_LOGGING +PRLogModuleInfo* GetDemuxerLog(); +#define WARN(...) PR_LOG(GetDemuxerLog(), PR_LOG_WARNING, (__VA_ARGS__)) +#else +#define WARN(...) +#endif + +#define PROPERTY_ID_FORMAT "%c%c%c%c" +#define PROPERTY_ID_PRINT(x) ((x) >> 24), \ + ((x) >> 16) & 0xff, \ + ((x) >> 8) & 0xff, \ + (x) & 0xff + +namespace mozilla { + +nsresult +AppleUtils::GetProperty(AudioFileStreamID aAudioFileStream, + AudioFileStreamPropertyID aPropertyID, + void *aData) +{ + UInt32 size; + Boolean writeable; + OSStatus rv = AudioFileStreamGetPropertyInfo(aAudioFileStream, aPropertyID, + &size, &writeable); + + if (rv) { + WARN("Couldn't get property " PROPERTY_ID_FORMAT "\n", + PROPERTY_ID_PRINT(aPropertyID)); + return NS_ERROR_FAILURE; + } + + rv = AudioFileStreamGetProperty(aAudioFileStream, aPropertyID, + &size, aData); + + return NS_OK; +} + +void +AppleUtils::SetCFDict(CFMutableDictionaryRef dict, + const char* key, + const char* value) +{ + // We avoid using the CFSTR macros because there's no way to release those. + AutoCFRelease<CFStringRef> keyRef = + CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8); + AutoCFRelease<CFStringRef> valueRef = + CFStringCreateWithCString(NULL, value, kCFStringEncodingUTF8); + CFDictionarySetValue(dict, keyRef, valueRef); +} + +void +AppleUtils::SetCFDict(CFMutableDictionaryRef dict, + const char* key, + int32_t value) +{ + AutoCFRelease<CFNumberRef> valueRef = + CFNumberCreate(NULL, kCFNumberSInt32Type, &value); + AutoCFRelease<CFStringRef> keyRef = + CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8); + CFDictionarySetValue(dict, keyRef, valueRef); +} + +void +AppleUtils::SetCFDict(CFMutableDictionaryRef dict, + const char* key, + bool value) +{ + AutoCFRelease<CFStringRef> keyRef = + CFStringCreateWithCString(NULL, key, kCFStringEncodingUTF8); + CFDictionarySetValue(dict, keyRef, value ? kCFBooleanTrue : kCFBooleanFalse); +} + + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleUtils.h @@ -0,0 +1,66 @@ +/* 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/. */ + +// Utility functions to help with Apple API calls. + +#ifndef mozilla_AppleUtils_h +#define mozilla_AppleUtils_h + +#include <AudioToolbox/AudioToolbox.h> +#include "nsError.h" + +namespace mozilla { + +struct AppleUtils { + // Helper to retrieve properties from AudioFileStream objects. + static nsresult GetProperty(AudioFileStreamID aAudioFileStream, + AudioFileStreamPropertyID aPropertyID, + void *aData); + + // Helper to set a string, string pair on a CFMutableDictionaryRef. + static void SetCFDict(CFMutableDictionaryRef dict, + const char* key, + const char* value); + // Helper to set a string, int32_t pair on a CFMutableDictionaryRef. + static void SetCFDict(CFMutableDictionaryRef dict, + const char* key, + int32_t value); + // Helper to set a string, bool pair on a CFMutableDictionaryRef. + static void SetCFDict(CFMutableDictionaryRef dict, + const char* key, + bool value); +}; + +// Wrapper class to call CFRelease on reference types +// when they go out of scope. +template <class T> +class AutoCFRelease { +public: + AutoCFRelease(T aRef) + : mRef(aRef) + { + } + ~AutoCFRelease() + { + if (mRef) { + CFRelease(mRef); + } + } + // Return the wrapped ref so it can be used as an in parameter. + operator T() + { + return mRef; + } + // Return a pointer to the wrapped ref for use as an out parameter. + T* receive() + { + return &mRef; + } +private: + T mRef; +}; + +} // namespace mozilla + +#endif // mozilla_AppleUtils_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleVTDecoder.cpp @@ -0,0 +1,427 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <CoreFoundation/CFString.h> + +#include "AppleUtils.h" +#include "mozilla/SHA1.h" +#include "mp4_demuxer/DecoderData.h" +#include "MP4Reader.h" +#include "MP4Decoder.h" +#include "nsAutoPtr.h" +#include "nsThreadUtils.h" +#include "AppleCMLinker.h" +#include "AppleVTDecoder.h" +#include "AppleVTLinker.h" +#include "prlog.h" +#include "MediaData.h" +#include "VideoUtils.h" + +#ifdef PR_LOGGING +PRLogModuleInfo* GetDemuxerLog(); +#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__)) +#define LOG_MEDIA_SHA1 +#else +#define LOG(...) +#endif + +namespace mozilla { + +AppleVTDecoder::AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback, + layers::ImageContainer* aImageContainer) + : mConfig(aConfig) + , mTaskQueue(aVideoTaskQueue) + , mCallback(aCallback) + , mImageContainer(aImageContainer) + , mFormat(nullptr) + , mSession(nullptr) +{ + MOZ_COUNT_CTOR(AppleVTDecoder); + // TODO: Verify aConfig.mime_type. + LOG("Creating AppleVTDecoder for %dx%d h.264 video", + mConfig.display_width, + mConfig.display_height + ); +} + +AppleVTDecoder::~AppleVTDecoder() +{ + MOZ_COUNT_DTOR(AppleVTDecoder); +} + +nsresult +AppleVTDecoder::Init() +{ + nsresult rv = InitializeSession(); + return rv; +} + +nsresult +AppleVTDecoder::Shutdown() +{ + if (mSession) { + LOG("%s: cleaning up session %p", __func__, mSession); + VTDecompressionSessionInvalidate(mSession); + CFRelease(mSession); + mSession = nullptr; + } + if (mFormat) { + LOG("%s: releasing format %p", __func__, mFormat); + CFRelease(mFormat); + mFormat = nullptr; + } + return NS_OK; +} + +nsresult +AppleVTDecoder::Input(mp4_demuxer::MP4Sample* aSample) +{ + LOG("mp4 input sample %p pts %lld duration %lld us%s %d bytes", + aSample, + aSample->composition_timestamp, + aSample->duration, + aSample->is_sync_point ? " keyframe" : "", + aSample->size); + +#ifdef LOG_MEDIA_SHA1 + SHA1Sum hash; + hash.update(aSample->data, aSample->size); + uint8_t digest_buf[SHA1Sum::kHashSize]; + hash.finish(digest_buf); + nsAutoCString digest; + for (size_t i = 0; i < sizeof(digest_buf); i++) { + digest.AppendPrintf("%02x", digest_buf[i]); + } + LOG(" sha1 %s", digest.get()); +#endif // LOG_MEDIA_SHA1 + + mTaskQueue->Dispatch( + NS_NewRunnableMethodWithArg<nsAutoPtr<mp4_demuxer::MP4Sample>>( + this, + &AppleVTDecoder::SubmitFrame, + nsAutoPtr<mp4_demuxer::MP4Sample>(aSample))); + return NS_OK; +} + +nsresult +AppleVTDecoder::Flush() +{ + mReorderQueue.Clear(); + return Drain(); +} + +nsresult +AppleVTDecoder::Drain() +{ + OSStatus rv = VTDecompressionSessionWaitForAsynchronousFrames(mSession); + if (rv != noErr) { + LOG("Error %d draining frames", rv); + return NS_ERROR_FAILURE; + } + return DrainReorderedFrames(); +} + +// +// Implementation details. +// + +// Context object to hold a copy of sample metadata. +class FrameRef { +public: + Microseconds timestamp; + Microseconds duration; + int64_t byte_offset; + bool is_sync_point; + + explicit FrameRef(mp4_demuxer::MP4Sample* aSample) + { + MOZ_ASSERT(aSample); + timestamp = aSample->composition_timestamp; + duration = aSample->duration; + byte_offset = aSample->byte_offset; + is_sync_point = aSample->is_sync_point; + } +}; + +// Callback passed to the VideoToolbox decoder for returning data. +// This needs to be static because the API takes a C-style pair of +// function and userdata pointers. This validates parameters and +// forwards the decoded image back to an object method. +static void +PlatformCallback(void* decompressionOutputRefCon, + void* sourceFrameRefCon, + OSStatus status, + VTDecodeInfoFlags flags, + CVImageBufferRef image, + CMTime presentationTimeStamp, + CMTime presentationDuration) +{ + LOG("AppleVideoDecoder %s status %d flags %d", __func__, status, flags); + + AppleVTDecoder* decoder = + static_cast<AppleVTDecoder*>(decompressionOutputRefCon); + nsAutoPtr<FrameRef> frameRef = + nsAutoPtr<FrameRef>(static_cast<FrameRef*>(sourceFrameRefCon)); + + LOG("mp4 output frame %lld pts %lld duration %lld us%s", + frameRef->byte_offset, + frameRef->timestamp, + frameRef->duration, + frameRef->is_sync_point ? " keyframe" : "" + ); + + // Validate our arguments. + if (status != noErr || !image) { + NS_WARNING("VideoToolbox decoder returned no data"); + return; + } + if (flags & kVTDecodeInfo_FrameDropped) { + NS_WARNING(" ...frame dropped..."); + } + MOZ_ASSERT(CFGetTypeID(image) == CVPixelBufferGetTypeID(), + "VideoToolbox returned an unexpected image type"); + + // Forward the data back to an object method which can access + // the correct MP4Reader callback. + decoder->OutputFrame(image, frameRef); +} + +nsresult +AppleVTDecoder::DrainReorderedFrames() +{ + while (!mReorderQueue.IsEmpty()) { + mCallback->Output(mReorderQueue.Pop()); + } + return NS_OK; +} + +// Copy and return a decoded frame. +nsresult +AppleVTDecoder::OutputFrame(CVPixelBufferRef aImage, + nsAutoPtr<FrameRef> aFrameRef) +{ + size_t width = CVPixelBufferGetWidth(aImage); + size_t height = CVPixelBufferGetHeight(aImage); + LOG(" got decoded frame data... %ux%u %s", width, height, + CVPixelBufferIsPlanar(aImage) ? "planar" : "chunked"); +#ifdef DEBUG + size_t planes = CVPixelBufferGetPlaneCount(aImage); + for (size_t i = 0; i < planes; ++i) { + size_t stride = CVPixelBufferGetBytesPerRowOfPlane(aImage, i); + LOG(" plane %u %ux%u rowbytes %u", + (unsigned)i, + CVPixelBufferGetWidthOfPlane(aImage, i), + CVPixelBufferGetHeightOfPlane(aImage, i), + (unsigned)stride); + } + MOZ_ASSERT(planes == 2); +#endif // DEBUG + + VideoData::YCbCrBuffer buffer; + + // Lock the returned image data. + CVReturn rv = CVPixelBufferLockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly); + if (rv != kCVReturnSuccess) { + NS_ERROR("error locking pixel data"); + mCallback->Error(); + return NS_ERROR_FAILURE; + } + // Y plane. + buffer.mPlanes[0].mData = + static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 0)); + buffer.mPlanes[0].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 0); + buffer.mPlanes[0].mWidth = width; + buffer.mPlanes[0].mHeight = height; + buffer.mPlanes[0].mOffset = 0; + buffer.mPlanes[0].mSkip = 0; + // Cb plane. + buffer.mPlanes[1].mData = + static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1)); + buffer.mPlanes[1].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1); + buffer.mPlanes[1].mWidth = (width+1) / 2; + buffer.mPlanes[1].mHeight = (height+1) / 2; + buffer.mPlanes[1].mOffset = 0; + buffer.mPlanes[1].mSkip = 1; + // Cr plane. + buffer.mPlanes[2].mData = + static_cast<uint8_t*>(CVPixelBufferGetBaseAddressOfPlane(aImage, 1)); + buffer.mPlanes[2].mStride = CVPixelBufferGetBytesPerRowOfPlane(aImage, 1); + buffer.mPlanes[2].mWidth = (width+1) / 2; + buffer.mPlanes[2].mHeight = (height+1) / 2; + buffer.mPlanes[2].mOffset = 1; + buffer.mPlanes[2].mSkip = 1; + + // Bounds. + VideoInfo info; + info.mDisplay = nsIntSize(width, height); + info.mHasVideo = true; + gfx::IntRect visible = gfx::IntRect(0, + 0, + mConfig.display_width, + mConfig.display_height); + + // Copy the image data into our own format. + nsAutoPtr<VideoData> data; + data = + VideoData::Create(info, + mImageContainer, + nullptr, + aFrameRef->byte_offset, + aFrameRef->timestamp, + aFrameRef->duration, + buffer, + aFrameRef->is_sync_point, + aFrameRef->timestamp, + visible); + // Unlock the returned image data. + CVPixelBufferUnlockBaseAddress(aImage, kCVPixelBufferLock_ReadOnly); + + // Frames come out in DTS order but we need to output them + // in composition order. + mReorderQueue.Push(data.forget()); + if (mReorderQueue.Length() > 2) { + VideoData* readyData = mReorderQueue.Pop(); + mCallback->Output(readyData); + } + + return NS_OK; +} + +// Helper to fill in a timestamp structure. +static CMSampleTimingInfo +TimingInfoFromSample(mp4_demuxer::MP4Sample* aSample) +{ + CMSampleTimingInfo timestamp; + + timestamp.duration = CMTimeMake(aSample->duration, USECS_PER_S); + timestamp.presentationTimeStamp = + CMTimeMake(aSample->composition_timestamp, USECS_PER_S); + // No DTS value available from libstagefright. + timestamp.decodeTimeStamp = CMTimeMake(0, USECS_PER_S); + + return timestamp; +} + +nsresult +AppleVTDecoder::SubmitFrame(mp4_demuxer::MP4Sample* aSample) +{ + // For some reason this gives me a double-free error with stagefright. + AutoCFRelease<CMBlockBufferRef> block = nullptr; + AutoCFRelease<CMSampleBufferRef> sample = nullptr; + VTDecodeInfoFlags flags; + OSStatus rv; + + // FIXME: This copies the sample data. I think we can provide + // a custom block source which reuses the aSample buffer. + // But note that there may be a problem keeping the samples + // alive over multiple frames. + rv = CMBlockBufferCreateWithMemoryBlock(NULL // Struct allocator. + ,aSample->data + ,aSample->size + ,kCFAllocatorNull // Block allocator. + ,NULL // Block source. + ,0 // Data offset. + ,aSample->size + ,false + ,block.receive()); + NS_ASSERTION(rv == noErr, "Couldn't create CMBlockBuffer"); + CMSampleTimingInfo timestamp = TimingInfoFromSample(aSample); + rv = CMSampleBufferCreate(NULL, block, true, 0, 0, mFormat, 1, 1, ×tamp, 0, NULL, sample.receive()); + NS_ASSERTION(rv == noErr, "Couldn't create CMSampleBuffer"); + rv = VTDecompressionSessionDecodeFrame(mSession, + sample, + 0, + new FrameRef(aSample), + &flags); + NS_ASSERTION(rv == noErr, "Couldn't pass frame to decoder"); + + // Ask for more data. + if (mTaskQueue->IsEmpty()) { + LOG("AppleVTDecoder task queue empty; requesting more data"); + mCallback->InputExhausted(); + } + + return NS_OK; +} + +nsresult +AppleVTDecoder::InitializeSession() +{ + OSStatus rv; + AutoCFRelease<CFMutableDictionaryRef> extensions = + CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationBottomField", "left"); + AppleUtils::SetCFDict(extensions, "CVImageBufferChromaLocationTopField", "left"); + AppleUtils::SetCFDict(extensions, "FullRangeVideo", true); + + AutoCFRelease<CFMutableDictionaryRef> atoms = + CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + AutoCFRelease<CFDataRef> avc_data = CFDataCreate(NULL, + mConfig.extra_data.begin(), mConfig.extra_data.length()); + +#ifdef LOG_MEDIA_SHA1 + SHA1Sum avc_hash; + avc_hash.update(mConfig.extra_data.begin(), mConfig.extra_data.length()); + uint8_t digest_buf[SHA1Sum::kHashSize]; + avc_hash.finish(digest_buf); + nsAutoCString avc_digest; + for (size_t i = 0; i < sizeof(digest_buf); i++) { + avc_digest.AppendPrintf("%02x", digest_buf[i]); + } + LOG("AVCDecoderConfig %ld bytes sha1 %s", + mConfig.extra_data.length(), avc_digest.get()); +#endif // LOG_MEDIA_SHA1 + + CFDictionarySetValue(atoms, CFSTR("avcC"), avc_data); + CFDictionarySetValue(extensions, CFSTR("SampleDescriptionExtensionAtoms"), atoms); + rv = CMVideoFormatDescriptionCreate(NULL, // Use default allocator. + kCMVideoCodecType_H264, + mConfig.display_width, + mConfig.display_height, + extensions, + &mFormat); + if (rv != noErr) { + NS_ERROR("Couldn't create format description!"); + return NS_ERROR_FAILURE; + } + + // Contruct video decoder selection spec. + AutoCFRelease<CFMutableDictionaryRef> spec = + CFDictionaryCreateMutable(NULL, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + // This key is supported (or ignored) but not declared prior to OSX 10.9. + AutoCFRelease<CFStringRef> + kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder = + CFStringCreateWithCString(NULL, "EnableHardwareAcceleratedVideoDecoder", + kCFStringEncodingUTF8); + + CFDictionarySetValue(spec, + kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder, + kCFBooleanTrue); + + VTDecompressionOutputCallbackRecord cb = { PlatformCallback, this }; + rv = VTDecompressionSessionCreate(NULL, // Allocator. + mFormat, + spec, // Video decoder selection. + NULL, // Output video format. + &cb, + &mSession); + if (rv != noErr) { + NS_ERROR("Couldn't create decompression session!"); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleVTDecoder.h @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_AppleVTDecoder_h +#define mozilla_AppleVTDecoder_h + +#include "PlatformDecoderModule.h" +#include "mozilla/RefPtr.h" +#include "mozilla/ReentrantMonitor.h" +#include "nsIThread.h" +#include "ReorderQueue.h" + +#include "VideoToolbox/VideoToolbox.h" + +namespace mozilla { + +class MediaTaskQueue; +class MediaDataDecoderCallback; +namespace layers { + class ImageContainer; +} +class FrameRef; + +class AppleVTDecoder : public MediaDataDecoder { +public: + AppleVTDecoder(const mp4_demuxer::VideoDecoderConfig& aConfig, + MediaTaskQueue* aVideoTaskQueue, + MediaDataDecoderCallback* aCallback, + layers::ImageContainer* aImageContainer); + ~AppleVTDecoder(); + virtual nsresult Init() MOZ_OVERRIDE; + virtual nsresult Input(mp4_demuxer::MP4Sample* aSample) MOZ_OVERRIDE; + virtual nsresult Flush() MOZ_OVERRIDE; + virtual nsresult Drain() MOZ_OVERRIDE; + virtual nsresult Shutdown() MOZ_OVERRIDE; + // Return hook for VideoToolbox callback. + nsresult OutputFrame(CVPixelBufferRef aImage, + nsAutoPtr<FrameRef> frameRef); +private: + const mp4_demuxer::VideoDecoderConfig& mConfig; + RefPtr<MediaTaskQueue> mTaskQueue; + MediaDataDecoderCallback* mCallback; + layers::ImageContainer* mImageContainer; + CMVideoFormatDescriptionRef mFormat; + VTDecompressionSessionRef mSession; + ReorderQueue mReorderQueue; + + // Method to pass a frame to VideoToolbox for decoding. + nsresult SubmitFrame(mp4_demuxer::MP4Sample* aSample); + // Method to set up the decompression session. + nsresult InitializeSession(); + nsresult DrainReorderedFrames(); +}; + +} // namespace mozilla + +#endif // mozilla_AppleVTDecoder_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleVTFunctions.h @@ -0,0 +1,12 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Construct references to each of the VideoToolbox symbols we use. + +LINK_FUNC(VTDecompressionSessionCreate) +LINK_FUNC(VTDecompressionSessionDecodeFrame) +LINK_FUNC(VTDecompressionSessionInvalidate) +LINK_FUNC(VTDecompressionSessionWaitForAsynchronousFrames)
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleVTLinker.cpp @@ -0,0 +1,89 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include <dlfcn.h> + +#include "AppleVTLinker.h" +#include "MainThreadUtils.h" +#include "nsDebug.h" + +#ifdef PR_LOGGING +PRLogModuleInfo* GetDemuxerLog(); +#define LOG(...) PR_LOG(GetDemuxerLog(), PR_LOG_DEBUG, (__VA_ARGS__)) +#else +#define LOG(...) +#endif + +namespace mozilla { + +AppleVTLinker::LinkStatus +AppleVTLinker::sLinkStatus = LinkStatus_INIT; + +void* AppleVTLinker::sLink = nullptr; +nsrefcnt AppleVTLinker::sRefCount = 0; + +#define LINK_FUNC(func) typeof(func) func; +#include "AppleVTFunctions.h" +#undef LINK_FUNC + +/* static */ bool +AppleVTLinker::Link() +{ + // Bump our reference count every time we're called. + // Add a lock or change the thread assertion if + // you need to call this off the main thread. + MOZ_ASSERT(NS_IsMainThread()); + ++sRefCount; + + if (sLinkStatus) { + return sLinkStatus == LinkStatus_SUCCEEDED; + } + + const char* dlname = + "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox"; + if (!(sLink = dlopen(dlname, RTLD_NOW | RTLD_LOCAL))) { + NS_WARNING("Couldn't load VideoToolbox framework"); + goto fail; + } + +#define LINK_FUNC(func) \ + func = (typeof(func))dlsym(sLink, #func); \ + if (!func) { \ + NS_WARNING("Couldn't load VideoToolbox function " #func ); \ + goto fail; \ + } +#include "AppleVTFunctions.h" +#undef LINK_FUNC + + LOG("Loaded VideoToolbox framework."); + sLinkStatus = LinkStatus_SUCCEEDED; + return true; + +fail: + Unlink(); + + sLinkStatus = LinkStatus_FAILED; + return false; +} + +/* static */ void +AppleVTLinker::Unlink() +{ + // We'll be called by multiple Decoders, one intantiated for + // each media element. Therefore we receive must maintain a + // reference count to avoidunloading our symbols when other + // instances still need them. + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(sLink && sRefCount > 0, "Unbalanced Unlink()"); + --sRefCount; + if (sLink && sRefCount < 1) { + LOG("Unlinking VideoToolbox framework."); + dlclose(sLink); + sLink = nullptr; + } +} + +} // namespace mozilla
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/AppleVTLinker.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef AppleVTLinker_h +#define AppleVTLinker_h + +extern "C" { +#pragma GCC visibility push(default) +#include "VideoToolbox/VideoToolbox.h" +#pragma GCC visibility pop +} + +#include "nscore.h" + +namespace mozilla { + +class AppleVTLinker +{ +public: + static bool Link(); + static void Unlink(); + +private: + static void* sLink; + static nsrefcnt sRefCount; + + static enum LinkStatus { + LinkStatus_INIT = 0, + LinkStatus_FAILED, + LinkStatus_SUCCEEDED + } sLinkStatus; +}; + +#define LINK_FUNC(func) extern typeof(func)* func; +#include "AppleVTFunctions.h" +#undef LINK_FUNC + +} // namespace mozilla + +#endif // AppleVTLinker_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/ReorderQueue.h @@ -0,0 +1,29 @@ +/* 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/. */ + +// Queue for ordering decoded video frames by presentation time. +// Decoders often return frames out of order, which we need to +// buffer so we can forward them in correct presentation order. + +#ifndef mozilla_ReorderQueue_h +#define mozilla_ReorderQueue_h + +#include <MediaData.h> +#include <nsTPriorityQueue.h> + +namespace mozilla { + +struct ReorderQueueComparator +{ + bool LessThan(VideoData* const& a, VideoData* const& b) const + { + return a->mTime < b->mTime; + } +}; + +typedef nsTPriorityQueue<VideoData*, ReorderQueueComparator> ReorderQueue; + +} // namespace mozilla + +#endif // mozilla_ReorderQueue_h
new file mode 100644 --- /dev/null +++ b/content/media/fmp4/apple/VideoToolbox/VideoToolbox.h @@ -0,0 +1,76 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// Stub header for VideoToolbox framework API. +// We include our own copy so we can build on MacOS versions +// where it's not available. + +#ifndef mozilla_VideoToolbox_VideoToolbox_h +#define mozilla_VideoToolbox_VideoToolbox_h + +// CoreMedia is available starting in OS X 10.7, +// so we need to dlopen it as well to run on 10.6, +// but we can depend on the real framework headers at build time. + +#include <CoreMedia/CMBase.h> +#include <CoreFoundation/CoreFoundation.h> +#include <CoreVideo/CVPixelBuffer.h> +#include <CoreMedia/CMSampleBuffer.h> +#include <CoreMedia/CMFormatDescription.h> +#include <CoreMedia/CMTime.h> + +typedef uint32_t VTDecodeFrameFlags; +typedef uint32_t VTDecodeInfoFlags; +enum { + kVTDecodeInfo_Asynchronous = 1UL << 0, + kVTDecodeInfo_FrameDropped = 1UL << 1, +}; + +typedef struct OpaqueVTDecompressionSession* VTDecompressionSessionRef; +typedef void (*VTDecompressionOutputCallback)( + void*, + void*, + OSStatus, + VTDecodeInfoFlags, + CVImageBufferRef, + CMTime, + CMTime +); +typedef struct VTDecompressionOutputCallbackRecord { + VTDecompressionOutputCallback decompressionOutputCallback; + void* decompressionOutputRefCon; +} VTDecompressionOutputCallbackRecord; + +OSStatus +VTDecompressionSessionCreate( + CFAllocatorRef, + CMVideoFormatDescriptionRef, + CFDictionaryRef, + CFDictionaryRef, + const VTDecompressionOutputCallbackRecord*, + VTDecompressionSessionRef* +); + +OSStatus +VTDecompressionSessionDecodeFrame( + VTDecompressionSessionRef, + CMSampleBufferRef, + VTDecodeFrameFlags, + void*, + VTDecodeInfoFlags* +); + +OSStatus +VTDecompressionSessionWaitForAsynchronousFrames( + VTDecompressionSessionRef +); + +void +VTDecompressionSessionInvalidate( + VTDecompressionSessionRef +); + +#endif // mozilla_VideoToolbox_VideoToolbox_h
--- a/content/media/fmp4/moz.build +++ b/content/media/fmp4/moz.build @@ -37,11 +37,27 @@ if CONFIG['MOZ_FFMPEG']: 'ffmpeg/libav53', 'ffmpeg/libav54', 'ffmpeg/libav55', ] LOCAL_INCLUDES += [ 'ffmpeg', ] +if CONFIG['MOZ_APPLEMEDIA']: + EXPORTS += [ + 'apple/AppleDecoderModule.h', + ] + UNIFIED_SOURCES += [ + 'apple/AppleATDecoder.cpp', + 'apple/AppleCMLinker.cpp', + 'apple/AppleDecoderModule.cpp', + 'apple/AppleUtils.cpp', + 'apple/AppleVTDecoder.cpp', + 'apple/AppleVTLinker.cpp', + ] + LDFLAGS += [ + '-framework AudioToolbox', + ] + FINAL_LIBRARY = 'xul' FAIL_ON_WARNINGS = True
--- a/content/media/gmp/GMPChild.cpp +++ b/content/media/gmp/GMPChild.cpp @@ -21,18 +21,16 @@ using mozilla::dom::CrashReporterChild; #include <stdlib.h> // for _exit() #else #include <unistd.h> // for _exit() #endif #if defined(XP_WIN) #define TARGET_SANDBOX_EXPORTS #include "mozilla/sandboxTarget.h" -#elif defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) -#include "mozilla/Sandbox.h" #endif namespace mozilla { namespace gmp { GMPChild::GMPChild() : mLib(nullptr) , mGetAPIFunc(nullptr) @@ -95,23 +93,16 @@ GMPChild::LoadPluginLibrary(const std::s nsAutoString binaryName = baseName + NS_LITERAL_STRING(".dll"); #else #error not defined #endif libFile->AppendRelativePath(binaryName); nsAutoCString nativePath; libFile->GetNativePath(nativePath); - -#if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX) - // Enable sandboxing here -- we know the plugin file's path, but - // this process's execution hasn't been affected by its content yet. - mozilla::SetMediaPluginSandbox(nativePath.get()); -#endif - mLib = PR_LoadLibrary(nativePath.get()); if (!mLib) { return false; } GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit")); if (!initFunc) { return false;
--- a/content/media/webaudio/AudioDestinationNode.cpp +++ b/content/media/webaudio/AudioDestinationNode.cpp @@ -324,17 +324,16 @@ AudioDestinationNode::AudioDestinationNo MediaStreamGraph::CreateNonRealtimeInstance(aSampleRate) : MediaStreamGraph::GetInstance(); AudioNodeEngine* engine = aIsOffline ? new OfflineDestinationNodeEngine(this, aNumberOfChannels, aLength, aSampleRate) : static_cast<AudioNodeEngine*>(new DestinationNodeEngine(this)); mStream = graph->CreateAudioNodeStream(engine, MediaStreamGraph::EXTERNAL_STREAM); - mStream->SetAudioChannelType(aChannel); mStream->AddMainThreadListener(this); mStream->AddAudioOutput(&gWebAudioOutputKey); if (aChannel != AudioChannel::Normal) { ErrorResult rv; SetMozAudioChannelType(aChannel, rv); } } @@ -534,16 +533,20 @@ AudioDestinationNode::SetMozAudioChannel aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return; } if (aValue != mAudioChannel && CheckAudioChannelPermissions(aValue)) { mAudioChannel = aValue; + if (mStream) { + mStream->SetAudioChannelType(mAudioChannel); + } + if (mAudioChannelAgent) { CreateAudioChannelAgent(); } } } bool AudioDestinationNode::CheckAudioChannelPermissions(AudioChannel aValue)
--- a/content/svg/content/src/SVGSVGElement.cpp +++ b/content/svg/content/src/SVGSVGElement.cpp @@ -1,16 +1,16 @@ /* -*- 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 <stdint.h> #include "mozilla/ArrayUtils.h" -#include "mozilla/BasicEvents.h" +#include "mozilla/ContentEvents.h" #include "mozilla/EventDispatcher.h" #include "mozilla/Likely.h" #include "nsGkAtoms.h" #include "nsLayoutUtils.h" #include "nsLayoutStylesheetCache.h" #include "DOMSVGNumber.h" #include "DOMSVGLength.h" @@ -513,21 +513,24 @@ SVGSVGElement::SetCurrentScaleTranslate( mCurrentScale = s; mCurrentTranslate = SVGPoint(x, y); // now dispatch the appropriate event if we are the root element nsIDocument* doc = GetCurrentDoc(); if (doc) { nsCOMPtr<nsIPresShell> presShell = doc->GetShell(); if (presShell && IsRoot()) { - bool scaling = (mPreviousScale != mCurrentScale); nsEventStatus status = nsEventStatus_eIgnore; - WidgetGUIEvent event(true, scaling ? NS_SVG_ZOOM : NS_SVG_SCROLL, 0); - event.eventStructType = scaling ? NS_SVGZOOM_EVENT : NS_EVENT; - presShell->HandleDOMEventWithTarget(this, &event, &status); + if (mPreviousScale != mCurrentScale) { + InternalSVGZoomEvent svgZoomEvent(true, NS_SVG_ZOOM); + presShell->HandleDOMEventWithTarget(this, &svgZoomEvent, &status); + } else { + WidgetEvent svgScrollEvent(true, NS_SVG_SCROLL); + presShell->HandleDOMEventWithTarget(this, &svgScrollEvent, &status); + } InvalidateTransformNotifyFrame(); } } } void SVGSVGElement::SetCurrentTranslate(float x, float y) {
--- a/content/svg/content/src/SVGZoomEvent.cpp +++ b/content/svg/content/src/SVGZoomEvent.cpp @@ -1,19 +1,20 @@ /* -*- 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 "mozilla/dom/SVGZoomEvent.h" #include "DOMSVGPoint.h" +#include "mozilla/ContentEvents.h" +#include "mozilla/dom/Element.h" #include "mozilla/dom/SVGSVGElement.h" -#include "nsIPresShell.h" +#include "mozilla/dom/SVGZoomEvent.h" #include "nsIDocument.h" -#include "mozilla/dom/Element.h" +#include "nsIPresShell.h" #include "prtime.h" namespace mozilla { namespace dom { //---------------------------------------------------------------------- // Implementation @@ -22,33 +23,30 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(SVGZo NS_IMPL_ADDREF_INHERITED(SVGZoomEvent, UIEvent) NS_IMPL_RELEASE_INHERITED(SVGZoomEvent, UIEvent) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGZoomEvent) NS_INTERFACE_MAP_END_INHERITING(UIEvent) SVGZoomEvent::SVGZoomEvent(EventTarget* aOwner, nsPresContext* aPresContext, - WidgetGUIEvent* aEvent) + InternalSVGZoomEvent* aEvent) : UIEvent(aOwner, aPresContext, - aEvent ? aEvent : new WidgetGUIEvent(false, NS_SVG_ZOOM, 0)) + aEvent ? aEvent : new InternalSVGZoomEvent(false, NS_SVG_ZOOM)) , mPreviousScale(0) , mNewScale(0) { if (aEvent) { mEventIsInternal = false; } else { mEventIsInternal = true; - mEvent->eventStructType = NS_SVGZOOM_EVENT; mEvent->time = PR_Now(); } - mEvent->mFlags.mCancelable = false; - // We must store the "Previous" and "New" values before this event is // dispatched. Reading the values from the root 'svg' element after we've // been dispatched is not an option since event handler code may change // currentScale and currentTranslate in response to this event. nsIPresShell *presShell; if (mPresContext && (presShell = mPresContext->GetPresShell())) { nsIDocument *doc = presShell->GetDocument(); if (doc) { @@ -90,14 +88,14 @@ SVGZoomEvent::~SVGZoomEvent() //////////////////////////////////////////////////////////////////////// // Exported creation functions: nsresult NS_NewDOMSVGZoomEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - mozilla::WidgetGUIEvent* aEvent) + mozilla::InternalSVGZoomEvent* aEvent) { mozilla::dom::SVGZoomEvent* it = new mozilla::dom::SVGZoomEvent(aOwner, aPresContext, aEvent); return CallQueryInterface(it, aInstancePtrResult); }
--- a/content/svg/content/src/SVGZoomEvent.h +++ b/content/svg/content/src/SVGZoomEvent.h @@ -23,17 +23,17 @@ namespace dom { class SVGZoomEvent MOZ_FINAL : public UIEvent { public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGZoomEvent, UIEvent) NS_DECL_ISUPPORTS_INHERITED SVGZoomEvent(EventTarget* aOwner, nsPresContext* aPresContext, - WidgetGUIEvent* aEvent); + InternalSVGZoomEvent* aEvent); // Forward to base class NS_FORWARD_TO_UIEVENT virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE { return SVGZoomEventBinding::Wrap(aCx, this); }
--- a/dom/events/EventDispatcher.cpp +++ b/dom/events/EventDispatcher.cpp @@ -724,20 +724,20 @@ EventDispatcher::CreateEvent(EventTarget case NS_TEXT_EVENT: return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsTextEvent()); case NS_CLIPBOARD_EVENT: return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsClipboardEvent()); case NS_SVGZOOM_EVENT: return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext, - aEvent->AsGUIEvent()); + aEvent->AsSVGZoomEvent()); case NS_SMIL_TIME_EVENT: - return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, aEvent); - + return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, + aEvent->AsSMILTimeEvent()); case NS_COMMAND_EVENT: return NS_NewDOMCommandEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsCommandEvent()); case NS_SIMPLE_GESTURE_EVENT: return NS_NewDOMSimpleGestureEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsSimpleGestureEvent()); case NS_POINTER_EVENT: return NS_NewDOMPointerEvent(aDOMEvent, aOwner, aPresContext,
--- a/dom/interfaces/events/nsIDOMEvent.idl +++ b/dom/interfaces/events/nsIDOMEvent.idl @@ -301,22 +301,22 @@ nsresult NS_NewDOMSVGEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, mozilla::WidgetEvent* aEvent); nsresult NS_NewDOMSVGZoomEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - mozilla::WidgetGUIEvent* aEvent); + mozilla::InternalSVGZoomEvent* aEvent); nsresult NS_NewDOMTimeEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, - mozilla::WidgetEvent* aEvent); + mozilla::InternalSMILTimeEvent* aEvent); nsresult NS_NewDOMXULCommandEvent(nsIDOMEvent** aResult, mozilla::dom::EventTarget* aOwner, nsPresContext* aPresContext, mozilla::WidgetInputEvent* aEvent); nsresult NS_NewDOMCommandEvent(nsIDOMEvent** aInstancePtrResult, mozilla::dom::EventTarget* aOwner,
--- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -913,17 +913,17 @@ ContentChild::AllocPBackgroundChild(Tran bool ContentChild::RecvSetProcessSandbox() { // We may want to move the sandbox initialization somewhere else // at some point; see bug 880808. #if defined(MOZ_CONTENT_SANDBOX) #if defined(XP_LINUX) - SetContentProcessSandbox(); + SetCurrentProcessSandbox(); #elif defined(XP_WIN) mozilla::SandboxTarget::Instance()->StartSandbox(); #endif #endif return true; } bool
--- a/dom/media/moz.build +++ b/dom/media/moz.build @@ -41,19 +41,17 @@ UNIFIED_SOURCES += [ 'MediaManager.cpp', ] EXTRA_COMPONENTS += [ 'PeerConnection.js', 'PeerConnection.manifest', ] -JS_MODULES_PATH = 'modules/media' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.media += [ 'IdpProxy.jsm', 'PeerConnectionIdp.jsm', 'RTCStatsReport.jsm', ] if CONFIG['MOZ_B2G']: EXPORTS.mozilla += [ 'MediaPermissionGonk.h',
--- a/dom/mobilemessage/src/moz.build +++ b/dom/mobilemessage/src/moz.build @@ -14,17 +14,17 @@ EXPORTS.mozilla.dom.mobilemessage += [ ] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android': SOURCES += [ 'android/MobileMessageDatabaseService.cpp', 'android/SmsService.cpp', ] elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']: - EXTRA_JS_MODULES = [ + EXTRA_JS_MODULES += [ 'gonk/mms_consts.js', 'gonk/MmsPduHelper.jsm', 'gonk/MobileMessageDB.jsm', 'gonk/wap_consts.js', 'gonk/WspPduHelper.jsm', ] EXTRA_COMPONENTS += [ 'gonk/MmsService.js',
--- a/dom/network/src/moz.build +++ b/dom/network/src/moz.build @@ -22,17 +22,17 @@ UNIFIED_SOURCES += [ 'TCPServerSocketParent.cpp', 'TCPSocketChild.cpp', 'TCPSocketParent.cpp', 'UDPSocketChild.cpp', 'UDPSocketParent.cpp', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk': - EXTRA_JS_MODULES = [ + EXTRA_JS_MODULES += [ 'NetworkStatsDB.jsm', 'NetworkStatsService.jsm', ] EXTRA_COMPONENTS += [ 'TCPServerSocket.js', 'TCPSocket.manifest', 'TCPSocketParentIntermediary.js',
--- a/dom/smil/TimeEvent.cpp +++ b/dom/smil/TimeEvent.cpp @@ -1,44 +1,36 @@ /* -*- 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 "mozilla/ContentEvents.h" #include "mozilla/dom/TimeEvent.h" -#include "mozilla/BasicEvents.h" #include "nsIDocShell.h" #include "nsIInterfaceRequestorUtils.h" #include "nsPresContext.h" namespace mozilla { namespace dom { TimeEvent::TimeEvent(EventTarget* aOwner, nsPresContext* aPresContext, - WidgetEvent* aEvent) + InternalSMILTimeEvent* aEvent) : Event(aOwner, aPresContext, - aEvent ? aEvent : new InternalUIEvent(false, 0)) - , mDetail(0) + aEvent ? aEvent : new InternalSMILTimeEvent(false, 0)) + , mDetail(mEvent->AsSMILTimeEvent()->detail) { SetIsDOMBinding(); if (aEvent) { mEventIsInternal = false; } else { mEventIsInternal = true; - mEvent->eventStructType = NS_SMIL_TIME_EVENT; } - if (mEvent->eventStructType == NS_SMIL_TIME_EVENT) { - mDetail = mEvent->AsUIEvent()->detail; - } - - mEvent->mFlags.mBubbles = false; - mEvent->mFlags.mCancelable = false; - if (mPresContext) { nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell(); if (docShell) { mView = docShell->GetWindow(); } } } @@ -87,15 +79,15 @@ TimeEvent::InitTimeEvent(const nsAString using namespace mozilla; using namespace mozilla::dom; nsresult NS_NewDOMTimeEvent(nsIDOMEvent** aInstancePtrResult, EventTarget* aOwner, nsPresContext* aPresContext, - WidgetEvent* aEvent) + InternalSMILTimeEvent* aEvent) { TimeEvent* it = new TimeEvent(aOwner, aPresContext, aEvent); NS_ADDREF(it); *aInstancePtrResult = static_cast<Event*>(it); return NS_OK; }
--- a/dom/smil/TimeEvent.h +++ b/dom/smil/TimeEvent.h @@ -14,17 +14,17 @@ namespace mozilla { namespace dom { class TimeEvent MOZ_FINAL : public Event, public nsIDOMTimeEvent { public: TimeEvent(EventTarget* aOwner, nsPresContext* aPresContext, - WidgetEvent* aEvent); + InternalSMILTimeEvent* aEvent); // nsISupports interface: NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TimeEvent, Event) // nsIDOMTimeEvent interface: NS_DECL_NSIDOMTIMEEVENT
--- a/dom/smil/nsSMILTimedElement.cpp +++ b/dom/smil/nsSMILTimedElement.cpp @@ -1,16 +1,16 @@ /* -*- 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 "mozilla/DebugOnly.h" -#include "mozilla/BasicEvents.h" +#include "mozilla/ContentEvents.h" #include "mozilla/EventDispatcher.h" #include "mozilla/dom/SVGAnimationElement.h" #include "nsSMILTimedElement.h" #include "nsAttrValueInlines.h" #include "nsSMILAnimationFunction.h" #include "nsSMILTimeValue.h" #include "nsSMILTimeValueSpec.h" #include "nsSMILInstanceTime.h" @@ -87,18 +87,17 @@ namespace public: AsyncTimeEventRunner(nsIContent* aTarget, uint32_t aMsg, int32_t aDetail) : mTarget(aTarget), mMsg(aMsg), mDetail(aDetail) { } NS_IMETHOD Run() { - InternalUIEvent event(true, mMsg); - event.eventStructType = NS_SMIL_TIME_EVENT; + InternalSMILTimeEvent event(true, mMsg); event.detail = mDetail; nsPresContext* context = nullptr; nsIDocument* doc = mTarget->GetCurrentDoc(); if (doc) { nsCOMPtr<nsIPresShell> shell = doc->GetShell(); if (shell) { context = shell->GetPresContext();
--- a/dom/wappush/src/moz.build +++ b/dom/wappush/src/moz.build @@ -1,14 +1,14 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']: - EXTRA_JS_MODULES = [ + EXTRA_JS_MODULES += [ 'gonk/CpPduHelper.jsm', 'gonk/SiPduHelper.jsm', 'gonk/SlPduHelper.jsm', 'gonk/WapPushManager.js', 'gonk/WbxmlPduHelper.jsm' ]
--- a/gfx/gl/GLBlitHelper.cpp +++ b/gfx/gl/GLBlitHelper.cpp @@ -540,18 +540,18 @@ GLBlitHelper::DeleteTexBlitProgram() if (mTexYUVPlanarBlit_Program) { mGL->fDeleteProgram(mTexYUVPlanarBlit_Program); mTexYUVPlanarBlit_Program = 0; } } void GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, - const gfx::IntSize& srcSize, - const gfx::IntSize& destSize) + const gfx::IntSize& srcSize, + const gfx::IntSize& destSize) { MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB)); MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB)); MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit)); ScopedBindFramebuffer boundFB(mGL); ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false); @@ -562,19 +562,19 @@ GLBlitHelper::BlitFramebufferToFramebuff mGL->fBlitFramebuffer(0, 0, srcSize.width, srcSize.height, 0, 0, destSize.width, destSize.height, LOCAL_GL_COLOR_BUFFER_BIT, LOCAL_GL_NEAREST); } void GLBlitHelper::BlitFramebufferToFramebuffer(GLuint srcFB, GLuint destFB, - const gfx::IntSize& srcSize, - const gfx::IntSize& destSize, - const GLFormats& srcFormats) + const gfx::IntSize& srcSize, + const gfx::IntSize& destSize, + const GLFormats& srcFormats) { MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB)); MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB)); if (mGL->IsSupported(GLFeature::framebuffer_blit)) { BlitFramebufferToFramebuffer(srcFB, destFB, srcSize, destSize); return; @@ -585,17 +585,21 @@ GLBlitHelper::BlitFramebufferToFramebuff BlitFramebufferToTexture(srcFB, tex, srcSize, srcSize); BlitTextureToFramebuffer(tex, destFB, srcSize, destSize); mGL->fDeleteTextures(1, &tex); } void -GLBlitHelper::BindAndUploadYUVTexture(Channel which, uint32_t width, uint32_t height, void* data, bool needsAllocation) +GLBlitHelper::BindAndUploadYUVTexture(Channel which, + uint32_t width, + uint32_t height, + void* data, + bool needsAllocation) { MOZ_ASSERT(which < Channel_Max, "Invalid channel!"); GLuint* srcTexArr[3] = {&mSrcTexY, &mSrcTexCb, &mSrcTexCr}; GLuint& tex = *srcTexArr[which]; if (!tex) { MOZ_ASSERT(needsAllocation); tex = CreateTexture(mGL, LOCAL_GL_LUMINANCE, LOCAL_GL_LUMINANCE, LOCAL_GL_UNSIGNED_BYTE, gfx::IntSize(width, height), false); @@ -623,34 +627,36 @@ GLBlitHelper::BindAndUploadYUVTexture(Ch LOCAL_GL_LUMINANCE, LOCAL_GL_UNSIGNED_BYTE, data); } } #ifdef MOZ_WIDGET_GONK void -GLBlitHelper::BindAndUploadExternalTexture(EGLImage image) { +GLBlitHelper::BindAndUploadExternalTexture(EGLImage image) +{ MOZ_ASSERT(image != EGL_NO_IMAGE, "Bad EGLImage"); if (!mSrcTexEGL) { mGL->fGenTextures(1, &mSrcTexEGL); mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mSrcTexEGL); mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE); mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE); mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST); mGL->fTexParameteri(LOCAL_GL_TEXTURE_EXTERNAL_OES, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST); } else { mGL->fBindTexture(LOCAL_GL_TEXTURE_EXTERNAL_OES, mSrcTexEGL); } mGL->fEGLImageTargetTexture2D(LOCAL_GL_TEXTURE_EXTERNAL_OES, image); } bool -GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip) { +GLBlitHelper::BlitGrallocImage(layers::GrallocImage* grallocImage, bool yFlip) +{ ScopedBindTextureUnit boundTU(mGL, LOCAL_GL_TEXTURE0); mGL->fClear(LOCAL_GL_COLOR_BUFFER_BIT); EGLint attrs[] = { LOCAL_EGL_IMAGE_PRESERVED, LOCAL_EGL_TRUE, LOCAL_EGL_NONE, LOCAL_EGL_NONE }; EGLImage image = sEGLLibrary.fCreateImage(sEGLLibrary.Display(), @@ -708,33 +714,40 @@ GLBlitHelper::BlitPlanarYCbCrImage(layer for (int i = 0; i < 3; i++) { mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i); mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, oldTex[i]); } return true; } bool -GLBlitHelper::BlitImageToTexture(layers::Image* srcImage, const gfx::IntSize& destSize, GLuint destTex, GLenum destTarget, bool yFlip, GLuint xoffset, GLuint yoffset, GLuint cropWidth, GLuint cropHeight) +GLBlitHelper::BlitImageToTexture(layers::Image* srcImage, + const gfx::IntSize& destSize, + GLuint destTex, + GLenum destTarget, + bool yFlip, + GLuint xoffset, + GLuint yoffset, + GLuint cropWidth, + GLuint cropHeight) { ScopedGLDrawState autoStates(mGL); BlitType type; - switch (srcImage->GetFormat()) - { - case ImageFormat::PLANAR_YCBCR: - type = ConvertPlanarYCbCr; - break; - case ImageFormat::GRALLOC_PLANAR_YCBCR: + switch (srcImage->GetFormat()) { + case ImageFormat::PLANAR_YCBCR: + type = ConvertPlanarYCbCr; + break; + case ImageFormat::GRALLOC_PLANAR_YCBCR: #ifdef MOZ_WIDGET_GONK - type = ConvertGralloc; - break; + type = ConvertGralloc; + break; #endif - default: - return false; + default: + return false; } bool init = InitTexQuadProgram(type); if (!init) { return false; } if (!mFBO) { @@ -762,19 +775,19 @@ GLBlitHelper::BlitImageToTexture(layers: return BlitPlanarYCbCrImage(yuvImage, yFlip); } return false; } void GLBlitHelper::BlitTextureToFramebuffer(GLuint srcTex, GLuint destFB, - const gfx::IntSize& srcSize, - const gfx::IntSize& destSize, - GLenum srcTarget) + const gfx::IntSize& srcSize, + const gfx::IntSize& destSize, + GLenum srcTarget) { MOZ_ASSERT(mGL->fIsTexture(srcTex)); MOZ_ASSERT(!destFB || mGL->fIsFramebuffer(destFB)); if (mGL->IsSupported(GLFeature::framebuffer_blit)) { ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget); MOZ_ASSERT(srcWrapper.IsComplete()); @@ -808,19 +821,19 @@ GLBlitHelper::BlitTextureToFramebuffer(G printf_stderr("[%s:%d] Fatal Error: Failed to prepare to blit texture->framebuffer.\n"); MOZ_CRASH(); } mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); } void GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex, - const gfx::IntSize& srcSize, - const gfx::IntSize& destSize, - GLenum destTarget) + const gfx::IntSize& srcSize, + const gfx::IntSize& destSize, + GLenum destTarget) { MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB)); MOZ_ASSERT(mGL->fIsTexture(destTex)); if (mGL->IsSupported(GLFeature::framebuffer_blit)) { ScopedFramebufferForTexture destWrapper(mGL, destTex, destTarget); BlitFramebufferToFramebuffer(srcFB, destWrapper.FB(), @@ -835,19 +848,19 @@ GLBlitHelper::BlitFramebufferToTexture(G mGL->fCopyTexSubImage2D(destTarget, 0, 0, 0, 0, 0, srcSize.width, srcSize.height); } void GLBlitHelper::BlitTextureToTexture(GLuint srcTex, GLuint destTex, - const gfx::IntSize& srcSize, - const gfx::IntSize& destSize, - GLenum srcTarget, GLenum destTarget) + const gfx::IntSize& srcSize, + const gfx::IntSize& destSize, + GLenum srcTarget, GLenum destTarget) { MOZ_ASSERT(mGL->fIsTexture(srcTex)); MOZ_ASSERT(mGL->fIsTexture(destTex)); // Generally, just use the CopyTexSubImage path ScopedFramebufferForTexture srcWrapper(mGL, srcTex, srcTarget); BlitFramebufferToTexture(srcWrapper.FB(), destTex,
--- a/gfx/gl/GLReadTexImageHelper.cpp +++ b/gfx/gl/GLReadTexImageHelper.cpp @@ -1,21 +1,24 @@ /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* vim: set ts=8 sts=4 et sw=4 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "GLReadTexImageHelper.h" + +#include "gfx2DGlue.h" +#include "gfxTypes.h" #include "GLContext.h" #include "OGLShaderProgram.h" -#include "gfxTypes.h" #include "ScopedGLHelpers.h" + #include "mozilla/gfx/2D.h" -#include "gfx2DGlue.h" +#include "mozilla/Move.h" namespace mozilla { namespace gl { using namespace mozilla::gfx; GLReadTexImageHelper::GLReadTexImageHelper(GLContext* gl) : mGL(gl) @@ -76,28 +79,27 @@ readTextureImageFS_TEXTURE_RECTANGLE[] = "#ifdef GL_ES\n" "precision mediump float;\n" "#endif\n" "varying vec2 vTexCoord;\n" "uniform sampler2DRect uTexture;\n" "void main() { gl_FragColor = texture2DRect(uTexture, vTexCoord).bgra; }"; GLuint -GLReadTexImageHelper::TextureImageProgramFor(GLenum aTextureTarget, int aConfig) { +GLReadTexImageHelper::TextureImageProgramFor(GLenum aTextureTarget, + int aConfig) +{ int variant = 0; const GLchar* readTextureImageFS = nullptr; - if (aTextureTarget == LOCAL_GL_TEXTURE_2D) - { - if (aConfig & mozilla::layers::ENABLE_TEXTURE_RB_SWAP) - { // Need to swizzle R/B. + if (aTextureTarget == LOCAL_GL_TEXTURE_2D) { + if (aConfig & mozilla::layers::ENABLE_TEXTURE_RB_SWAP) { + // Need to swizzle R/B. readTextureImageFS = readTextureImageFS_TEXTURE_2D_BGRA; variant = 1; - } - else - { + } else { readTextureImageFS = readTextureImageFS_TEXTURE_2D; variant = 0; } } else if (aTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL) { readTextureImageFS = readTextureImageFS_TEXTURE_EXTERNAL; variant = 2; } else if (aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE) { readTextureImageFS = readTextureImageFS_TEXTURE_RECTANGLE; @@ -200,107 +202,134 @@ GetActualReadFormats(GLContext* gl, return false; } else { readFormat = destFormat; readType = destType; return true; } } -static void SwapRAndBComponents(DataSourceSurface* surf) +static void +SwapRAndBComponents(DataSourceSurface* surf) { - uint8_t *row = surf->GetData(); - if (!row) { - MOZ_ASSERT(false, "SwapRAndBComponents: Failed to get data from DataSourceSurface."); - return; - } - - size_t rowBytes = surf->GetSize().width*4; - size_t rowHole = surf->Stride() - rowBytes; + DataSourceSurface::MappedSurface map; + MOZ_ALWAYS_TRUE( surf->Map(DataSourceSurface::MapType::READ_WRITE, &map) ); + MOZ_ASSERT(map.mStride >= 0); - size_t rows = surf->GetSize().height; - - while (rows) { - - const uint8_t *rowEnd = row + rowBytes; + const size_t rowBytes = surf->GetSize().width*4; + const size_t rowHole = map.mStride - rowBytes; - while (row != rowEnd) { - row[0] ^= row[2]; - row[2] ^= row[0]; - row[0] ^= row[2]; - row += 4; + uint8_t* row = map.mData; + if (!row) { + MOZ_ASSERT(false, "SwapRAndBComponents: Failed to get data from" + " DataSourceSurface."); + surf->Unmap(); + return; } - row += rowHole; - --rows; - } + const size_t rows = surf->GetSize().height; + for (size_t i = 0; i < rows; i++) { + const uint8_t* rowEnd = row + rowBytes; + + while (row != rowEnd) { + Swap(row[0], row[2]); + row += 4; + } + + row += rowHole; + } + + surf->Unmap(); } -static uint16_t PackRGB565(uint8_t r, uint8_t g, uint8_t b) +static uint16_t +PackRGB565(uint8_t r, uint8_t g, uint8_t b) { uint16_t pixel = ((r << 11) & 0xf800) | ((g << 5) & 0x07e0) | ((b ) & 0x001f); return pixel; } -static void CopyDataSourceSurface(DataSourceSurface* aSource, - DataSourceSurface* aDest) +static void +CopyDataSourceSurface(DataSourceSurface* aSource, + DataSourceSurface* aDest) { - MOZ_ASSERT(aSource->GetSize() == aDest->GetSize()); - MOZ_ASSERT(aSource->GetFormat() == SurfaceFormat::B8G8R8A8 || - aSource->GetFormat() == SurfaceFormat::B8G8R8X8); + // Don't worry too much about speed. + MOZ_ASSERT(aSource->GetSize() == aDest->GetSize()); + MOZ_ASSERT(aSource->GetFormat() == SurfaceFormat::R8G8B8A8 || + aSource->GetFormat() == SurfaceFormat::R8G8B8X8 || + aSource->GetFormat() == SurfaceFormat::B8G8R8A8 || + aSource->GetFormat() == SurfaceFormat::B8G8R8X8); + MOZ_ASSERT(aDest->GetFormat() == SurfaceFormat::R8G8B8A8 || + aDest->GetFormat() == SurfaceFormat::R8G8B8X8 || + aDest->GetFormat() == SurfaceFormat::B8G8R8A8 || + aDest->GetFormat() == SurfaceFormat::B8G8R8X8 || + aDest->GetFormat() == SurfaceFormat::R5G6B5); - uint8_t *srcRow = aSource->GetData(); - size_t srcRowBytes = aSource->GetSize().width * BytesPerPixel(aSource->GetFormat()); - size_t srcRowHole = aSource->Stride() - srcRowBytes; + const bool isSrcBGR = aSource->GetFormat() == SurfaceFormat::B8G8R8A8 || + aSource->GetFormat() == SurfaceFormat::B8G8R8X8; + const bool isDestBGR = aDest->GetFormat() == SurfaceFormat::B8G8R8A8 || + aDest->GetFormat() == SurfaceFormat::B8G8R8X8; + const bool needsSwap02 = isSrcBGR != isDestBGR; - uint8_t *destRow = aDest->GetData(); - size_t destRowBytes = aDest->GetSize().width * BytesPerPixel(aDest->GetFormat()); - size_t destRowHole = aDest->Stride() - destRowBytes; + const bool srcHasAlpha = aSource->GetFormat() == SurfaceFormat::R8G8B8A8 || + aSource->GetFormat() == SurfaceFormat::B8G8R8A8; + const bool destHasAlpha = aDest->GetFormat() == SurfaceFormat::R8G8B8A8 || + aDest->GetFormat() == SurfaceFormat::B8G8R8A8; + const bool needsAlphaMask = !srcHasAlpha && destHasAlpha; - bool needsRBSwap = false; - if (aDest->GetFormat() == SurfaceFormat::B8G8R8A8 || - aDest->GetFormat() == SurfaceFormat::B8G8R8X8) { - needsRBSwap = true; - } + const bool needsConvertTo16Bits = aDest->GetFormat() == SurfaceFormat::R5G6B5; - bool needsConvertTo16Bits = false; - if (aDest->GetFormat() == SurfaceFormat::R5G6B5) { - needsConvertTo16Bits = true; - } + DataSourceSurface::MappedSurface srcMap; + DataSourceSurface::MappedSurface destMap; + MOZ_ALWAYS_TRUE( aSource->Map(DataSourceSurface::MapType::READ, &srcMap) ); + MOZ_ALWAYS_TRUE( aDest->Map(DataSourceSurface::MapType::WRITE, &destMap) ); + MOZ_ASSERT(srcMap.mStride >= 0); + MOZ_ASSERT(destMap.mStride >= 0); - size_t rows = aSource->GetSize().height; + const size_t srcBPP = BytesPerPixel(aSource->GetFormat()); + const size_t srcRowBytes = aSource->GetSize().width * srcBPP; + const size_t srcRowHole = srcMap.mStride - srcRowBytes; - while (rows) { - const uint8_t *srcRowEnd = srcRow + srcRowBytes; + const size_t destBPP = BytesPerPixel(aDest->GetFormat()); + const size_t destRowBytes = aDest->GetSize().width * destBPP; + const size_t destRowHole = destMap.mStride - destRowBytes; + + uint8_t* srcRow = srcMap.mData; + uint8_t* destRow = destMap.mData; + const size_t rows = aSource->GetSize().height; + for (size_t i = 0; i < rows; i++) { + const uint8_t* srcRowEnd = srcRow + srcRowBytes; - while (srcRow != srcRowEnd) { - uint8_t r = needsRBSwap ? srcRow[2] : srcRow[0]; - uint8_t g = srcRow[1]; - uint8_t b = needsRBSwap ? srcRow[0] : srcRow[2]; - uint8_t a = srcRow[3]; + while (srcRow != srcRowEnd) { + uint8_t d0 = needsSwap02 ? srcRow[2] : srcRow[0]; + uint8_t d1 = srcRow[1]; + uint8_t d2 = needsSwap02 ? srcRow[0] : srcRow[2]; + uint8_t d3 = needsAlphaMask ? 0xff : srcRow[3]; - if (needsConvertTo16Bits) { - *(uint16_t*)destRow = PackRGB565(r, g, b); - } else { - destRow[0] = r; - destRow[1] = g; - destRow[2] = b; - destRow[3] = a; - } - srcRow += BytesPerPixel(aSource->GetFormat()); - destRow += BytesPerPixel(aDest->GetFormat()); + if (needsConvertTo16Bits) { + *(uint16_t*)destRow = PackRGB565(d0, d1, d2); + } else { + destRow[0] = d0; + destRow[1] = d1; + destRow[2] = d2; + destRow[3] = d3; + } + srcRow += srcBPP; + destRow += destBPP; + } + + srcRow += srcRowHole; + destRow += destRowHole; } - srcRow += srcRowHole; - destRow += destRowHole; - --rows; - } + aSource->Unmap(); + aDest->Unmap(); } static int CalcRowStride(int width, int pixelSize, int alignment) { MOZ_ASSERT(alignment); int rowStride = width * pixelSize; @@ -321,47 +350,48 @@ GuessAlignment(int width, int pixelSize, NS_WARNING("Bad alignment for GLES. Will use temp surf for readback."); return 0; } } return alignment; } void -ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) { +ReadPixelsIntoDataSurface(GLContext* gl, DataSourceSurface* dest) +{ gl->MakeCurrent(); MOZ_ASSERT(dest->GetSize().width != 0); MOZ_ASSERT(dest->GetSize().height != 0); bool hasAlpha = dest->GetFormat() == SurfaceFormat::B8G8R8A8 || dest->GetFormat() == SurfaceFormat::R8G8B8A8; int destPixelSize; GLenum destFormat; GLenum destType; switch (dest->GetFormat()) { - case SurfaceFormat::B8G8R8A8: - case SurfaceFormat::B8G8R8X8: - // Needs host (little) endian ARGB. - destFormat = LOCAL_GL_BGRA; - destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; - break; - case SurfaceFormat::R8G8B8A8: - case SurfaceFormat::R8G8B8X8: - // Needs host (little) endian ABGR. - destFormat = LOCAL_GL_RGBA; - destType = LOCAL_GL_UNSIGNED_BYTE; - break; - case SurfaceFormat::R5G6B5: - destFormat = LOCAL_GL_RGB; - destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV; - break; - default: - MOZ_CRASH("Bad format."); + case SurfaceFormat::B8G8R8A8: + case SurfaceFormat::B8G8R8X8: + // Needs host (little) endian ARGB. + destFormat = LOCAL_GL_BGRA; + destType = LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV; + break; + case SurfaceFormat::R8G8B8A8: + case SurfaceFormat::R8G8B8X8: + // Needs host (little) endian ABGR. + destFormat = LOCAL_GL_RGBA; + destType = LOCAL_GL_UNSIGNED_BYTE; + break; + case SurfaceFormat::R5G6B5: + destFormat = LOCAL_GL_RGB; + destType = LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV; + break; + default: + MOZ_CRASH("Bad format."); } destPixelSize = BytesPerPixel(dest->GetFormat()); MOZ_ASSERT(dest->GetSize().width * destPixelSize <= dest->Stride()); GLenum readFormat = destFormat; GLenum readType = destType; bool needsTempSurf = !GetActualReadFormats(gl, destFormat, destType, @@ -377,17 +407,21 @@ ReadPixelsIntoDataSurface(GLContext* gl, } if (needsTempSurf) { if (gl->DebugMode()) { NS_WARNING("Needing intermediary surface for ReadPixels. This will be slow!"); } SurfaceFormat readFormatGFX; switch (readFormat) { - case LOCAL_GL_RGBA: + case LOCAL_GL_RGBA: { + readFormatGFX = hasAlpha ? SurfaceFormat::R8G8B8A8 + : SurfaceFormat::R8G8B8X8; + break; + } case LOCAL_GL_BGRA: { readFormatGFX = hasAlpha ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8; break; } case LOCAL_GL_RGB: { MOZ_ASSERT(destPixelSize == 2); MOZ_ASSERT(readType == LOCAL_GL_UNSIGNED_SHORT_5_6_5_REV); @@ -452,18 +486,17 @@ ReadPixelsIntoDataSurface(GLContext* gl, CopyDataSourceSurface(readSurf, dest); } // Check if GL is giving back 1.0 alpha for // RGBA reads to RGBA images from no-alpha buffers. #ifdef XP_MACOSX if (gl->WorkAroundDriverBugs() && gl->Vendor() == gl::GLVendor::NVIDIA && - (dest->GetFormat() == SurfaceFormat::R8G8B8A8 || - dest->GetFormat() == SurfaceFormat::B8G8R8A8) && + hasAlpha && width && height) { GLint alphaBits = 0; gl->fGetIntegerv(LOCAL_GL_ALPHA_BITS, &alphaBits); if (!alphaBits) { const uint32_t alphaMask = gfxPackedPixelNoPreMultiply(0xff,0,0,0); MOZ_ASSERT(dest->GetSize().width * destPixelSize == dest->Stride()); @@ -478,46 +511,50 @@ ReadPixelsIntoDataSurface(GLContext* gl, *itr |= alphaMask; } } } } #endif } -static TemporaryRef<DataSourceSurface> YInvertImageSurface(DataSourceSurface* aSurf) +static TemporaryRef<DataSourceSurface> +YInvertImageSurface(DataSourceSurface* aSurf) { - RefPtr<DataSourceSurface> temp = - Factory::CreateDataSourceSurfaceWithStride(aSurf->GetSize(), - aSurf->GetFormat(), - aSurf->Stride()); - if (!temp) { - return nullptr; - } - DataSourceSurface::MappedSurface map; - if (!temp->Map(DataSourceSurface::MapType::WRITE, &map)) { - return nullptr; - } - RefPtr<DrawTarget> dt = - Factory::CreateDrawTargetForData(BackendType::CAIRO, - map.mData, - temp->GetSize(), - map.mStride, - temp->GetFormat()); - if (!dt) { + RefPtr<DataSourceSurface> temp = + Factory::CreateDataSourceSurfaceWithStride(aSurf->GetSize(), + aSurf->GetFormat(), + aSurf->Stride()); + if (!temp) { + return nullptr; + } + + DataSourceSurface::MappedSurface map; + if (!temp->Map(DataSourceSurface::MapType::WRITE, &map)) { + return nullptr; + } + + RefPtr<DrawTarget> dt = + Factory::CreateDrawTargetForData(BackendType::CAIRO, + map.mData, + temp->GetSize(), + map.mStride, + temp->GetFormat()); + if (!dt) { + temp->Unmap(); + return nullptr; + } + + dt->SetTransform(Matrix::Translation(0.0, aSurf->GetSize().height) * + Matrix::Scaling(1.0, -1.0)); + Rect rect(0, 0, aSurf->GetSize().width, aSurf->GetSize().height); + dt->DrawSurface(aSurf, rect, rect, DrawSurfaceOptions(), + DrawOptions(1.0, CompositionOp::OP_SOURCE, AntialiasMode::NONE)); temp->Unmap(); - return nullptr; - } - dt->SetTransform(Matrix::Translation(0.0, aSurf->GetSize().height) * - Matrix::Scaling(1.0, -1.0)); - Rect rect(0, 0, aSurf->GetSize().width, aSurf->GetSize().height); - dt->DrawSurface(aSurf, rect, rect, DrawSurfaceOptions(), - DrawOptions(1.0, CompositionOp::OP_SOURCE, AntialiasMode::NONE)); - temp->Unmap(); - return temp.forget(); + return temp.forget(); } TemporaryRef<DataSourceSurface> ReadBackSurface(GLContext* gl, GLuint aTexture, bool aYInvert, SurfaceFormat aFormat) { gl->MakeCurrent(); gl->GuaranteeResolve(); gl->fActiveTexture(LOCAL_GL_TEXTURE0); @@ -535,27 +572,29 @@ ReadBackSurface(GLContext* gl, GLuint aT return nullptr; } uint32_t currentPackAlignment = 0; gl->fGetIntegerv(LOCAL_GL_PACK_ALIGNMENT, (GLint*)¤tPackAlignment); if (currentPackAlignment != 4) { gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, 4); } + gl->fGetTexImage(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGBA, LOCAL_GL_UNSIGNED_BYTE, surf->GetData()); + if (currentPackAlignment != 4) { gl->fPixelStorei(LOCAL_GL_PACK_ALIGNMENT, currentPackAlignment); } if (aFormat == SurfaceFormat::R8G8B8A8 || aFormat == SurfaceFormat::R8G8B8X8) { - SwapRAndBComponents(surf); + SwapRAndBComponents(surf); } if (aYInvert) { - surf = YInvertImageSurface(surf); + surf = YInvertImageSurface(surf); } return surf.forget(); } #define CLEANUP_IF_GLERROR_OCCURRED(x) \ if (DidGLErrorOccur(x)) { \ isurf = nullptr; \ @@ -697,11 +736,10 @@ GLReadTexImageHelper::ReadTexImage(GLuin if (oldTexUnit != LOCAL_GL_TEXTURE0) mGL->fActiveTexture(oldTexUnit); return isurf.forget(); } #undef CLEANUP_IF_GLERROR_OCCURRED - } }
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -62,16 +62,17 @@ #include "SharedMemoryBasic.h" // for SharedMemoryBasic // #define APZC_ENABLE_RENDERTRACE #define ENABLE_APZC_LOGGING 0 // #define ENABLE_APZC_LOGGING 1 #if ENABLE_APZC_LOGGING +# include "LayersLogging.h" # define APZC_LOG(...) printf_stderr("APZC: " __VA_ARGS__) # define APZC_LOG_FM(fm, prefix, ...) \ { std::stringstream ss; \ ss << nsPrintfCString(prefix, __VA_ARGS__).get(); \ AppendToString(ss, fm, ":", "", true); \ APZC_LOG("%s", ss.str().c_str()); \ } #else
--- a/gfx/thebes/gfxFontFamilyList.h +++ b/gfx/thebes/gfxFontFamilyList.h @@ -160,59 +160,46 @@ struct FontFamilyName MOZ_FINAL { nsString mName; // empty if mType != eFamily_named }; inline bool operator==(const FontFamilyName& a, const FontFamilyName& b) { return a.mType == b.mType && a.mName == b.mName; } -class FontFamilyList; - -template<> -struct HasDangerousPublicDestructor<FontFamilyList> -{ - static const bool value = true; -}; - /** * font family list, array of font families and a default font type. * font family names are either named strings or generics. the default * font type is used to preserve the variable font fallback behavior */ -class FontFamilyList MOZ_FINAL { +class FontFamilyList { public: - FontFamilyList() : mDefaultFontType(eFamily_none) { - MOZ_COUNT_CTOR(FontFamilyList); + FontFamilyList() + : mDefaultFontType(eFamily_none) + { } FontFamilyList(FontFamilyType aGenericType) : mDefaultFontType(eFamily_none) { Append(FontFamilyName(aGenericType)); - MOZ_COUNT_CTOR(FontFamilyList); } FontFamilyList(const nsAString& aFamilyName, QuotedName aQuoted) : mDefaultFontType(eFamily_none) { Append(FontFamilyName(aFamilyName, aQuoted)); - MOZ_COUNT_CTOR(FontFamilyList); } FontFamilyList(const FontFamilyList& aOther) - : mFontlist(aOther.mFontlist), mDefaultFontType(aOther.mDefaultFontType) + : mFontlist(aOther.mFontlist) + , mDefaultFontType(aOther.mDefaultFontType) { - MOZ_COUNT_CTOR(FontFamilyList); - } - - ~FontFamilyList() { - MOZ_COUNT_DTOR(FontFamilyList); } void Append(const FontFamilyName& aFamilyName) { mFontlist.AppendElement(aFamilyName); } void Append(const nsTArray<nsString>& aFamilyNameList) { uint32_t len = aFamilyNameList.Length(); @@ -305,18 +292,16 @@ public: size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { return mFontlist.SizeOfExcludingThis(aMallocSizeOf); } size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); } - NS_INLINE_DECL_REFCOUNTING(FontFamilyList) - private: nsTArray<FontFamilyName> mFontlist; FontFamilyType mDefaultFontType; // none, serif or sans-serif }; inline bool operator==(const FontFamilyList& a, const FontFamilyList& b) { return a.Equals(b);
--- a/js/public/Id.h +++ b/js/public/Id.h @@ -55,16 +55,26 @@ JSID_IS_STRING(jsid id) static MOZ_ALWAYS_INLINE JSString * JSID_TO_STRING(jsid id) { MOZ_ASSERT(JSID_IS_STRING(id)); return (JSString *)JSID_BITS(id); } +/* + * Only JSStrings that have been interned via the JSAPI can be turned into + * jsids by API clients. + * + * N.B. if a jsid is backed by a string which has not been interned, that + * string must be appropriately rooted to avoid being collected by the GC. + */ +JS_PUBLIC_API(jsid) +INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str); + static MOZ_ALWAYS_INLINE bool JSID_IS_ZERO(jsid id) { return JSID_BITS(id) == 0; } static MOZ_ALWAYS_INLINE bool JSID_IS_INT(jsid id)
--- a/js/public/OldDebugAPI.h +++ b/js/public/OldDebugAPI.h @@ -125,93 +125,16 @@ extern JS_PUBLIC_API(const jschar *) JS_GetScriptSourceMap(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(unsigned) JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script); extern JS_PUBLIC_API(unsigned) JS_GetScriptLineExtent(JSContext *cx, JSScript *script); -/************************************************************************/ - -/* - * JSAbstractFramePtr is the public version of AbstractFramePtr, a pointer to a - * StackFrame or baseline JIT frame. - */ -class JS_PUBLIC_API(JSAbstractFramePtr) -{ - uintptr_t ptr_; - jsbytecode *pc_; - - protected: - JSAbstractFramePtr() - : ptr_(0), pc_(nullptr) - { } - - public: - JSAbstractFramePtr(void *raw, jsbytecode *pc); - - uintptr_t raw() const { return ptr_; } - jsbytecode *pc() const { return pc_; } - - operator bool() const { return !!ptr_; } - - JSObject *scopeChain(JSContext *cx); - JSObject *callObject(JSContext *cx); - - JSFunction *maybeFun(); - JSScript *script(); - - bool getThisValue(JSContext *cx, JS::MutableHandleValue thisv); - - bool isDebuggerFrame(); - - bool evaluateInStackFrame(JSContext *cx, - const char *bytes, unsigned length, - const char *filename, unsigned lineno, - JS::MutableHandleValue rval); - - bool evaluateUCInStackFrame(JSContext *cx, - const jschar *chars, unsigned length, - const char *filename, unsigned lineno, - JS::MutableHandleValue rval); -}; - -class JS_PUBLIC_API(JSNullFramePtr) : public JSAbstractFramePtr -{ - public: - JSNullFramePtr() - : JSAbstractFramePtr() - {} -}; - -/* - * This class does not work when IonMonkey is active. It's only used by jsd, - * which can only be used when IonMonkey is disabled. - * - * To find the calling script and line number, use JS_DescribeSciptedCaller. - * To summarize the call stack, use JS::DescribeStack. - */ -class JS_PUBLIC_API(JSBrokenFrameIterator) -{ - void *data_; - - public: - explicit JSBrokenFrameIterator(JSContext *cx); - ~JSBrokenFrameIterator(); - - bool done() const; - JSBrokenFrameIterator& operator++(); - - JSAbstractFramePtr abstractFramePtr() const; - jsbytecode *pc() const; - - bool isConstructing() const; -}; - /************************************************************************/ /** * Add various profiling-related functions as properties of the given object. */ extern JS_PUBLIC_API(bool) JS_DefineProfilingFunctions(JSContext *cx, JSObject *obj);
--- a/js/src/jit-test/tests/latin1/toLowerCase-toUpperCase.js +++ b/js/src/jit-test/tests/latin1/toLowerCase-toUpperCase.js @@ -27,19 +27,21 @@ function testToLowerCase() { testToLowerCase(); function testToUpperCase() { var s1 = "abcdefgABCDEFGH 12345"; assertEq(isLatin1(s1), true); // Latin1 var s2 = s1.toUpperCase(); + assertEq(isLatin1(s2), true); assertEq(s2, "ABCDEFGABCDEFGH 12345"); s2 = s1.toLocaleUpperCase(); + assertEq(isLatin1(s2), true); assertEq(s2, "ABCDEFGABCDEFGH 12345"); // TwoByte s2 = "abcdefg\u1200ABCDEFGH 12345\u1E0F".toUpperCase(); assertEq(s2, "ABCDEFG\u1200ABCDEFGH 12345\u1E0E"); s2 = "abcdefg\u1200ABCDEFGH 12345\u1E0F".toLocaleUpperCase(); assertEq(s2, "ABCDEFG\u1200ABCDEFGH 12345\u1E0E");
--- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -1789,17 +1789,17 @@ IonBuilder::inlineUnsafeSetReservedSlot( callInfo.setImplicitlyUsedUnchecked(); MStoreFixedSlot *store = MStoreFixedSlot::New(alloc(), callInfo.getArg(0), slot, callInfo.getArg(2)); current->add(store); current->push(store); if (NeedsPostBarrier(info(), callInfo.getArg(2))) - current->add(MPostWriteBarrier::New(alloc(), callInfo.thisArg(), callInfo.getArg(2))); + current->add(MPostWriteBarrier::New(alloc(), callInfo.getArg(0), callInfo.getArg(2))); return InliningStatus_Inlined; } IonBuilder::InliningStatus IonBuilder::inlineUnsafeGetReservedSlot(CallInfo &callInfo) { if (callInfo.argc() != 2 || callInfo.constructing())
--- a/js/src/jit/arm/Simulator-arm.cpp +++ b/js/src/jit/arm/Simulator-arm.cpp @@ -1425,16 +1425,18 @@ ReturnType Simulator::getFromVFPRegister memcpy(&value, buffer, register_size * sizeof(vfp_registers_[0])); return value; } // These forced-instantiations are for jsapi-tests. Evidently, nothing // requires these to be instantiated. template double Simulator::getFromVFPRegister<double, 2>(int reg_index); template float Simulator::getFromVFPRegister<float, 1>(int reg_index); +template void Simulator::setVFPRegister<double, 2>(int reg_index, const double& value); +template void Simulator::setVFPRegister<float, 1>(int reg_index, const float& value); void Simulator::getFpArgs(double *x, double *y, int32_t *z) { if (UseHardFpABI()) { *x = get_double_from_d_register(0); *y = get_double_from_d_register(1); *z = get_register(0);
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -798,26 +798,16 @@ JS_NumberValue(double d) return DOUBLE_TO_JSVAL(d); } /************************************************************************/ JS_PUBLIC_API(bool) JS_StringHasBeenInterned(JSContext *cx, JSString *str); -/* - * Only JSStrings that have been interned via the JSAPI can be turned into - * jsids by API clients. - * - * N.B. if a jsid is backed by a string which has not been interned, that - * string must be appropriately rooted to avoid being collected by the GC. - */ -JS_PUBLIC_API(jsid) -INTERNED_STRING_TO_JSID(JSContext *cx, JSString *str); - namespace JS { // Container class for passing in script source buffers to the JS engine. This // not only groups the buffer and length values, it also provides a way to // optionally pass ownership of the buffer to the JS engine without copying. // Rules for use: // // 1) The data array must be allocated with js_malloc() or js_realloc() if
--- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -698,37 +698,54 @@ str_substring(JSContext *cx, unsigned ar } template <typename CharT> static JSString * ToLowerCase(JSContext *cx, JSLinearString *str) { // Unlike toUpperCase, toLowerCase has the nice invariant that if the input // is a Latin1 string, the output is also a Latin1 string. + UniquePtr<CharT[], JS::FreePolicy> newChars; size_t length = str->length(); - ScopedJSFreePtr<CharT> newChars(cx->pod_malloc<CharT>(length + 1)); - if (!newChars) - return nullptr; - { AutoCheckCannotGC nogc; const CharT *chars = str->chars<CharT>(nogc); - for (size_t i = 0; i < length; i++) { + + // Look for the first upper case character. + size_t i = 0; + for (; i < length; i++) { + jschar c = chars[i]; + if (unicode::ToLowerCase(c) != c) + break; + } + + // If all characters are lower case, return the input string. + if (i == length) + return str; + + newChars = cx->make_pod_array<CharT>(length + 1); + if (!newChars) + return nullptr; + + PodCopy(newChars.get(), chars, i); + + for (; i < length; i++) { jschar c = unicode::ToLowerCase(chars[i]); - MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), c <= 0xff); + MOZ_ASSERT_IF((IsSame<CharT, Latin1Char>::value), c <= JSString::MAX_LATIN1_CHAR); newChars[i] = c; } + newChars[length] = 0; } JSString *res = NewStringDontDeflate<CanGC>(cx, newChars.get(), length); if (!res) return nullptr; - newChars.forget(); + newChars.release(); return res; } static inline bool ToLowerCaseHelper(JSContext *cx, CallReceiver call) { RootedString str(cx, ThisToStringForStringProto(cx, call)); if (!str) @@ -775,40 +792,111 @@ str_toLocaleLowerCase(JSContext *cx, uns args.rval().set(result); return true; } return ToLowerCaseHelper(cx, args); } +template <typename DestChar, typename SrcChar> +static void +ToUpperCaseImpl(DestChar *destChars, const SrcChar *srcChars, size_t firstLowerCase, size_t length) +{ + MOZ_ASSERT(firstLowerCase < length); + + for (size_t i = 0; i < firstLowerCase; i++) + destChars[i] = srcChars[i]; + + for (size_t i = firstLowerCase; i < length; i++) { + jschar c = unicode::ToUpperCase(srcChars[i]); + MOZ_ASSERT_IF((IsSame<DestChar, Latin1Char>::value), c <= JSString::MAX_LATIN1_CHAR); + destChars[i] = c; + } + + destChars[length] = '\0'; +} + template <typename CharT> static JSString * ToUpperCase(JSContext *cx, JSLinearString *str) { - // toUpperCase on a Latin1 string can yield a non-Latin1 string. For now, - // we use a TwoByte string for the result. + typedef UniquePtr<Latin1Char[], JS::FreePolicy> Latin1CharPtr; + typedef UniquePtr<jschar[], JS::FreePolicy> TwoByteCharPtr; + + mozilla::MaybeOneOf<Latin1CharPtr, TwoByteCharPtr> newChars; size_t length = str->length(); - ScopedJSFreePtr<jschar> newChars(cx->pod_malloc<jschar>(length + 1)); - if (!newChars) - return nullptr; - { AutoCheckCannotGC nogc; const CharT *chars = str->chars<CharT>(nogc); - for (size_t i = 0; i < length; i++) - newChars[i] = unicode::ToUpperCase(chars[i]); - newChars[length] = 0; + + // Look for the first lower case character. + size_t i = 0; + for (; i < length; i++) { + jschar c = chars[i]; + if (unicode::ToUpperCase(c) != c) + break; + } + + // If all characters are upper case, return the input string. + if (i == length) + return str; + + // If the string is Latin1, check if it contains the MICRO SIGN (0xb5) + // or SMALL LETTER Y WITH DIAERESIS (0xff) character. The corresponding + // upper case characters are not in the Latin1 range. + bool resultIsLatin1; + if (IsSame<CharT, Latin1Char>::value) { + resultIsLatin1 = true; + for (size_t j = i; j < length; j++) { + Latin1Char c = chars[j]; + if (c == 0xb5 || c == 0xff) { + MOZ_ASSERT(unicode::ToUpperCase(c) > JSString::MAX_LATIN1_CHAR); + resultIsLatin1 = false; + break; + } else { + MOZ_ASSERT(unicode::ToUpperCase(c) <= JSString::MAX_LATIN1_CHAR); + } + } + } else { + resultIsLatin1 = false; + } + + if (resultIsLatin1) { + Latin1CharPtr buf = cx->make_pod_array<Latin1Char>(length + 1); + if (!buf) + return nullptr; + + ToUpperCaseImpl(buf.get(), chars, i, length); + newChars.construct<Latin1CharPtr>(buf); + } else { + TwoByteCharPtr buf = cx->make_pod_array<jschar>(length + 1); + if (!buf) + return nullptr; + + ToUpperCaseImpl(buf.get(), chars, i, length); + newChars.construct<TwoByteCharPtr>(buf); + } } - JSString *res = NewString<CanGC>(cx, newChars.get(), length); - if (!res) - return nullptr; - - newChars.forget(); + JSString *res; + if (newChars.constructed<Latin1CharPtr>()) { + res = NewStringDontDeflate<CanGC>(cx, newChars.ref<Latin1CharPtr>().get(), length); + if (!res) + return nullptr; + + newChars.ref<Latin1CharPtr>().release(); + } else { + res = NewStringDontDeflate<CanGC>(cx, newChars.ref<TwoByteCharPtr>().get(), length); + if (!res) + return nullptr; + + newChars.ref<TwoByteCharPtr>().release(); + } + return res; } static bool ToUpperCaseHelper(JSContext *cx, CallReceiver call) { RootedString str(cx, ThisToStringForStringProto(cx, call)); if (!str)
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -57,25 +57,29 @@ #include "jit/arm/Simulator-arm.h" #include "jit/Ion.h" #include "js/OldDebugAPI.h" #include "js/StructuredClone.h" #include "perf/jsperf.h" #include "shell/jsheaptools.h" #include "shell/jsoptparse.h" #include "vm/ArgumentsObject.h" +#include "vm/Debugger.h" #include "vm/HelperThreads.h" #include "vm/Monitor.h" #include "vm/Shape.h" #include "vm/TypedArrayObject.h" #include "vm/WrapperObject.h" #include "jscompartmentinlines.h" #include "jsobjinlines.h" +#include "vm/Interpreter-inl.h" +#include "vm/Stack-inl.h" + #ifdef XP_WIN # define PATH_MAX (MAX_PATH > _MAX_DIR ? MAX_PATH : _MAX_DIR) #else # include <libgen.h> #endif using namespace js; using namespace js::cli; @@ -2672,24 +2676,39 @@ EvalInFrame(JSContext *cx, unsigned argc return false; ac.construct(cx, DefaultObjectForContextOrNull(cx)); } AutoStableStringChars stableChars(cx); if (!stableChars.initTwoByte(cx, str)) return JSTRAP_ERROR; - mozilla::Range<const jschar> chars = stableChars.twoByteRange(); - JSAbstractFramePtr frame(fi.abstractFramePtr().raw(), fi.pc()); + AbstractFramePtr frame = fi.abstractFramePtr(); RootedScript fpscript(cx, frame.script()); - bool ok = !!frame.evaluateUCInStackFrame(cx, chars.start().get(), chars.length(), - fpscript->filename(), - JS_PCToLineNumber(cx, fpscript, - fi.pc()), - MutableHandleValue::fromMarkedLocation(vp)); + + RootedObject scope(cx); + { + RootedObject scopeChain(cx, frame.scopeChain()); + AutoCompartment ac(cx, scopeChain); + scope = GetDebugScopeForFrame(cx, frame, fi.pc()); + } + Rooted<Env*> env(cx, scope); + if (!env) + return false; + + if (!ComputeThis(cx, frame)) + return false; + RootedValue thisv(cx, frame.thisValue()); + + bool ok; + { + AutoCompartment ac(cx, env); + ok = EvaluateInEnv(cx, env, thisv, frame, stableChars.twoByteRange(), fpscript->filename(), + JS_PCToLineNumber(cx, fpscript, fi.pc()), args.rval()); + } return ok; } struct WorkerInput { JSRuntime *runtime; jschar *chars; size_t length;
--- a/js/src/vm/OldDebugAPI.cpp +++ b/js/src/vm/OldDebugAPI.cpp @@ -496,180 +496,8 @@ JS::FormatStackDump(JSContext *cx, char num++; } if (!num) buf = JS_sprintf_append(buf, "JavaScript stack is empty\n"); return buf; } - -JSAbstractFramePtr::JSAbstractFramePtr(void *raw, jsbytecode *pc) - : ptr_(uintptr_t(raw)), pc_(pc) -{ } - -JSObject * -JSAbstractFramePtr::scopeChain(JSContext *cx) -{ - AbstractFramePtr frame(*this); - RootedObject scopeChain(cx, frame.scopeChain()); - AutoCompartment ac(cx, scopeChain); - return GetDebugScopeForFrame(cx, frame, pc()); -} - -JSObject * -JSAbstractFramePtr::callObject(JSContext *cx) -{ - AbstractFramePtr frame(*this); - if (!frame.isFunctionFrame()) - return nullptr; - - JSObject *o = GetDebugScopeForFrame(cx, frame, pc()); - - /* - * Given that fp is a function frame and GetDebugScopeForFrame always fills - * in missing scopes, we can expect to find fp's CallObject on 'o'. Note: - * - GetDebugScopeForFrame wraps every ScopeObject (missing or not) with - * a DebugScopeObject proxy. - * - If fp is an eval-in-function, then fp has no callobj of its own and - * JS_GetFrameCallObject will return the innermost function's callobj. - */ - while (o) { - ScopeObject &scope = o->as<DebugScopeObject>().scope(); - if (scope.is<CallObject>()) - return o; - o = o->enclosingScope(); - } - return nullptr; -} - -JSFunction * -JSAbstractFramePtr::maybeFun() -{ - AbstractFramePtr frame(*this); - return frame.maybeFun(); -} - -JSScript * -JSAbstractFramePtr::script() -{ - AbstractFramePtr frame(*this); - return frame.script(); -} - -bool -JSAbstractFramePtr::getThisValue(JSContext *cx, MutableHandleValue thisv) -{ - AbstractFramePtr frame(*this); - - RootedObject scopeChain(cx, frame.scopeChain()); - js::AutoCompartment ac(cx, scopeChain); - if (!ComputeThis(cx, frame)) - return false; - - thisv.set(frame.thisValue()); - return true; -} - -bool -JSAbstractFramePtr::isDebuggerFrame() -{ - AbstractFramePtr frame(*this); - return frame.isDebuggerFrame(); -} - -bool -JSAbstractFramePtr::evaluateInStackFrame(JSContext *cx, - const char *bytes, unsigned length, - const char *filename, unsigned lineno, - MutableHandleValue rval) -{ - if (!CheckDebugMode(cx)) - return false; - - size_t len = length; - jschar *chars = InflateString(cx, bytes, &len); - if (!chars) - return false; - length = (unsigned) len; - - bool ok = evaluateUCInStackFrame(cx, chars, length, filename, lineno, rval); - js_free(chars); - - return ok; -} - -bool -JSAbstractFramePtr::evaluateUCInStackFrame(JSContext *cx, - const jschar *chars, unsigned length, - const char *filename, unsigned lineno, - MutableHandleValue rval) -{ - if (!CheckDebugMode(cx)) - return false; - - RootedObject scope(cx, scopeChain(cx)); - Rooted<Env*> env(cx, scope); - if (!env) - return false; - - AbstractFramePtr frame(*this); - if (!ComputeThis(cx, frame)) - return false; - RootedValue thisv(cx, frame.thisValue()); - - js::AutoCompartment ac(cx, env); - return EvaluateInEnv(cx, env, thisv, frame, mozilla::Range<const jschar>(chars, length), - filename, lineno, rval); -} - -JSBrokenFrameIterator::JSBrokenFrameIterator(JSContext *cx) -{ - // Show all frames on the stack whose principal is subsumed by the current principal. - NonBuiltinScriptFrameIter iter(cx, - ScriptFrameIter::ALL_CONTEXTS, - ScriptFrameIter::GO_THROUGH_SAVED, - cx->compartment()->principals); - data_ = iter.copyData(); -} - -JSBrokenFrameIterator::~JSBrokenFrameIterator() -{ - js_free((ScriptFrameIter::Data *)data_); -} - -bool -JSBrokenFrameIterator::done() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return iter.done(); -} - -JSBrokenFrameIterator & -JSBrokenFrameIterator::operator++() -{ - ScriptFrameIter::Data *data = (ScriptFrameIter::Data *)data_; - NonBuiltinScriptFrameIter iter(*data); - ++iter; - *data = iter.data_; - return *this; -} - -JSAbstractFramePtr -JSBrokenFrameIterator::abstractFramePtr() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return JSAbstractFramePtr(iter.abstractFramePtr().raw(), iter.pc()); -} - -jsbytecode * -JSBrokenFrameIterator::pc() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return iter.pc(); -} - -bool -JSBrokenFrameIterator::isConstructing() const -{ - NonBuiltinScriptFrameIter iter(*(ScriptFrameIter::Data *)data_); - return iter.isConstructing(); -}
--- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -130,21 +130,16 @@ class AbstractFramePtr } MOZ_IMPLICIT AbstractFramePtr(jit::RematerializedFrame *fp) : ptr_(fp ? uintptr_t(fp) | Tag_RematerializedFrame : 0) { MOZ_ASSERT_IF(fp, asRematerializedFrame() == fp); } - explicit AbstractFramePtr(JSAbstractFramePtr frame) - : ptr_(uintptr_t(frame.raw())) - { - } - static AbstractFramePtr FromRaw(void *raw) { AbstractFramePtr frame; frame.ptr_ = uintptr_t(raw); return frame; } bool isScriptFrameIterData() const { return !!ptr_ && (ptr_ & TagMask) == Tag_ScriptFrameIterData; @@ -1674,18 +1669,16 @@ class FrameIter jit::InlineFrameIterator ionInlineFrames_; void popActivation(); void popInterpreterFrame(); void nextJitFrame(); void popJitFrame(); void popAsmJSFrame(); void settleOnActivation(); - - friend class ::JSBrokenFrameIterator; }; class ScriptFrameIter : public FrameIter { void settle() { while (!done() && !hasScript()) FrameIter::operator++(); }
--- a/js/xpconnect/idl/nsIXPConnect.idl +++ b/js/xpconnect/idl/nsIXPConnect.idl @@ -269,17 +269,17 @@ interface nsIXPCFunctionThisTranslator : %{ C++ // For use with the service manager // {CB6593E0-F9B2-11d2-BDD6-000064657374} #define NS_XPCONNECT_CID \ { 0xcb6593e0, 0xf9b2, 0x11d2, \ { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } %} -[noscript, uuid(9ec7367c-0dde-4b7a-963c-5a590ee3ee42)] +[noscript, uuid(89b8525d-5c22-48bd-8a79-66aac9cd705e)] interface nsIXPConnect : nsISupports { %{ C++ NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCONNECT_CID) %} /** * Creates a new global object using the given aCOMObj as the global @@ -429,18 +429,16 @@ interface nsIXPConnect : nsISupports readonly attribute nsIStackFrame CurrentJSStack; readonly attribute nsAXPCNativeCallContextPtr CurrentNativeCallContext; void debugDump(in short depth); void debugDumpObject(in nsISupports aCOMObj, in short depth); void debugDumpJSStack(in boolean showArgs, in boolean showLocals, in boolean showThisProps); - void debugDumpEvalInJSStackFrame(in uint32_t aFrameNumber, - in string aSourceText); /** * wrapJSAggregatedToNative is just like wrapJS except it is used in cases * where the JSObject is also aggregated to some native xpcom Object. * At present XBL is the only system that might want to do this. * * XXX write more! *
--- a/js/xpconnect/src/XPCDebug.cpp +++ b/js/xpconnect/src/XPCDebug.cpp @@ -50,65 +50,8 @@ xpc_PrintJSStack(JSContext* cx, bool sho char *buf = JS::FormatStackDump(cx, nullptr, showArgs, showLocals, showThisProps); if (!buf) DebugDump("%s", "Failed to format JavaScript stack for dump\n"); state.restore(); return buf; } - -/***************************************************************************/ - -static void -xpcDumpEvalErrorReporter(JSContext *cx, const char *message, - JSErrorReport *report) -{ - DebugDump("Error: %s\n", message); -} - -bool -xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text) -{ - if (!cx || !text) { - DebugDump("%s", "invalid params passed to xpc_DumpEvalInJSStackFrame!\n"); - return false; - } - - DebugDump("js[%d]> %s\n", frameno, text); - - uint32_t num = 0; - - JSAbstractFramePtr frame = JSNullFramePtr(); - - JSBrokenFrameIterator iter(cx); - while (!iter.done()) { - if (num == frameno) { - frame = iter.abstractFramePtr(); - break; - } - ++iter; - num++; - } - - if (!frame) { - DebugDump("%s", "invalid frame number!\n"); - return false; - } - - JS::AutoSaveExceptionState exceptionState(cx); - JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter); - - JS::RootedValue rval(cx); - JSString* str; - JSAutoByteString bytes; - if (frame.evaluateInStackFrame(cx, text, strlen(text), "eval", 1, &rval) && - nullptr != (str = ToString(cx, rval)) && - bytes.encodeLatin1(cx, str)) { - DebugDump("%s\n", bytes.ptr()); - } else { - DebugDump("%s", "eval failed!\n"); - } - - JS_SetErrorReporter(cx, older); - exceptionState.restore(); - return true; -}
--- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -940,29 +940,16 @@ nsXPConnect::DebugPrintJSStack(bool show if (!cx) printf("there is no JSContext on the nsIThreadJSContextStack!\n"); else return xpc_PrintJSStack(cx, showArgs, showLocals, showThisProps); return nullptr; } -/* void debugDumpEvalInJSStackFrame (in uint32_t aFrameNumber, in string aSourceText); */ -NS_IMETHODIMP -nsXPConnect::DebugDumpEvalInJSStackFrame(uint32_t aFrameNumber, const char *aSourceText) -{ - JSContext* cx = GetCurrentJSContext(); - if (!cx) - printf("there is no JSContext on the nsIThreadJSContextStack!\n"); - else - xpc_DumpEvalInJSStackFrame(cx, aFrameNumber, aSourceText); - - return NS_OK; -} - /* jsval variantToJS (in JSContextPtr ctx, in JSObjectPtr scope, in nsIVariant value); */ NS_IMETHODIMP nsXPConnect::VariantToJS(JSContext* ctx, JSObject* scopeArg, nsIVariant* value, MutableHandleValue _retval) { NS_PRECONDITION(ctx, "bad param"); NS_PRECONDITION(scopeArg, "bad param"); NS_PRECONDITION(value, "bad param"); @@ -1403,26 +1390,16 @@ JS_EXPORT_API(char*) PrintJSStack() { nsresult rv; nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); return (NS_SUCCEEDED(rv) && xpc) ? xpc->DebugPrintJSStack(true, true, false) : nullptr; } -JS_EXPORT_API(void) DumpJSEval(uint32_t frameno, const char* text) -{ - nsresult rv; - nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); - if (NS_SUCCEEDED(rv) && xpc) - xpc->DebugDumpEvalInJSStackFrame(frameno, text); - else - printf("failed to get XPConnect service!\n"); -} - JS_EXPORT_API(void) DumpCompleteHeap() { nsCOMPtr<nsICycleCollectorListener> listener = do_CreateInstance("@mozilla.org/cycle-collector-logger;1"); if (!listener) { NS_WARNING("Failed to create CC logger"); return; }
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2962,20 +2962,16 @@ xpc_DumpJSStack(JSContext* cx, bool show // Return a newly-allocated string containing a representation of the // current JS stack. It is the *caller's* responsibility to free this // string with JS_smprintf_free(). extern char* xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps); -extern bool -xpc_DumpEvalInJSStackFrame(JSContext* cx, uint32_t frameno, const char* text); - - /***************************************************************************/ // Definition of nsScriptError, defined here because we lack a place to put // XPCOM objects associated with the JavaScript engine. class nsScriptError : public nsIScriptError { public: nsScriptError();
--- a/layout/reftests/reftest.list +++ b/layout/reftests/reftest.list @@ -44,17 +44,17 @@ include box-properties/reftest.list # box-shadow/ include box-shadow/reftest.list # bugs/ include bugs/reftest.list # canvas include canvas/reftest.list -skip-if(xulFennec) include ../../dom/canvas/test/reftest/reftest.list +include ../../dom/canvas/test/reftest/reftest.list # css animations include css-animations/reftest.list # blending/ include css-blending/reftest.list # Tests for the css-break spec
--- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -12240,17 +12240,18 @@ AppendGeneric(nsCSSKeyword aKeyword, Fon } return false; } bool CSSParserImpl::ParseFamily(nsCSSValue& aValue) { - nsRefPtr<FontFamilyList> familyList = new FontFamilyList(); + nsRefPtr<css::FontFamilyListRefCnt> familyList = + new css::FontFamilyListRefCnt(); nsAutoString family; bool single, quoted; // keywords only have meaning in the first position if (!ParseOneFamily(family, single, quoted)) return false; // check for keywords, but only when keywords appear by themselves
--- a/layout/style/nsCSSValue.cpp +++ b/layout/style/nsCSSValue.cpp @@ -106,17 +106,17 @@ nsCSSValue::nsCSSValue(nsCSSValueTokenSt nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue) : mUnit(eCSSUnit_GridTemplateAreas) { mValue.mGridTemplateAreas = aValue; mValue.mGridTemplateAreas->AddRef(); } -nsCSSValue::nsCSSValue(FontFamilyList* aValue) +nsCSSValue::nsCSSValue(css::FontFamilyListRefCnt* aValue) : mUnit(eCSSUnit_FontFamilyList) { mValue.mFontFamilyList = aValue; mValue.mFontFamilyList->AddRef(); } nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) : mUnit(aCopy.mUnit) @@ -486,17 +486,17 @@ void nsCSSValue::SetTokenStreamValue(nsC void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue) { Reset(); mUnit = eCSSUnit_GridTemplateAreas; mValue.mGridTemplateAreas = aValue; mValue.mGridTemplateAreas->AddRef(); } -void nsCSSValue::SetFontFamilyListValue(FontFamilyList* aValue) +void nsCSSValue::SetFontFamilyListValue(css::FontFamilyListRefCnt* aValue) { Reset(); mUnit = eCSSUnit_FontFamilyList; mValue.mFontFamilyList = aValue; mValue.mFontFamilyList->AddRef(); } void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue)
--- a/layout/style/nsCSSValue.h +++ b/layout/style/nsCSSValue.h @@ -195,16 +195,51 @@ private: { } GridTemplateAreasValue(const GridTemplateAreasValue& aOther) MOZ_DELETE; GridTemplateAreasValue& operator=(const GridTemplateAreasValue& aOther) MOZ_DELETE; }; +class FontFamilyListRefCnt MOZ_FINAL : public FontFamilyList { +public: + FontFamilyListRefCnt() + : FontFamilyList() + { + MOZ_COUNT_CTOR(FontFamilyListRefCnt); + } + + FontFamilyListRefCnt(FontFamilyType aGenericType) + : FontFamilyList(aGenericType) + { + MOZ_COUNT_CTOR(FontFamilyListRefCnt); + } + + FontFamilyListRefCnt(const nsAString& aFamilyName, + QuotedName aQuoted) + : FontFamilyList(aFamilyName, aQuoted) + { + MOZ_COUNT_CTOR(FontFamilyListRefCnt); + } + + FontFamilyListRefCnt(const FontFamilyListRefCnt& aOther) + : FontFamilyList(aOther) + { + MOZ_COUNT_CTOR(FontFamilyListRefCnt); + } + + NS_INLINE_DECL_REFCOUNTING(FontFamilyListRefCnt); + +private: + ~FontFamilyListRefCnt() { + MOZ_COUNT_DTOR(FontFamilyListRefCnt); + } +}; + } } enum nsCSSUnit { eCSSUnit_Null = 0, // (n/a) null unit, value is not specified eCSSUnit_Auto = 1, // (n/a) value is algorithmic eCSSUnit_Inherit = 2, // (n/a) value is inherited eCSSUnit_Initial = 3, // (n/a) value is default UA value @@ -366,17 +401,17 @@ public: nsCSSValue(float aValue, nsCSSUnit aUnit); nsCSSValue(const nsString& aValue, nsCSSUnit aUnit); nsCSSValue(Array* aArray, nsCSSUnit aUnit); explicit nsCSSValue(mozilla::css::URLValue* aValue); explicit nsCSSValue(mozilla::css::ImageValue* aValue); explicit nsCSSValue(nsCSSValueGradient* aValue); explicit nsCSSValue(nsCSSValueTokenStream* aValue); explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue); - explicit nsCSSValue(mozilla::FontFamilyList* aValue); + explicit nsCSSValue(mozilla::css::FontFamilyListRefCnt* aValue); nsCSSValue(const nsCSSValue& aCopy); ~nsCSSValue() { Reset(); } nsCSSValue& operator=(const nsCSSValue& aCopy); bool operator==(const nsCSSValue& aOther) const; bool operator!=(const nsCSSValue& aOther) const { @@ -634,17 +669,17 @@ public: float aComponent3, float aAlpha, nsCSSUnit aUnit); void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit); void SetURLValue(mozilla::css::URLValue* aURI); void SetImageValue(mozilla::css::ImageValue* aImage); void SetGradientValue(nsCSSValueGradient* aGradient); void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream); void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue); - void SetFontFamilyListValue(mozilla::FontFamilyList* aFontListValue); + void SetFontFamilyListValue(mozilla::css::FontFamilyListRefCnt* aFontListValue); void SetPairValue(const nsCSSValuePair* aPair); void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue); void SetSharedListValue(nsCSSValueSharedList* aList); void SetDependentListValue(nsCSSValueList* aList); void SetDependentPairListValue(nsCSSValuePairList* aList); void SetTripletValue(const nsCSSValueTriplet* aTriplet); void SetTripletValue(const nsCSSValue& xValue, const nsCSSValue& yValue, const nsCSSValue& zValue); void SetAutoValue(); @@ -702,17 +737,17 @@ protected: nsCSSRect_heap* mRect; nsCSSValueTriplet_heap* mTriplet; nsCSSValueList_heap* mList; nsCSSValueList* mListDependent; nsCSSValueSharedList* mSharedList; nsCSSValuePairList_heap* mPairList; nsCSSValuePairList* mPairListDependent; nsCSSValueFloatColor* mFloatColor; - mozilla::FontFamilyList* mFontFamilyList; + mozilla::css::FontFamilyListRefCnt* mFontFamilyList; } mValue; }; struct nsCSSValue::Array MOZ_FINAL { // return |Array| with reference count of zero static Array* Create(size_t aItemCount) { return new (aItemCount) Array(aItemCount);
--- a/layout/tools/reftest/reftest.js +++ b/layout/tools/reftest/reftest.js @@ -753,20 +753,16 @@ function BuildConditionSandbox(aURL) { sandbox.browserIsRemote = gBrowserIsRemote; try { sandbox.asyncPanZoom = prefs.getBoolPref("layers.async-pan-zoom.enabled"); } catch (e) { sandbox.asyncPanZoom = false; } - // Distinguish the Fennecs: - sandbox.xulFennec = sandbox.Android && sandbox.browserIsRemote; - sandbox.nativeFennec = sandbox.Android && !sandbox.browserIsRemote; - if (!gDumpedConditionSandbox) { dump("REFTEST INFO | Dumping JSON representation of sandbox \n"); dump("REFTEST INFO | " + JSON.stringify(sandbox) + " \n"); gDumpedConditionSandbox = true; } return sandbox; }
--- a/media/libstagefright/binding/include/mp4_demuxer/mp4_demuxer.h +++ b/media/libstagefright/binding/include/mp4_demuxer/mp4_demuxer.h @@ -62,11 +62,12 @@ public: private: AudioDecoderConfig mAudioConfig; VideoDecoderConfig mVideoConfig; CryptoFile mCrypto; nsAutoPtr<StageFrightPrivate> mPrivate; }; -} -#endif +} // namespace mozilla + +#endif // MP4_DEMUXER_H_
--- a/mfbt/RefPtr.h +++ b/mfbt/RefPtr.h @@ -387,166 +387,9 @@ template<typename T> OutParamRef<T> byRef(RefPtr<T>& aPtr) { return OutParamRef<T>(aPtr); } } // namespace mozilla -#if 0 - -// Command line that builds these tests -// -// cp RefPtr.h test.cc && g++ -g -Wall -pedantic -DDEBUG -o test test.cc && ./test - -using namespace mozilla; - -struct Foo : public RefCounted<Foo> -{ - MOZ_DECLARE_REFCOUNTED_TYPENAME(Foo) - Foo() : mDead(false) {} - ~Foo() - { - MOZ_ASSERT(!mDead); - mDead = true; - sNumDestroyed++; - } - - bool mDead; - static int sNumDestroyed; -}; -int Foo::sNumDestroyed; - -struct Bar : public Foo {}; - -TemporaryRef<Foo> -NewFoo() -{ - return RefPtr<Foo>(new Foo()); -} - -TemporaryRef<Foo> -NewBar() -{ - return new Bar(); -} - -void -GetNewFoo(Foo** f) -{ - *f = new Bar(); - // Kids, don't try this at home - (*f)->AddRef(); -} - -void -GetPassedFoo(Foo** f) -{ - // Kids, don't try this at home - (*f)->AddRef(); -} - -void -GetNewFoo(RefPtr<Foo>* f) -{ - *f = new Bar(); -} - -void -GetPassedFoo(RefPtr<Foo>* f) -{} - -TemporaryRef<Foo> -GetNullFoo() -{ - return 0; -} - -int -main(int argc, char** argv) -{ - // This should blow up -// Foo* f = new Foo(); delete f; - - MOZ_ASSERT(0 == Foo::sNumDestroyed); - { - RefPtr<Foo> f = new Foo(); - MOZ_ASSERT(f->refCount() == 1); - } - MOZ_ASSERT(1 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f1 = NewFoo(); - RefPtr<Foo> f2(NewFoo()); - MOZ_ASSERT(1 == Foo::sNumDestroyed); - } - MOZ_ASSERT(3 == Foo::sNumDestroyed); - - { - RefPtr<Foo> b = NewBar(); - MOZ_ASSERT(3 == Foo::sNumDestroyed); - } - MOZ_ASSERT(4 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f1; - { - f1 = new Foo(); - RefPtr<Foo> f2(f1); - RefPtr<Foo> f3 = f2; - MOZ_ASSERT(4 == Foo::sNumDestroyed); - } - MOZ_ASSERT(4 == Foo::sNumDestroyed); - } - MOZ_ASSERT(5 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f = new Foo(); - f.forget(); - MOZ_ASSERT(6 == Foo::sNumDestroyed); - } - - { - RefPtr<Foo> f = new Foo(); - GetNewFoo(byRef(f)); - MOZ_ASSERT(7 == Foo::sNumDestroyed); - } - MOZ_ASSERT(8 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f = new Foo(); - GetPassedFoo(byRef(f)); - MOZ_ASSERT(8 == Foo::sNumDestroyed); - } - MOZ_ASSERT(9 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f = new Foo(); - GetNewFoo(&f); - MOZ_ASSERT(10 == Foo::sNumDestroyed); - } - MOZ_ASSERT(11 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f = new Foo(); - GetPassedFoo(&f); - MOZ_ASSERT(11 == Foo::sNumDestroyed); - } - MOZ_ASSERT(12 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f1 = new Bar(); - } - MOZ_ASSERT(13 == Foo::sNumDestroyed); - - { - RefPtr<Foo> f = GetNullFoo(); - MOZ_ASSERT(13 == Foo::sNumDestroyed); - } - MOZ_ASSERT(13 == Foo::sNumDestroyed); - - return 0; -} - -#endif - #endif /* mozilla_RefPtr_h */
new file mode 100644 --- /dev/null +++ b/mfbt/tests/TestRefPtr.cpp @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/RefPtr.h" + +using mozilla::RefCounted; +using mozilla::RefPtr; +using mozilla::TemporaryRef; + +class Foo : public RefCounted<Foo> +{ +public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(Foo) + + Foo() : mDead(false) {} + + static int sNumDestroyed; + + ~Foo() + { + MOZ_ASSERT(!mDead); + mDead = true; + sNumDestroyed++; + } + +private: + bool mDead; +}; +int Foo::sNumDestroyed; + +struct Bar : public Foo {}; + +TemporaryRef<Foo> +NewFoo() +{ + return RefPtr<Foo>(new Foo()); +} + +TemporaryRef<Foo> +NewBar() +{ + return new Bar(); +} + +void +GetNewFoo(Foo** aFoo) +{ + *aFoo = new Bar(); + // Kids, don't try this at home + (*aFoo)->AddRef(); +} + +void +GetPassedFoo(Foo** aFoo) +{ + // Kids, don't try this at home + (*aFoo)->AddRef(); +} + +void +GetNewFoo(RefPtr<Foo>* aFoo) +{ + *aFoo = new Bar(); +} + +void +GetPassedFoo(RefPtr<Foo>* aFoo) +{} + +TemporaryRef<Foo> +GetNullFoo() +{ + return 0; +} + +int +main() +{ + MOZ_RELEASE_ASSERT(0 == Foo::sNumDestroyed); + { + RefPtr<Foo> f = new Foo(); + MOZ_RELEASE_ASSERT(f->refCount() == 1); + } + MOZ_RELEASE_ASSERT(1 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f1 = NewFoo(); + RefPtr<Foo> f2(NewFoo()); + MOZ_RELEASE_ASSERT(1 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(3 == Foo::sNumDestroyed); + + { + RefPtr<Foo> b = NewBar(); + MOZ_RELEASE_ASSERT(3 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(4 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f1; + { + f1 = new Foo(); + RefPtr<Foo> f2(f1); + RefPtr<Foo> f3 = f2; + MOZ_RELEASE_ASSERT(4 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(4 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(5 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f = new Foo(); + f.forget(); + MOZ_RELEASE_ASSERT(6 == Foo::sNumDestroyed); + } + + { + RefPtr<Foo> f = new Foo(); + GetNewFoo(byRef(f)); + MOZ_RELEASE_ASSERT(7 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(8 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f = new Foo(); + GetPassedFoo(byRef(f)); + MOZ_RELEASE_ASSERT(8 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(9 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f = new Foo(); + GetNewFoo(&f); + MOZ_RELEASE_ASSERT(10 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f = new Foo(); + GetPassedFoo(&f); + MOZ_RELEASE_ASSERT(11 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(12 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f1 = new Bar(); + } + MOZ_RELEASE_ASSERT(13 == Foo::sNumDestroyed); + + { + RefPtr<Foo> f = GetNullFoo(); + MOZ_RELEASE_ASSERT(13 == Foo::sNumDestroyed); + } + MOZ_RELEASE_ASSERT(13 == Foo::sNumDestroyed); + + return 0; +} +
--- a/mfbt/tests/moz.build +++ b/mfbt/tests/moz.build @@ -16,16 +16,17 @@ CPP_UNIT_TESTS += [ 'TestCountZeroes', 'TestEndian', 'TestEnumSet', 'TestFloatingPoint', 'TestIntegerPrintfMacros', 'TestMacroArgs', 'TestMacroForEach', 'TestPair', + 'TestRefPtr', 'TestRollingMean', 'TestSHA1', 'TestTypedEnum', 'TestTypeTraits', 'TestUniquePtr', 'TestWeakPtr', ]
--- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -265,16 +265,17 @@ pref("media.wave.enabled", true); #ifdef MOZ_WEBM pref("media.webm.enabled", true); #endif #ifdef MOZ_GSTREAMER pref("media.gstreamer.enabled", true); #endif #ifdef MOZ_APPLEMEDIA pref("media.apple.mp3.enabled", true); +pref("media.apple.mp4.enabled", true); #endif #ifdef MOZ_WEBRTC pref("media.navigator.enabled", true); pref("media.navigator.video.enabled", true); pref("media.navigator.load_adapt", true); pref("media.navigator.load_adapt.measure_interval",1000); pref("media.navigator.load_adapt.avg_seconds",3); pref("media.navigator.load_adapt.high_load","0.90");
--- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -853,42 +853,55 @@ class RecursiveMakeBackend(CommonBackend # registered or not. self._traversal.add(backend_file.relobjdir) affected_tiers = set(obj.affected_tiers) for tier in set(self._may_skip.keys()) - affected_tiers: self._may_skip[tier].add(backend_file.relobjdir) + def _process_hierarchy_elements(self, obj, element, namespace, action): + """Walks the ``HierarchicalStringList`` ``element`` and performs + ``action`` on each HierarchicalStringList in the hierarchy. + + ``action`` is a callback to be invoked with the following arguments: + - ``element`` - The HierarchicalStringList along the current namespace + - ``namespace`` - The namespace of the element + """ + if namespace: + namespace += '/' + + action(element, namespace) + + children = element.get_children() + for subdir in sorted(children): + self._process_hierarchy_elements(obj, children[subdir], + namespace + subdir, + action) + def _process_hierarchy(self, obj, element, namespace, action): """Walks the ``HierarchicalStringList`` ``element`` and performs - ``action`` on each string in the heirarcy. + ``action`` on each string in the hierarchy. ``action`` is a callback to be invoked with the following arguments: - ``source`` - The path to the source file named by the current string - ``dest`` - The relative path, including the namespace, of the destination file. """ - strings = element.get_strings() - if namespace: - namespace += '/' + def process_element(element, namespace): + strings = element.get_strings() + for s in strings: + source = mozpath.normpath(mozpath.join(obj.srcdir, s)) + dest = '%s%s' % (namespace, mozpath.basename(s)) + flags = None + if '__getitem__' in dir(element): + flags = element[s] + action(source, dest, flags) - for s in strings: - source = mozpath.normpath(mozpath.join(obj.srcdir, s)) - dest = '%s%s' % (namespace, mozpath.basename(s)) - flags = None - if '__getitem__' in dir(element): - flags = element[s] - action(source, dest, flags) - - children = element.get_children() - for subdir in sorted(children): - self._process_hierarchy(obj, children[subdir], - namespace=namespace + subdir, - action=action) + self._process_hierarchy_elements(obj, element, namespace, process_element) def _process_exports(self, obj, exports, backend_file): # This may not be needed, but is present for backwards compatibility # with the old make rules, just in case. if not obj.dist_install: return def handle_export(source, dest, flags): @@ -933,18 +946,44 @@ class RecursiveMakeBackend(CommonBackend backend_file.write('FINAL_TARGET = $(DEPTH)/%s\n' % (obj.target)) else: backend_file.write('FINAL_TARGET = $(if $(XPI_NAME),$(DIST)/xpi-stage/$(XPI_NAME),$(DIST)/bin)$(DIST_SUBDIR:%=/%)\n') if not obj.enabled: backend_file.write('NO_DIST_INSTALL := 1\n') def _process_javascript_modules(self, obj, backend_file): - if obj.flavor != 'testing': - raise Exception('We only support testing JavaScriptModules instances.') + if obj.flavor not in ('extra', 'extra_pp', 'testing'): + raise Exception('Unsupported JavaScriptModules instance: %s' % obj.flavor) + + if obj.flavor == 'extra': + def onelement(element, namespace): + if not element.get_strings(): + return + + prefix = 'extra_js_%s' % namespace.replace('/', '_') + backend_file.write('%s_FILES := %s\n' + % (prefix, ' '.join(element.get_strings()))) + backend_file.write('%s_DEST = $(FINAL_TARGET)/%s\n' % (prefix, namespace)) + backend_file.write('INSTALL_TARGETS += %s\n\n' % prefix) + self._process_hierarchy_elements(obj, obj.modules, 'modules', onelement) + return + + if obj.flavor == 'extra_pp': + def onelement(element, namespace): + if not element.get_strings(): + return + + prefix = 'extra_pp_js_%s' % namespace.replace('/', '_') + backend_file.write('%s := %s\n' + % (prefix, ' '.join(element.get_strings()))) + backend_file.write('%s_PATH = $(FINAL_TARGET)/%s\n' % (prefix, namespace)) + backend_file.write('PP_TARGETS += %s\n\n' % prefix) + self._process_hierarchy_elements(obj, obj.modules, 'modules', onelement) + return if not self.environment.substs.get('ENABLE_TESTS', False): return manifest = self._install_manifests['tests'] def onmodule(source, dest, flags): manifest.add_symlink(source, mozpath.join('modules', dest))
--- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -368,25 +368,22 @@ class TreeMetadataEmitter(LoggingMixin): varlist = [ 'ANDROID_GENERATED_RESFILES', 'ANDROID_RES_DIRS', 'DISABLE_STL_WRAPPING', 'EXTRA_ASSEMBLER_FLAGS', 'EXTRA_COMPILE_FLAGS', 'EXTRA_COMPONENTS', 'EXTRA_DSO_LDOPTS', - 'EXTRA_JS_MODULES', 'EXTRA_PP_COMPONENTS', - 'EXTRA_PP_JS_MODULES', 'FAIL_ON_WARNINGS', 'FILES_PER_UNIFIED_FILE', 'USE_STATIC_LIBS', 'GENERATED_FILES', 'IS_GYP_DIR', - 'JS_MODULES_PATH', 'MSVC_ENABLE_PGO', 'NO_DIST_INSTALL', 'OS_LIBS', 'PYTHON_UNIT_TESTS', 'RCFILE', 'RESFILE', 'RCINCLUDE', 'DEFFILE', @@ -502,16 +499,24 @@ class TreeMetadataEmitter(LoggingMixin): 'because it is already used in %s' % (program, kind, self._binaries[program].relativedir), sandbox) self._binaries[program] = cls(sandbox, program, is_unit_test=kind == 'CPP_UNIT_TESTS') self._linkage.append((sandbox, self._binaries[program], 'HOST_USE_LIBS' if kind == 'HOST_SIMPLE_PROGRAMS' else 'USE_LIBS')) + extra_js_modules = sandbox.get('EXTRA_JS_MODULES') + if extra_js_modules: + yield JavaScriptModules(sandbox, extra_js_modules, 'extra') + + extra_pp_js_modules = sandbox.get('EXTRA_PP_JS_MODULES') + if extra_pp_js_modules: + yield JavaScriptModules(sandbox, extra_pp_js_modules, 'extra_pp') + test_js_modules = sandbox.get('TESTING_JS_MODULES') if test_js_modules: yield JavaScriptModules(sandbox, test_js_modules, 'testing') simple_lists = [ ('GENERATED_EVENTS_WEBIDL_FILES', GeneratedEventWebIDLFile), ('GENERATED_WEBIDL_FILES', GeneratedWebIDLFile), ('IPDL_SOURCES', IPDLFile),
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py +++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py @@ -181,30 +181,28 @@ VARIABLES = { 'EXTRA_COMPONENTS': (StrictOrderingOnAppendList, list, """Additional component files to distribute. This variable contains a list of files to copy into ``$(FINAL_TARGET)/components/``. """, 'libs'), - 'EXTRA_JS_MODULES': (StrictOrderingOnAppendList, list, + 'EXTRA_JS_MODULES': (HierarchicalStringList, list, """Additional JavaScript files to distribute. This variable contains a list of files to copy into - ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``. ``JS_MODULES_PATH`` defaults - to ``modules`` if left undefined. + ``$(FINAL_TARGET)/modules. """, 'libs'), - 'EXTRA_PP_JS_MODULES': (StrictOrderingOnAppendList, list, + 'EXTRA_PP_JS_MODULES': (HierarchicalStringList, list, """Additional JavaScript files to distribute. This variable contains a list of files to copy into - ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``, after preprocessing. - ``JS_MODULES_PATH`` defaults to ``modules`` if left undefined. + ``$(FINAL_TARGET)/modules``, after preprocessing. """, 'libs'), 'TESTING_JS_MODULES': (HierarchicalStringList, list, """JavaScript modules to install in the test-only destination. Some JavaScript modules (JSMs) are test-only and not distributed with Firefox. This variable defines them. @@ -287,26 +285,16 @@ VARIABLES = { 'JAVA_JAR_TARGETS': (dict, dict, """Defines Java JAR targets to be built. This variable should not be populated directly. Instead, it should populated by calling add_java_jar(). """, 'libs'), - 'JS_MODULES_PATH': (unicode, unicode, - """Sub-directory of ``$(FINAL_TARGET)`` to install - ``EXTRA_JS_MODULES``. - - ``EXTRA_JS_MODULES`` files are copied to - ``$(FINAL_TARGET)/$(JS_MODULES_PATH)``. This variable does not - need to be defined if the desired destination directory is - ``$(FINAL_TARGET)/modules``. - """, None), - 'LIBRARY_NAME': (unicode, unicode, """The code name of the library generated for a directory. By default STATIC_LIBRARY_NAME and SHARED_LIBRARY_NAME take this name. In ``example/components/moz.build``,:: LIBRARY_NAME = 'xpcomsample'
--- a/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build +++ b/python/mozbuild/mozbuild/test/backend/data/variable_passthru/moz.build @@ -2,19 +2,16 @@ # Any copyright is dedicated to the Public Domain. # http://creativecommons.org/publicdomain/zero/1.0/ SOURCES += ['bar.s', 'foo.asm'] EXTRA_COMPONENTS = ['bar.js', 'foo.js'] EXTRA_PP_COMPONENTS = ['bar.pp.js', 'foo.pp.js'] -EXTRA_JS_MODULES = ['bar.jsm', 'foo.jsm'] -EXTRA_PP_JS_MODULES = ['bar.pp.jsm', 'foo.pp.jsm'] - HOST_SOURCES += ['bar.cpp', 'foo.cpp'] HOST_SOURCES += ['bar.c', 'foo.c'] OS_LIBS = ['foo.so', '-l123', 'bar.a'] SOURCES += ['bar.c', 'foo.c'] SOURCES += ['bar.mm', 'foo.mm']
--- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -271,24 +271,16 @@ class TestRecursiveMakeBackend(BackendTe 'EXTRA_COMPONENTS': [ 'EXTRA_COMPONENTS += bar.js', 'EXTRA_COMPONENTS += foo.js', ], 'EXTRA_PP_COMPONENTS': [ 'EXTRA_PP_COMPONENTS += bar.pp.js', 'EXTRA_PP_COMPONENTS += foo.pp.js', ], - 'EXTRA_JS_MODULES': [ - 'EXTRA_JS_MODULES += bar.jsm', - 'EXTRA_JS_MODULES += foo.jsm', - ], - 'EXTRA_PP_JS_MODULES': [ - 'EXTRA_PP_JS_MODULES += bar.pp.jsm', - 'EXTRA_PP_JS_MODULES += foo.pp.jsm', - ], 'FAIL_ON_WARNINGS': [ 'FAIL_ON_WARNINGS := 1', ], 'HOST_CPPSRCS': [ 'HOST_CPPSRCS += bar.cpp', 'HOST_CPPSRCS += foo.cpp', ], 'HOST_CSRCS': [
--- a/python/mozbuild/mozbuild/test/frontend/data/variable-passthru/moz.build +++ b/python/mozbuild/mozbuild/test/frontend/data/variable-passthru/moz.build @@ -2,19 +2,16 @@ # Any copyright is dedicated to the Public Domain. # http://creativecommons.org/publicdomain/zero/1.0/ SOURCES += ['fans.asm', 'tans.s'] EXTRA_COMPONENTS=['fans.js', 'tans.js'] EXTRA_PP_COMPONENTS=['fans.pp.js', 'tans.pp.js'] -EXTRA_JS_MODULES = ['bar.jsm', 'foo.jsm'] -EXTRA_PP_JS_MODULES = ['bar.pp.jsm', 'foo.pp.jsm'] - HOST_SOURCES += ['fans.cpp', 'tans.cpp'] HOST_SOURCES += ['fans.c', 'tans.c'] OS_LIBS += ['foo.so', '-l123', 'aaa.a'] SOURCES += ['fans.c', 'tans.c'] SOURCES += ['fans.mm', 'tans.mm']
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py +++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py @@ -149,18 +149,16 @@ class TestEmitterBasic(unittest.TestCase wanted = dict( ASFILES=['fans.asm', 'tans.s'], CMMSRCS=['fans.mm', 'tans.mm'], CSRCS=['fans.c', 'tans.c'], DISABLE_STL_WRAPPING=True, EXTRA_COMPONENTS=['fans.js', 'tans.js'], EXTRA_PP_COMPONENTS=['fans.pp.js', 'tans.pp.js'], - EXTRA_JS_MODULES=['bar.jsm', 'foo.jsm'], - EXTRA_PP_JS_MODULES=['bar.pp.jsm', 'foo.pp.jsm'], FAIL_ON_WARNINGS=True, HOST_CPPSRCS=['fans.cpp', 'tans.cpp'], HOST_CSRCS=['fans.c', 'tans.c'], MSVC_ENABLE_PGO=True, NO_DIST_INSTALL=True, OS_LIBS=['foo.so', '-l123', 'aaa.a'], SSRCS=['bans.S', 'fans.S'], VISIBILITY_FLAGS='',
--- a/python/mozbuild/mozbuild/util.py +++ b/python/mozbuild/mozbuild/util.py @@ -431,37 +431,46 @@ class HierarchicalStringList(object): # EXPORTS.foo = ['file.h'] # # In this case, we need to overwrite foo's current list of strings. # # However, __setattr__ is also called with a HierarchicalStringList # to try to actually set the attribute. We want to ignore this case, # since we don't actually create an attribute called 'foo', but just add # it to our list of children (using _get_exportvariable()). - exports = self._get_exportvariable(name) - if not isinstance(value, HierarchicalStringList): - exports._check_list(value) - exports._strings = value + self._set_exportvariable(name, value) def __getattr__(self, name): if name.startswith('__'): return object.__getattr__(self, name) return self._get_exportvariable(name) def __delattr__(self, name): raise MozbuildDeletionError('Unable to delete attributes for this object') def __iadd__(self, other): self._check_list(other) self._strings += other return self + def __getitem__(self, name): + return self._get_exportvariable(name) + + def __setitem__(self, name, value): + self._set_exportvariable(name, value) + def _get_exportvariable(self, name): return self._children.setdefault(name, HierarchicalStringList()) + def _set_exportvariable(self, name, value): + exports = self._get_exportvariable(name) + if not isinstance(value, HierarchicalStringList): + exports._check_list(value) + exports._strings = value + def _check_list(self, value): if not isinstance(value, list): raise ValueError('Expected a list of strings, not %s' % type(value)) for v in value: if not isinstance(v, str_type): raise ValueError( 'Expected a list of strings, not an element of %s' % type(v))
--- a/security/sandbox/linux/Sandbox.cpp +++ b/security/sandbox/linux/Sandbox.cpp @@ -14,17 +14,16 @@ #include <signal.h> #include <string.h> #include <linux/futex.h> #include <sys/time.h> #include <dirent.h> #include <stdlib.h> #include <pthread.h> #include <errno.h> -#include <fcntl.h> #include "mozilla/Atomics.h" #include "mozilla/NullPtr.h" #include "mozilla/unused.h" #include "mozilla/dom/Exceptions.h" #include "nsString.h" #include "nsThreadUtils.h" @@ -32,18 +31,20 @@ #include "nsExceptionHandler.h" #endif #if defined(ANDROID) #include "android_ucontext.h" #include <android/log.h> #endif +#if defined(MOZ_CONTENT_SANDBOX) #include "linux_seccomp.h" #include "SandboxFilter.h" +#endif #ifdef MOZ_LOGGING #define FORCE_PR_LOG 1 #endif #include "prlog.h" #include "prenv.h" // See definition of SandboxDie, below. @@ -54,24 +55,16 @@ namespace mozilla { #define LOG_ERROR(args...) __android_log_print(ANDROID_LOG_ERROR, "Sandbox", ## args) #elif defined(PR_LOGGING) static PRLogModuleInfo* gSeccompSandboxLog; #define LOG_ERROR(args...) PR_LOG(mozilla::gSeccompSandboxLog, PR_LOG_ERROR, (args)) #else #define LOG_ERROR(args...) #endif -#ifdef MOZ_GMP_SANDBOX -// For media plugins, we can start the sandbox before we dlopen the -// module, so we have to pre-open the file and simulate the sandboxed -// open(). -static int gMediaPluginFileDesc = -1; -static nsCString gMediaPluginFilePath; -#endif - /** * Log JS stack info in the same place as the sandbox violation * message. Useful in case the responsible code is JS and all we have * are logs and a minidump with the C++ stacks (e.g., on TBPL). */ static void SandboxLogJSStack(void) { @@ -139,37 +132,16 @@ Reporter(int nr, siginfo_t *info, void * syscall_nr = SECCOMP_SYSCALL(ctx); args[0] = SECCOMP_PARM1(ctx); args[1] = SECCOMP_PARM2(ctx); args[2] = SECCOMP_PARM3(ctx); args[3] = SECCOMP_PARM4(ctx); args[4] = SECCOMP_PARM5(ctx); args[5] = SECCOMP_PARM6(ctx); -#ifdef MOZ_GMP_SANDBOX - if (syscall_nr == __NR_open && !gMediaPluginFilePath.IsEmpty()) { - const char *path = reinterpret_cast<const char*>(args[0]); - int flags = int(args[1]); - - if ((flags & O_ACCMODE) != O_RDONLY) { - LOG_ERROR("non-read-only open of file %s attempted (flags=0%o)", - path, flags); - } else if (strcmp(path, gMediaPluginFilePath.get()) != 0) { - LOG_ERROR("attempt to open file %s which is not the media plugin %s", - path, gMediaPluginFilePath.get()); - } else if (gMediaPluginFileDesc == -1) { - LOG_ERROR("multiple opens of media plugin file unimplemented"); - } else { - SECCOMP_RESULT(ctx) = gMediaPluginFileDesc; - gMediaPluginFileDesc = -1; - return; - } - } -#endif - LOG_ERROR("seccomp sandbox violation: pid %d, syscall %lu, args %lu %lu %lu" " %lu %lu %lu. Killing process.", pid, syscall_nr, args[0], args[1], args[2], args[3], args[4], args[5]); #ifdef MOZ_CRASHREPORTER // Bug 1017393: record syscall number somewhere useful. info->si_addr = reinterpret_cast<void*>(syscall_nr); bool dumped = CrashReporter::WriteMinidumpForSigInfo(nr, info, void_context); @@ -277,17 +249,18 @@ FindFreeSignalNumber() return 0; } static bool SetThreadSandbox() { bool didAnything = false; - if (prctl(PR_GET_SECCOMP, 0, 0, 0, 0) == 0) { + if (PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX") == nullptr && + prctl(PR_GET_SECCOMP, 0, 0, 0, 0) == 0) { if (InstallSyscallFilter(sSetSandboxFilter) == 0) { didAnything = true; } /* * Bug 880797: when all B2G devices are required to support * seccomp-bpf, this should exit/crash if InstallSyscallFilter * returns nonzero (ifdef MOZ_WIDGET_GONK). */ @@ -307,29 +280,29 @@ SetThreadSandboxHandler(int signum) } // Wake up the main thread. See the FUTEX_WAIT call, below, for an // explanation. syscall(__NR_futex, reinterpret_cast<int*>(&sSetSandboxDone), FUTEX_WAKE, 1); } static void -BroadcastSetThreadSandbox(SandboxType aType) +BroadcastSetThreadSandbox() { int signum; - pid_t pid, tid, myTid; + pid_t pid, tid; DIR *taskdp; struct dirent *de; - SandboxFilter filter(&sSetSandboxFilter, aType, - PR_GetEnv("MOZ_SANDBOX_VERBOSE")); + SandboxFilter filter(&sSetSandboxFilter, + PR_GetEnv("MOZ_CONTENT_SANDBOX_VERBOSE")); static_assert(sizeof(mozilla::Atomic<int>) == sizeof(int), "mozilla::Atomic<int> isn't represented by an int"); + MOZ_ASSERT(NS_IsMainThread()); pid = getpid(); - myTid = syscall(__NR_gettid); taskdp = opendir("/proc/self/task"); if (taskdp == nullptr) { LOG_ERROR("opendir /proc/self/task: %s\n", strerror(errno)); MOZ_CRASH(); } signum = FindFreeSignalNumber(); if (signum == 0) { LOG_ERROR("No available signal numbers!"); @@ -352,19 +325,19 @@ BroadcastSetThreadSandbox(SandboxType aT // For each thread... while ((de = readdir(taskdp))) { char *endptr; tid = strtol(de->d_name, &endptr, 10); if (*endptr != '\0' || tid <= 0) { // Not a task ID. continue; } - if (tid == myTid) { - // Drop this thread's privileges last, below, so we can - // continue to signal other threads. + if (tid == pid) { + // Drop the main thread's privileges last, below, so + // we can continue to signal other threads. continue; } // Reset the futex cell and signal. sSetSandboxDone = 0; if (syscall(__NR_tgkill, pid, tid, signum) != 0) { if (errno == ESRCH) { LOG_ERROR("Thread %d unexpectedly exited.", tid); // Rescan threads, in case it forked before exiting. @@ -447,86 +420,41 @@ BroadcastSetThreadSandbox(SandboxType aT // This function can overapproximate (i.e., return true even if // sandboxing isn't supported, but not the reverse). See bug 993145. static bool IsSandboxingSupported(void) { return prctl(PR_GET_SECCOMP) != -1; } -// Common code for sandbox startup. -static void -SetCurrentProcessSandbox(SandboxType aType) +/** + * Starts the seccomp sandbox for this process and sets user/group-based privileges. + * Should be called only once, and before any potentially harmful content is loaded. + * + * Should normally make the process exit on failure. +*/ +void +SetCurrentProcessSandbox() { #if !defined(ANDROID) && defined(PR_LOGGING) if (!gSeccompSandboxLog) { gSeccompSandboxLog = PR_NewLogModule("SeccompSandbox"); } PR_ASSERT(gSeccompSandboxLog); #endif if (InstallSyscallReporter()) { LOG_ERROR("install_syscall_reporter() failed\n"); } if (IsSandboxingSupported()) { - BroadcastSetThreadSandbox(aType); + BroadcastSetThreadSandbox(); } } -#ifdef MOZ_CONTENT_SANDBOX -/** - * Starts the seccomp sandbox for a content process. Should be called - * only once, and before any potentially harmful content is loaded. - * - * Will normally make the process exit on failure. -*/ -void -SetContentProcessSandbox() -{ - if (PR_GetEnv("MOZ_DISABLE_CONTENT_SANDBOX")) { - return; - } - - SetCurrentProcessSandbox(kSandboxContentProcess); -} -#endif // MOZ_CONTENT_SANDBOX - -#ifdef MOZ_GMP_SANDBOX -/** - * Starts the seccomp sandbox for a media plugin process. Should be - * called only once, and before any potentially harmful content is - * loaded -- including the plugin itself, if it's considered untrusted. - * - * The file indicated by aFilePath, if non-null, can be open()ed once - * read-only after the sandbox starts; it should be the .so file - * implementing the not-yet-loaded plugin. - * - * Will normally make the process exit on failure. -*/ -void -SetMediaPluginSandbox(const char *aFilePath) -{ - if (PR_GetEnv("MOZ_DISABLE_GMP_SANDBOX")) { - return; - } - - if (aFilePath) { - gMediaPluginFilePath.Assign(aFilePath); - gMediaPluginFileDesc = open(aFilePath, O_RDONLY | O_CLOEXEC); - if (gMediaPluginFileDesc == -1) { - LOG_ERROR("failed to open plugin file %s: %s", aFilePath, strerror(errno)); - MOZ_CRASH(); - } - } - // Finally, start the sandbox. - SetCurrentProcessSandbox(kSandboxMediaPlugin); -} -#endif // MOZ_GMP_SANDBOX - } // namespace mozilla // "Polyfill" for sandbox::Die, the real version of which requires // Chromium's logging code. namespace sandbox { void
--- a/security/sandbox/linux/Sandbox.h +++ b/security/sandbox/linux/Sandbox.h @@ -4,19 +4,14 @@ * 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_Sandbox_h #define mozilla_Sandbox_h namespace mozilla { -#ifdef MOZ_CONTENT_SANDBOX -void SetContentProcessSandbox(); -#endif -#ifdef MOZ_GMP_SANDBOX -void SetMediaPluginSandbox(const char *aFilePath); -#endif +void SetCurrentProcessSandbox(); } // namespace mozilla #endif // mozilla_Sandbox_h
--- a/security/sandbox/linux/SandboxFilter.cpp +++ b/security/sandbox/linux/SandboxFilter.cpp @@ -9,82 +9,97 @@ #include "linux_seccomp.h" #include "linux_syscalls.h" #include "mozilla/ArrayUtils.h" #include "mozilla/NullPtr.h" #include <errno.h> -#include <linux/ipc.h> +#include <unistd.h> #include <linux/net.h> -#include <linux/prctl.h> -#include <linux/sched.h> -#include <sys/mman.h> -#include <time.h> -#include <unistd.h> +#include <linux/ipc.h> namespace mozilla { class SandboxFilterImpl : public SandboxAssembler { + void Build(); public: - virtual void Build() = 0; - virtual ~SandboxFilterImpl() { } + SandboxFilterImpl() { + Build(); + Finish(); + } }; -// Some helper macros to make the code that builds the filter more -// readable, and to help deal with differences among architectures. +SandboxFilter::SandboxFilter(const sock_fprog** aStored, bool aVerbose) + : mStored(aStored) +{ + MOZ_ASSERT(*mStored == nullptr); + std::vector<struct sock_filter> filterVec; + { + SandboxFilterImpl impl; + impl.Compile(&filterVec, aVerbose); + } + mProg = new sock_fprog; + mProg->len = filterVec.size(); + mProg->filter = mFilter = new sock_filter[mProg->len]; + for (size_t i = 0; i < mProg->len; ++i) { + mFilter[i] = filterVec[i]; + } + *mStored = mProg; +} +SandboxFilter::~SandboxFilter() +{ + *mStored = nullptr; + delete[] mFilter; + delete mProg; +} + +void +SandboxFilterImpl::Build() { #define SYSCALL_EXISTS(name) (defined(__NR_##name)) #define SYSCALL(name) (Condition(__NR_##name)) #if defined(__arm__) && (defined(__thumb__) || defined(__ARM_EABI__)) #define ARM_SYSCALL(name) (Condition(__ARM_NR_##name)) #endif #define SYSCALL_WITH_ARG(name, arg, values...) ({ \ uint32_t argValues[] = { values }; \ Condition(__NR_##name, arg, argValues); \ }) -// Some architectures went through a transition from 32-bit to -// 64-bit off_t and had to version all the syscalls that referenced -// it; others (newer and/or 64-bit ones) didn't. Adjust the -// conditional as needed. + // Some architectures went through a transition from 32-bit to + // 64-bit off_t and had to version all the syscalls that referenced + // it; others (newer and/or 64-bit ones) didn't. Adjust the + // conditional as needed. #if SYSCALL_EXISTS(stat64) #define SYSCALL_LARGEFILE(plain, versioned) SYSCALL(versioned) #else #define SYSCALL_LARGEFILE(plain, versioned) SYSCALL(plain) #endif -// i386 multiplexes all the socket-related interfaces into a single -// syscall. + // i386 multiplexes all the socket-related interfaces into a single + // syscall. #if SYSCALL_EXISTS(socketcall) #define SOCKETCALL(name, NAME) SYSCALL_WITH_ARG(socketcall, 0, SYS_##NAME) #else #define SOCKETCALL(name, NAME) SYSCALL(name) #endif -// i386 multiplexes all the SysV-IPC-related interfaces into a single -// syscall. + // i386 multiplexes all the SysV-IPC-related interfaces into a single + // syscall. #if SYSCALL_EXISTS(ipc) #define SYSVIPCCALL(name, NAME) SYSCALL_WITH_ARG(ipc, 0, NAME) #else #define SYSVIPCCALL(name, NAME) SYSCALL(name) #endif -#ifdef MOZ_CONTENT_SANDBOX -class SandboxFilterImplContent : public SandboxFilterImpl { -protected: - virtual void Build() MOZ_OVERRIDE; -}; - -void -SandboxFilterImplContent::Build() { /* Most used system calls should be at the top of the whitelist * for performance reasons. The whitelist BPF filter exits after * processing any ALLOW_SYSCALL macro. * * How are those syscalls found? * 1) via strace -p <child pid> or/and * 2) the child will report which system call has been denied by seccomp-bpf, * just before exiting, via NSPR or Android logging. @@ -305,155 +320,10 @@ SandboxFilterImplContent::Build() { #endif /* nsSystemInfo uses uname (and we cache an instance, so */ /* the info remains present even if we block the syscall) */ Allow(SYSCALL(uname)); Allow(SYSCALL(exit_group)); Allow(SYSCALL(exit)); } -#endif // MOZ_CONTENT_SANDBOX - -#ifdef MOZ_GMP_SANDBOX -class SandboxFilterImplGMP : public SandboxFilterImpl { -protected: - virtual void Build() MOZ_OVERRIDE; -}; - -void SandboxFilterImplGMP::Build() { - // As for content processes, check the most common syscalls first. - - Allow(SYSCALL_WITH_ARG(clock_gettime, 0, CLOCK_MONOTONIC, CLOCK_REALTIME)); - Allow(SYSCALL(futex)); - Allow(SYSCALL(gettimeofday)); - Allow(SYSCALL(poll)); - Allow(SYSCALL(write)); - Allow(SYSCALL(read)); - Allow(SYSCALL(epoll_wait)); - Allow(SOCKETCALL(recvmsg, RECVMSG)); - Allow(SOCKETCALL(sendmsg, SENDMSG)); - Allow(SYSCALL(time)); - - // Nothing after this line is performance-critical. - -#if SYSCALL_EXISTS(mmap2) - Allow(SYSCALL(mmap2)); -#else - Allow(SYSCALL(mmap)); -#endif - Allow(SYSCALL_LARGEFILE(fstat, fstat64)); - Allow(SYSCALL(munmap)); - - Allow(SYSCALL(gettid)); - - // The glibc source hasn't changed the thread creation clone flags - // since 2004, so this *should* be safe to hard-code. Bionic is - // different, but MOZ_GMP_SANDBOX isn't supported there yet. - // - // At minimum we should require CLONE_THREAD, so that a single - // SIGKILL from the parent will destroy all descendant tasks. In - // general, pinning down as much of the flags word as possible is a - // good idea, because it exposes a lot of subtle (and probably not - // well tested in all cases) kernel functionality. - // - // WARNING: s390 and cris pass the flags in a different arg -- see - // CLONE_BACKWARDS2 in arch/Kconfig in the kernel source -- but we - // don't support seccomp-bpf on those archs yet. - static const int new_thread_flags = CLONE_VM | CLONE_FS | CLONE_FILES | - CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | - CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; - Allow(SYSCALL_WITH_ARG(clone, 0, new_thread_flags)); - - Allow(SYSCALL_WITH_ARG(prctl, 0, PR_GET_SECCOMP, PR_SET_NAME)); - -#if SYSCALL_EXISTS(set_robust_list) - Allow(SYSCALL(set_robust_list)); -#endif - - // NSPR can call this when creating a thread, but it will accept a - // polite "no". - Deny(EACCES, SYSCALL(getpriority)); - - Allow(SYSCALL(mprotect)); - Allow(SYSCALL_WITH_ARG(madvise, 2, MADV_DONTNEED)); - -#if SYSCALL_EXISTS(sigreturn) - Allow(SYSCALL(sigreturn)); -#endif - Allow(SYSCALL(rt_sigreturn)); - - Allow(SYSCALL(restart_syscall)); - Allow(SYSCALL(close)); - - // "Sleeping for 300 seconds" in debug crashes; possibly other uses. - Allow(SYSCALL(nanosleep)); - - // For the crash reporter: -#if SYSCALL_EXISTS(sigprocmask) - Allow(SYSCALL(sigprocmask)); -#endif - Allow(SYSCALL(rt_sigprocmask)); -#if SYSCALL_EXISTS(sigaction) - Allow(SYSCALL(sigaction)); -#endif - Allow(SYSCALL(rt_sigaction)); - Allow(SOCKETCALL(socketpair, SOCKETPAIR)); - Allow(SYSCALL_WITH_ARG(tgkill, 0, uint32_t(getpid()))); - Allow(SYSCALL_WITH_ARG(prctl, 0, PR_SET_DUMPABLE)); - - // Note for when GMP is supported on an ARM platform: Add whichever - // of the ARM-specific syscalls are needed for this type of process. - - Allow(SYSCALL(epoll_ctl)); - Allow(SYSCALL(exit)); - Allow(SYSCALL(exit_group)); -} -#endif // MOZ_GMP_SANDBOX - -SandboxFilter::SandboxFilter(const sock_fprog** aStored, SandboxType aType, - bool aVerbose) - : mStored(aStored) -{ - MOZ_ASSERT(*mStored == nullptr); - std::vector<struct sock_filter> filterVec; - SandboxFilterImpl *impl; - - switch (aType) { - case kSandboxContentProcess: -#ifdef MOZ_CONTENT_SANDBOX - impl = new SandboxFilterImplContent(); -#else - MOZ_CRASH("Content process sandboxing not supported in this build!"); -#endif - break; - case kSandboxMediaPlugin: -#ifdef MOZ_GMP_SANDBOX - impl = new SandboxFilterImplGMP(); -#else - MOZ_CRASH("Gecko Media Plugin process sandboxing not supported in this" - " build!"); -#endif - break; - default: - MOZ_CRASH("Nonexistent sandbox type!"); - } - impl->Build(); - impl->Finish(); - impl->Compile(&filterVec, aVerbose); - delete impl; - - mProg = new sock_fprog; - mProg->len = filterVec.size(); - mProg->filter = mFilter = new sock_filter[mProg->len]; - for (size_t i = 0; i < mProg->len; ++i) { - mFilter[i] = filterVec[i]; - } - *mStored = mProg; -} - -SandboxFilter::~SandboxFilter() -{ - *mStored = nullptr; - delete[] mFilter; - delete mProg; -} }
--- a/security/sandbox/linux/SandboxFilter.h +++ b/security/sandbox/linux/SandboxFilter.h @@ -6,30 +6,22 @@ #ifndef mozilla_SandboxFilter_h #define mozilla_SandboxFilter_h struct sock_fprog; struct sock_filter; namespace mozilla { - -enum SandboxType { - kSandboxContentProcess, - kSandboxMediaPlugin -}; - -class SandboxFilter { - sock_filter *mFilter; - sock_fprog *mProg; - const sock_fprog **mStored; -public: + class SandboxFilter { + sock_filter *mFilter; + sock_fprog *mProg; + const sock_fprog **mStored; + public: // RAII: on construction, builds the filter and stores it in the // provided variable (with optional logging); on destruction, frees // the filter and nulls out the pointer. - SandboxFilter(const sock_fprog** aStored, SandboxType aBox, - bool aVerbose = false); - ~SandboxFilter(); -}; - -} // namespace mozilla + SandboxFilter(const sock_fprog** aStored, bool aVerbose = false); + ~SandboxFilter(); + }; +} #endif
--- a/services/metrics/moz.build +++ b/services/metrics/moz.build @@ -1,19 +1,17 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TEST_DIRS += ['tests'] -EXTRA_PP_JS_MODULES += [ +EXTRA_PP_JS_MODULES.services.metrics += [ 'dataprovider.jsm', 'providermanager.jsm', 'storage.jsm', ] -JS_MODULES_PATH = 'modules/services/metrics' - TESTING_JS_MODULES.services.metrics += [ 'modules-testing/mocks.jsm', ]
--- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -203,21 +203,16 @@ class MessageLogger(object): # Cleaning the list of buffered messages self.buffered_messages = [] def finish(self): self.dump_buffered() self.buffering = False self.logger.suite_end() -# Global logger -log = StructuredLogger('mochitest') -stream_handler = StreamHandler(stream=sys.stdout, formatter=MochitestFormatter()) -log.add_handler(stream_handler) - #################### # PROCESS HANDLING # #################### def call(*args, **kwargs): """front-end function to mozprocess.ProcessHandler""" # TODO: upstream -> mozprocess # https://bugzilla.mozilla.org/show_bug.cgi?id=791383 @@ -989,18 +984,23 @@ class Mochitest(MochitestUtilsMixin): # XXX use automation.py for test name to avoid breaking legacy # TODO: replace this with 'runtests.py' or 'mochitest' or the like test_name = 'automation.py' def __init__(self): super(Mochitest, self).__init__() + # Structured logger + structured_log = StructuredLogger('mochitest') + stream_handler = StreamHandler(stream=sys.stdout, formatter=MochitestFormatter()) + structured_log.add_handler(stream_handler) + # Structured logs parser - self.message_logger = MessageLogger(logger=log) + self.message_logger = MessageLogger(logger=structured_log) # environment function for browserEnv self.environment = environment # Max time in seconds to wait for server startup before tests will fail -- if # this seems big, it's mostly for debug machines where cold startup # (particularly after a build) takes forever. self.SERVER_STARTUP_TIMEOUT = 180 if mozinfo.info.get('debug') else 90
--- a/testing/specialpowers/content/specialpowersAPI.js +++ b/testing/specialpowers/content/specialpowersAPI.js @@ -764,17 +764,20 @@ SpecialPowersAPI.prototype = { } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_SESSION, context)) { originalValue = Ci.nsICookiePermission.ACCESS_SESSION; } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY, context)) { originalValue = Ci.nsICookiePermission.ACCESS_ALLOW_FIRST_PARTY_ONLY; } else if (this.testPermission(permission.type, Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY, context)) { originalValue = Ci.nsICookiePermission.ACCESS_LIMIT_THIRD_PARTY; } - let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(context); + let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(context); + if (isSystem) { + continue; + } let perm; if (typeof permission.allow !== 'boolean') { perm = permission.allow; } else { perm = permission.allow ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION; } @@ -1667,16 +1670,17 @@ SpecialPowersAPI.prototype = { removeFullscreenAllowed: function(document) { Services.perms.removeFromPrincipal(document.nodePrincipal, "fullscreen"); }, _getInfoFromPermissionArg: function(arg) { let url = ""; let appId = Ci.nsIScriptSecurityManager.NO_APP_ID; let isInBrowserElement = false; + let isSystem = false; if (typeof(arg) == "string") { // It's an URL. url = Cc["@mozilla.org/network/io-service;1"] .getService(Ci.nsIIOService) .newURI(arg, null, null) .spec; } else if (arg.manifestURL) { @@ -1689,30 +1693,42 @@ SpecialPowersAPI.prototype = { throw "No app for this manifest!"; } appId = appsSvc.getAppLocalIdByManifestURL(arg.manifestURL); url = app.origin; isInBrowserElement = arg.isInBrowserElement || false; } else if (arg.nodePrincipal) { // It's a document. - url = arg.nodePrincipal.URI.spec; - appId = arg.nodePrincipal.appId; - isInBrowserElement = arg.nodePrincipal.isInBrowserElement; + isSystem = (arg.nodePrincipal instanceof Ci.nsIPrincipal) && + Cc["@mozilla.org/scriptsecuritymanager;1"]. + getService(Ci.nsIScriptSecurityManager). + isSystemPrincipal(arg.nodePrincipal); + if (!isSystem) { + // System principals don't have a URL associated with them, and they + // don't really need any permissions to be registered with the + // permission manager anyway. + url = arg.nodePrincipal.URI.spec; + appId = arg.nodePrincipal.appId; + isInBrowserElement = arg.nodePrincipal.isInBrowserElement; + } } else { url = arg.url; appId = arg.appId; isInBrowserElement = arg.isInBrowserElement; } - return [ url, appId, isInBrowserElement ]; + return [ url, appId, isInBrowserElement, isSystem ]; }, addPermission: function(type, allow, arg) { - let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg); + let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg); + if (isSystem) { + return; // nothing to do + } let permission; if (typeof allow !== 'boolean') { permission = allow; } else { permission = allow ? Ci.nsIPermissionManager.ALLOW_ACTION : Ci.nsIPermissionManager.DENY_ACTION; } @@ -1725,44 +1741,53 @@ SpecialPowersAPI.prototype = { 'appId': appId, 'isInBrowserElement': isInBrowserElement }; this._sendSyncMessage('SPPermissionManager', msg); }, removePermission: function(type, arg) { - let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg); + let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg); + if (isSystem) { + return; // nothing to do + } var msg = { 'op': 'remove', 'type': type, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement }; this._sendSyncMessage('SPPermissionManager', msg); }, hasPermission: function (type, arg) { - let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg); + let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg); + if (isSystem) { + return true; // system principals have all permissions + } var msg = { 'op': 'has', 'type': type, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement }; return this._sendSyncMessage('SPPermissionManager', msg)[0]; }, testPermission: function (type, value, arg) { - let [url, appId, isInBrowserElement] = this._getInfoFromPermissionArg(arg); + let [url, appId, isInBrowserElement, isSystem] = this._getInfoFromPermissionArg(arg); + if (isSystem) { + return true; // system principals have all permissions + } var msg = { 'op': 'test', 'type': type, 'value': value, 'url': url, 'appId': appId, 'isInBrowserElement': isInBrowserElement
--- a/testing/xpcshell/mach_commands.py +++ b/testing/xpcshell/mach_commands.py @@ -136,20 +136,26 @@ class XPCShellRunner(MozbuildObject): xpcshell_filter = TestStartFilter() self.log_manager.terminal_handler.addFilter(xpcshell_filter) tests_dir = os.path.join(self.topobjdir, '_tests', 'xpcshell') modules_dir = os.path.join(self.topobjdir, '_tests', 'modules') # We want output from the test to be written immediately if we are only # running a single test. verbose_output = test_path is not None or (manifest and len(manifest.test_paths())==1) + + # We need to attach the '.exe' extension on Windows for the debugger to + # work properly. + xpcsExecutable = 'xpcshell' + if os.name == 'nt': + xpcsExecutable += '.exe' args = { 'manifest': manifest, - 'xpcshell': os.path.join(self.bindir, 'xpcshell'), + 'xpcshell': os.path.join(self.bindir, xpcsExecutable), 'mozInfo': os.path.join(self.topobjdir, 'mozinfo.json'), 'symbolsPath': os.path.join(self.distdir, 'crashreporter-symbols'), 'interactive': interactive, 'keepGoing': keep_going, 'logfiles': False, 'sequential': sequential, 'shuffle': shuffle, 'testsRootDir': tests_dir,
--- a/toolkit/components/crashmonitor/moz.build +++ b/toolkit/components/crashmonitor/moz.build @@ -1,16 +1,16 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] -EXTRA_JS_MODULES = [ +EXTRA_JS_MODULES += [ 'CrashMonitor.jsm', ] EXTRA_COMPONENTS += [ 'crashmonitor.manifest', 'nsCrashMonitor.js', -] \ No newline at end of file +]
--- a/toolkit/components/osfile/modules/moz.build +++ b/toolkit/components/osfile/modules/moz.build @@ -1,17 +1,15 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/osfile' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.osfile += [ 'osfile_async_front.jsm', 'osfile_async_worker.js', 'osfile_native.jsm', 'osfile_shared_allthreads.jsm', 'osfile_shared_front.jsm', 'osfile_unix_allthreads.jsm', 'osfile_unix_back.jsm', 'osfile_unix_front.jsm',
--- a/toolkit/components/places/moz.build +++ b/toolkit/components/places/moz.build @@ -54,17 +54,17 @@ if CONFIG['MOZ_PLACES']: 'SQLFunctions.cpp', 'VisitInfo.cpp', ] LOCAL_INCLUDES += [ '../build', ] - EXTRA_JS_MODULES = [ + EXTRA_JS_MODULES += [ 'BookmarkHTMLUtils.jsm', 'BookmarkJSONUtils.jsm', 'ClusterLib.js', 'ColorAnalyzer_worker.js', 'ColorConversion.js', 'PlacesBackups.jsm', 'PlacesDBUtils.jsm', 'PlacesTransactions.jsm',
--- a/toolkit/components/promiseworker/moz.build +++ b/toolkit/components/promiseworker/moz.build @@ -3,11 +3,11 @@ # 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/. DIRS += [ 'worker' ] -EXTRA_JS_MODULES = [ +EXTRA_JS_MODULES += [ 'PromiseWorker.jsm', ]
--- a/toolkit/components/promiseworker/worker/moz.build +++ b/toolkit/components/promiseworker/worker/moz.build @@ -1,11 +1,9 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/workers' - -EXTRA_JS_MODULES = [ +EXTRA_JS_MODULES.workers = [ 'PromiseWorker.js', ]
--- a/toolkit/components/social/moz.build +++ b/toolkit/components/social/moz.build @@ -5,17 +5,17 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini'] if CONFIG['MOZ_SOCIAL']: BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini'] # social is turned off for android - EXTRA_JS_MODULES = [ + EXTRA_JS_MODULES += [ 'FrameWorker.jsm', 'FrameWorkerContent.js', 'MessagePortBase.jsm', 'MessagePortWorker.js', 'MozSocialAPI.jsm', 'SocialService.jsm', 'WorkerAPI.jsm', ]
--- a/toolkit/components/sqlite/moz.build +++ b/toolkit/components/sqlite/moz.build @@ -1,13 +1,11 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini'] -JS_MODULES_PATH = 'modules/sqlite' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.sqlite += [ 'sqlite_internal.js', ]
--- a/toolkit/components/workerloader/moz.build +++ b/toolkit/components/workerloader/moz.build @@ -1,13 +1,11 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini'] -JS_MODULES_PATH = 'modules/workers' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.workers += [ 'require.js' ]
--- a/toolkit/components/workerlz4/moz.build +++ b/toolkit/components/workerlz4/moz.build @@ -1,19 +1,17 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['tests/xpcshell/xpcshell.ini'] -JS_MODULES_PATH = 'modules/workers' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.workers += [ 'lz4.js', 'lz4_internal.js', ] SOURCES += [ 'lz4.cpp', ]
--- a/toolkit/crashreporter/test/Makefile.in +++ b/toolkit/crashreporter/test/Makefile.in @@ -1,14 +1,14 @@ # # 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/. EXTRA_LIBS += $(NSPR_LIBS) -UNIT_FILES = $(SHARED_LIBRARY) $(EXTRA_JS_MODULES) +UNIT_FILES = $(SHARED_LIBRARY) CrashTestUtils.jsm UNIT_DEST = $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/ INSTALL_TARGETS += UNIT UNIT_IPC_FILES = $(UNIT_FILES) UNIT_IPC_DEST = $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit_ipc/ INSTALL_TARGETS += UNIT_IPC
--- a/toolkit/crashreporter/tools/symbolstore.py +++ b/toolkit/crashreporter/tools/symbolstore.py @@ -310,17 +310,18 @@ def validate_install_manifests(install_m def make_file_mapping(install_manifests): file_mapping = {} for manifest, destination in install_manifests: destination = os.path.abspath(destination) reg = FileRegistry() manifest.populate_registry(reg) for dst, src in reg: if hasattr(src, 'path'): - file_mapping[os.path.join(destination, dst)] = src.path + abs_dest = os.path.normpath(os.path.join(destination, dst)) + file_mapping[abs_dest] = src.path return file_mapping def GetPlatformSpecificDumper(**kwargs): """This function simply returns a instance of a subclass of Dumper that is appropriate for the current platform.""" # Python 2.5 has a bug where platform.system() returns 'Microsoft'. # Remove this when we no longer support Python 2.5. return {'Windows': Dumper_Win32,
--- a/toolkit/devtools/acorn/moz.build +++ b/toolkit/devtools/acorn/moz.build @@ -1,15 +1,13 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] -JS_MODULES_PATH = 'modules/devtools/acorn' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.acorn += [ 'acorn.js', 'acorn_loose.js', 'walk.js', ]
--- a/toolkit/devtools/apps/moz.build +++ b/toolkit/devtools/apps/moz.build @@ -1,14 +1,12 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TEST_DIRS += ['tests'] -JS_MODULES_PATH = 'modules/devtools' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools += [ 'app-actor-front.js', 'Devices.jsm', 'Simulator.jsm' ]
--- a/toolkit/devtools/discovery/moz.build +++ b/toolkit/devtools/discovery/moz.build @@ -1,13 +1,11 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TEST_DIRS += ['tests'] -JS_MODULES_PATH = 'modules/devtools/discovery' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.discovery += [ 'discovery.js', ]
--- a/toolkit/devtools/jsbeautify/moz.build +++ b/toolkit/devtools/jsbeautify/moz.build @@ -1,19 +1,17 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] -JS_MODULES_PATH = 'modules/devtools/jsbeautify' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.jsbeautify += [ 'beautify.js', 'lib/sanitytest.js', 'lib/urlencode_unpacker.js', 'src/beautify-css.js', 'src/beautify-html.js', 'src/beautify-js.js', 'src/beautify-tests.js' ]
--- a/toolkit/devtools/pretty-fast/moz.build +++ b/toolkit/devtools/pretty-fast/moz.build @@ -1,13 +1,11 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] -JS_MODULES_PATH = 'modules/devtools' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools += [ 'pretty-fast.js', ]
--- a/toolkit/devtools/qrcode/decoder/moz.build +++ b/toolkit/devtools/qrcode/decoder/moz.build @@ -1,11 +1,9 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/qrcode/decoder' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.qrcode.decoder += [ 'index.js', ]
--- a/toolkit/devtools/qrcode/encoder/moz.build +++ b/toolkit/devtools/qrcode/encoder/moz.build @@ -1,11 +1,9 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/qrcode/encoder' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.qrcode.encoder += [ 'index.js', ]
--- a/toolkit/devtools/qrcode/moz.build +++ b/toolkit/devtools/qrcode/moz.build @@ -9,16 +9,14 @@ DIRS += [ ] # Save file size on Fennec until there are active plans to use the decoder there if CONFIG['MOZ_BUILD_APP'] != 'mobile/android': DIRS += [ 'decoder' ] -JS_MODULES_PATH = 'modules/devtools/qrcode' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.qrcode += [ 'index.js', ] XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] MOCHITEST_CHROME_MANIFESTS += ['tests/mochitest/chrome.ini']
--- a/toolkit/devtools/styleinspector/moz.build +++ b/toolkit/devtools/styleinspector/moz.build @@ -1,11 +1,9 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/devtools/styleinspector' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.styleinspector += [ 'css-logic.js' ]
--- a/toolkit/devtools/tern/moz.build +++ b/toolkit/devtools/tern/moz.build @@ -1,19 +1,17 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini'] -JS_MODULES_PATH = 'modules/devtools/tern' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.tern += [ 'browser.js', 'comment.js', 'condense.js', 'def.js', 'ecma5.js', 'infer.js', 'signal.js', 'tern.js',
--- a/toolkit/devtools/transport/moz.build +++ b/toolkit/devtools/transport/moz.build @@ -1,15 +1,13 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TEST_DIRS += ['tests'] -JS_MODULES_PATH = 'modules/devtools/transport' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.transport += [ 'packets.js', 'stream-utils.js', 'transport.js' ]
--- a/toolkit/devtools/webconsole/moz.build +++ b/toolkit/devtools/webconsole/moz.build @@ -3,16 +3,14 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. if CONFIG['OS_TARGET'] != 'Android': MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini'] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] -JS_MODULES_PATH = 'modules/devtools/toolkit/webconsole' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.devtools.toolkit.webconsole += [ 'client.js', 'network-helper.js', 'network-monitor.js', 'utils.js', ]
--- a/toolkit/identity/moz.build +++ b/toolkit/identity/moz.build @@ -12,29 +12,27 @@ XPIDL_SOURCES += [ ] XPIDL_MODULE = 'identity' SOURCES += [ 'IdentityCryptoService.cpp', ] -JS_MODULES_PATH = 'modules/identity' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.identity += [ 'Identity.jsm', 'IdentityProvider.jsm', 'IdentityStore.jsm', 'IdentityUtils.jsm', 'jwcrypto.jsm', 'LogUtils.jsm', 'MinimalIdentity.jsm', 'RelyingParty.jsm', 'Sandbox.jsm', ] -EXTRA_PP_JS_MODULES += [ +EXTRA_PP_JS_MODULES.identity += [ 'FirefoxAccounts.jsm', ] FAIL_ON_WARNINGS = True FINAL_LIBRARY = 'xul'
--- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -1,29 +1,27 @@ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -JS_MODULES_PATH = 'modules/addons' - -EXTRA_JS_MODULES += [ +EXTRA_JS_MODULES.addons += [ 'AddonLogging.jsm', 'AddonRepository.jsm', 'AddonRepository_SQLiteMigrator.jsm', 'AddonUpdateChecker.jsm', 'Content.js', 'LightweightThemeImageOptimizer.jsm', 'OpenH264Provider.jsm', 'PluginProvider.jsm', 'SpellCheckDictionaryBootstrap.js', ] -EXTRA_PP_JS_MODULES += [ +EXTRA_PP_JS_MODULES.addons += [ 'XPIProvider.jsm', 'XPIProviderUtils.js', ] # This is used in multiple places, so is defined here to avoid it getting # out of sync. DEFINES['MOZ_EXTENSIONS_DB_SCHEMA'] = 16
--- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -1,17 +1,17 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. if CONFIG['LIBXUL_SDK']: error('toolkit.mozbuild is not compatible with --enable-libxul-sdk=') -if CONFIG['MOZ_CONTENT_SANDBOX'] or CONFIG['MOZ_GMP_SANDBOX']: +if CONFIG['MOZ_CONTENT_SANDBOX'] or (CONFIG['OS_ARCH'] == 'WINNT'): add_tier_dir('sandbox', 'security/sandbox') # Depends on NSS and NSPR, and must be built after sandbox or else B2G emulator # builds fail. add_tier_dir('platform', 'security/certverifier') # Depends on certverifier add_tier_dir('platform', 'security/apps')
--- a/tools/profiler/moz.build +++ b/tools/profiler/moz.build @@ -14,17 +14,17 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']: ] EXPORTS += [ 'GeckoProfilerFunc.h', 'GeckoProfilerImpl.h', 'ProfilerMarkers.h', 'PseudoStack.h', 'shared-libraries.h', ] - EXTRA_JS_MODULES = [ + EXTRA_JS_MODULES += [ 'Profiler.jsm', ] UNIFIED_SOURCES += [ 'BreakpadSampler.cpp', 'JSStreamWriter.cpp', 'nsProfiler.cpp', 'nsProfilerFactory.cpp', 'platform.cpp',
--- a/widget/BasicEvents.h +++ b/widget/BasicEvents.h @@ -53,30 +53,26 @@ enum nsEventStructType // ContentEvents.h NS_SCROLLPORT_EVENT, // InternalScrollPortEvent NS_SCROLLAREA_EVENT, // InternalScrollAreaEvent NS_FORM_EVENT, // InternalFormEvent NS_FOCUS_EVENT, // InternalFocusEvent NS_CLIPBOARD_EVENT, // InternalClipboardEvent NS_TRANSITION_EVENT, // InternalTransitionEvent NS_ANIMATION_EVENT, // InternalAnimationEvent + NS_SVGZOOM_EVENT, // InternalSVGZoomEvent + NS_SMIL_TIME_EVENT, // InternalSMILTimeEvent // MiscEvents.h NS_COMMAND_EVENT, // WidgetCommandEvent NS_CONTENT_COMMAND_EVENT, // WidgetContentCommandEvent NS_PLUGIN_EVENT, // WidgetPluginEvent // InternalMutationEvent.h (dom/events) - NS_MUTATION_EVENT, // InternalMutationEvent - - // Follwoing struct type values are ugly. They indicate other struct type - // actually. However, they are used for distinguishing which DOM event - // should be created for the event. - NS_SVGZOOM_EVENT, // WidgetGUIEvent - NS_SMIL_TIME_EVENT // InternalUIEvent + NS_MUTATION_EVENT // InternalMutationEvent }; /****************************************************************************** * Messages * * TODO: Make them enum. ******************************************************************************/ @@ -857,18 +853,17 @@ public: WidgetGUIEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) : WidgetEvent(aIsTrusted, aMessage, NS_GUI_EVENT), widget(aWidget) { } virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE { - MOZ_ASSERT(eventStructType == NS_GUI_EVENT || - eventStructType == NS_SVGZOOM_EVENT, + MOZ_ASSERT(eventStructType == NS_GUI_EVENT, "Duplicate() must be overridden by sub class"); // Not copying widget, it is a weak reference. WidgetGUIEvent* result = new WidgetGUIEvent(false, message, nullptr); result->AssignGUIEventData(*this, true); result->mFlags = mFlags; return result; } @@ -1170,18 +1165,17 @@ public: InternalUIEvent(bool aIsTrusted, uint32_t aMessage) : WidgetGUIEvent(aIsTrusted, aMessage, nullptr, NS_UI_EVENT) , detail(0) { } virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE { - MOZ_ASSERT(eventStructType == NS_UI_EVENT || - eventStructType == NS_SMIL_TIME_EVENT, + MOZ_ASSERT(eventStructType == NS_UI_EVENT, "Duplicate() must be overridden by sub class"); InternalUIEvent* result = new InternalUIEvent(false, message); result->AssignUIEventData(*this, true); result->mFlags = mFlags; return result; } int32_t detail;
--- a/widget/ContentEvents.h +++ b/widget/ContentEvents.h @@ -310,11 +310,81 @@ public: AssignEventData(aEvent, aCopyTargets); animationName = aEvent.animationName; elapsedTime = aEvent.elapsedTime; pseudoElement = aEvent.pseudoElement; } }; +/****************************************************************************** + * mozilla::InternalSVGZoomEvent + ******************************************************************************/ + +class InternalSVGZoomEvent : public WidgetGUIEvent +{ +public: + virtual InternalSVGZoomEvent* AsSVGZoomEvent() MOZ_OVERRIDE { return this; } + + InternalSVGZoomEvent(bool aIsTrusted, uint32_t aMessage) : + WidgetGUIEvent(aIsTrusted, aMessage, nullptr, NS_SVGZOOM_EVENT) + { + mFlags.mCancelable = false; + } + + virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE + { + MOZ_ASSERT(eventStructType == NS_SVGZOOM_EVENT, + "Duplicate() must be overridden by sub class"); + // Not copying widget, it is a weak reference. + InternalSVGZoomEvent* result = new InternalSVGZoomEvent(false, message); + result->AssignSVGZoomEventData(*this, true); + result->mFlags = mFlags; + return result; + } + + void AssignSVGZoomEventData(const InternalSVGZoomEvent& aEvent, + bool aCopyTargets) + { + AssignGUIEventData(aEvent, aCopyTargets); + } +}; + +/****************************************************************************** + * mozilla::InternalSMILTimeEvent + ******************************************************************************/ + +class InternalSMILTimeEvent : public InternalUIEvent +{ +public: + virtual InternalSMILTimeEvent* AsSMILTimeEvent() MOZ_OVERRIDE + { + return this; + } + + InternalSMILTimeEvent(bool aIsTrusted, uint32_t aMessage) : + InternalUIEvent(aIsTrusted, aMessage, NS_SMIL_TIME_EVENT) + { + mFlags.mBubbles = false; + mFlags.mCancelable = false; + } + + virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE + { + MOZ_ASSERT(eventStructType == NS_SMIL_TIME_EVENT, + "Duplicate() must be overridden by sub class"); + InternalSMILTimeEvent* result = new InternalSMILTimeEvent(false, message); + result->AssignSMILTimeEventData(*this, true); + result->mFlags = mFlags; + return result; + } + + void AssignSMILTimeEventData(const InternalSMILTimeEvent& aEvent, + bool aCopyTargets) + { + AssignUIEventData(aEvent, aCopyTargets); + } +}; + + } // namespace mozilla #endif // mozilla_ContentEvents_h__
--- a/widget/EventClassList.h +++ b/widget/EventClassList.h @@ -44,16 +44,18 @@ NS_EVENT_CLASS(Widget, TouchEvent) // ContentEvents.h NS_EVENT_CLASS(Internal, ScrollPortEvent) NS_EVENT_CLASS(Internal, ScrollAreaEvent) NS_EVENT_CLASS(Internal, FormEvent) NS_EVENT_CLASS(Internal, ClipboardEvent) NS_EVENT_CLASS(Internal, FocusEvent) NS_EVENT_CLASS(Internal, TransitionEvent) NS_EVENT_CLASS(Internal, AnimationEvent) +NS_EVENT_CLASS(Internal, SVGZoomEvent) +NS_EVENT_CLASS(Internal, SMILTimeEvent) // MiscEvents.h NS_EVENT_CLASS(Widget, CommandEvent) NS_EVENT_CLASS(Widget, ContentCommandEvent) NS_EVENT_CLASS(Widget, PluginEvent) // InternalMutationEvent.h (dom/events) NS_EVENT_CLASS(Internal, MutationEvent)
--- a/xpcom/tests/moz.build +++ b/xpcom/tests/moz.build @@ -60,21 +60,21 @@ CPP_UNIT_TESTS += [ 'TestAutoRef', 'TestCOMArray', 'TestCOMPtr', 'TestCOMPtrEq', 'TestDeque', 'TestFile', 'TestHashtables', 'TestID', + 'TestNsRefPtr', 'TestObserverArray', 'TestObserverService', 'TestPipe', 'TestPLDHash', - 'TestRefPtr', 'TestStringAPI', 'TestTArray', 'TestTextFormatter', 'TestThreadUtils' ] if CONFIG['MOZ_MEMORY']: CPP_UNIT_TESTS += [