This commit is contained in:
Ryan VanderMeulen 2013-07-03 14:04:16 -04:00
Родитель 474e756b18 8db0da549f
Коммит a4120936bf
1448 изменённых файлов: 58848 добавлений и 39085 удалений

Просмотреть файл

@ -17,4 +17,4 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 880917 needs a clobber for the removal of testVersion.cpp
Bug 848491 - Skia update.

Просмотреть файл

@ -9,11 +9,4 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_JS_MODULES = \
Keyboard.jsm \
TelURIParser.jsm \
SignInToWebsite.jsm \
ErrorPage.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -35,3 +35,10 @@ if CONFIG['MOZ_UPDATER']:
EXTRA_PP_COMPONENTS += [
'UpdatePrompt.js',
]
EXTRA_JS_MODULES += [
'ErrorPage.jsm',
'Keyboard.jsm',
'SignInToWebsite.jsm',
'TelURIParser.jsm',
]

Просмотреть файл

@ -135,17 +135,9 @@ pref("app.update.enabled", true);
// the UI easier to construct.
pref("app.update.auto", true);
// Defines how the Application Update Service notifies the user about updates:
//
// AUM Set to: Minor Releases: Major Releases:
// 0 download no prompt download no prompt
// 1 download no prompt download no prompt if no incompatibilities
// 2 download no prompt prompt
//
// See chart in nsUpdateService.js source for more details
// incompatibilities are ignored by updates in Metro
//
pref("app.update.mode", 0);
pref("app.update.mode", 1);
#ifdef XP_WIN
#ifdef MOZ_METRO

Просмотреть файл

@ -144,6 +144,11 @@ const DEFAULT_SNIPPETS_URLS = [
const SNIPPETS_UPDATE_INTERVAL_MS = 86400000; // 1 Day.
// IndexedDB storage constants.
const DATABASE_NAME = "abouthome";
const DATABASE_VERSION = 1;
const SNIPPETS_OBJECTSTORE_NAME = "snippets";
// This global tracks if the page has been set up before, to prevent double inits
let gInitialized = false;
let gObserver = new MutationObserver(function (mutations) {
@ -200,40 +205,87 @@ function ensureSnippetsMapThen(aCallback)
return;
}
// TODO (bug 789348): use a real asynchronous storage here. This setTimeout
// is done just to catch bugs with the asynchronous behavior.
setTimeout(function() {
// Populate the cache from the persistent storage.
let cache = new Map();
for (let key of [ "snippets-last-update",
"snippets-cached-version",
"snippets" ]) {
cache.set(key, localStorage[key]);
let invokeCallbacks = function () {
if (!gSnippetsMap) {
gSnippetsMap = Object.freeze(new Map());
}
gSnippetsMap = Object.freeze({
get: function (aKey) cache.get(aKey),
set: function (aKey, aValue) {
localStorage[aKey] = aValue;
return cache.set(aKey, aValue);
},
has: function(aKey) cache.has(aKey),
delete: function(aKey) {
delete localStorage[aKey];
return cache.delete(aKey);
},
clear: function() {
localStorage.clear();
return cache.clear();
},
get size() cache.size
});
for (let callback of gSnippetsMapCallbacks) {
callback(gSnippetsMap);
}
gSnippetsMapCallbacks.length = 0;
}, 0);
}
let openRequest = indexedDB.open(DATABASE_NAME, DATABASE_VERSION);
openRequest.onerror = function (event) {
// Try to delete the old database so that we can start this process over
// next time.
indexedDB.deleteDatabase(DATABASE_NAME);
invokeCallbacks();
};
openRequest.onupgradeneeded = function (event) {
let db = event.target.result;
if (!db.objectStoreNames.contains(SNIPPETS_OBJECTSTORE_NAME)) {
db.createObjectStore(SNIPPETS_OBJECTSTORE_NAME);
}
}
openRequest.onsuccess = function (event) {
let db = event.target.result;
db.onerror = function (event) {
invokeCallbacks();
}
db.onversionchange = function (event) {
event.target.close();
invokeCallbacks();
}
let cache = new Map();
let cursorRequest = db.transaction(SNIPPETS_OBJECTSTORE_NAME)
.objectStore(SNIPPETS_OBJECTSTORE_NAME).openCursor();
cursorRequest.onerror = function (event) {
invokeCallbacks();
}
cursorRequest.onsuccess = function(event) {
let cursor = event.target.result;
// Populate the cache from the persistent storage.
if (cursor) {
cache.set(cursor.key, cursor.value);
cursor.continue();
return;
}
// The cache has been filled up, create the snippets map.
gSnippetsMap = Object.freeze({
get: function (aKey) cache.get(aKey),
set: function (aKey, aValue) {
db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
.objectStore(SNIPPETS_OBJECTSTORE_NAME).put(aValue, aKey);
return cache.set(aKey, aValue);
},
has: function (aKey) cache.has(aKey),
delete: function (aKey) {
db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
.objectStore(SNIPPETS_OBJECTSTORE_NAME).delete(aKey);
return cache.delete(aKey);
},
clear: function () {
db.transaction(SNIPPETS_OBJECTSTORE_NAME, "readwrite")
.objectStore(SNIPPETS_OBJECTSTORE_NAME).clear();
return cache.clear();
},
get size() cache.size
});
setTimeout(invokeCallbacks, 0);
}
}
}
function onSearchSubmit(aEvent)

Просмотреть файл

@ -13,6 +13,4 @@ DISABLED_EXTRA_COMPONENTS = \
BrowserComponents.manifest \
$(NULL)
EXTRA_JS_MODULES = distribution.js
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -15,9 +15,4 @@ DISABLED_EXTRA_COMPONENTS = \
DownloadsStartup.js \
$(NULL)
EXTRA_JS_MODULES = \
DownloadsCommon.jsm \
DownloadsLogger.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -9,3 +9,9 @@ EXTRA_COMPONENTS += [
'DownloadsStartup.js',
'DownloadsUI.js',
]
EXTRA_JS_MODULES += [
'DownloadsCommon.jsm',
'DownloadsLogger.jsm',
]

Просмотреть файл

@ -43,3 +43,8 @@ EXTRA_PP_COMPONENTS += [
'nsBrowserContentHandler.js',
'nsBrowserGlue.js',
]
EXTRA_JS_MODULES += [
'distribution.js',
]

Просмотреть файл

@ -937,7 +937,7 @@ PlacesController.prototype = {
gen.next();
} catch (ex if ex instanceof StopIteration) {}
}, Ci.nsIThread.DISPATCH_NORMAL);
yield;
yield undefined;
}
}
let gen = pagesChunkGenerator(URIs);

Просмотреть файл

@ -15,9 +15,5 @@ DISABLED_EXTRA_COMPONENTS = \
PlacesProtocolHandler.js \
$(NULL)
EXTRA_JS_MODULES = \
PlacesUIUtils.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -12,3 +12,8 @@ EXTRA_COMPONENTS += [
'BrowserPlaces.manifest',
'PlacesProtocolHandler.js',
]
EXTRA_JS_MODULES += [
'PlacesUIUtils.jsm',
]

Просмотреть файл

@ -16,16 +16,6 @@ DISABLED_EXTRA_COMPONENTS = \
nsSessionStartup.js \
$(NULL)
JS_MODULES_PATH := modules/sessionstore
EXTRA_JS_MODULES := \
DocumentUtils.jsm \
SessionStorage.jsm \
SessionMigration.jsm \
XPathGenerator.jsm \
_SessionFile.jsm \
$(NULL)
EXTRA_PP_JS_MODULES := \
SessionStore.jsm \
$(NULL)

Просмотреть файл

@ -9,3 +9,13 @@ EXTRA_COMPONENTS += [
'nsSessionStore.js',
'nsSessionStore.manifest',
]
JS_MODULES_PATH = 'modules/sessionstore'
EXTRA_JS_MODULES = [
'DocumentUtils.jsm',
'SessionMigration.jsm',
'SessionStorage.jsm',
'XPathGenerator.jsm',
'_SessionFile.jsm',
]

Просмотреть файл

@ -10,10 +10,4 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_JS_MODULES = \
source-editor.jsm \
source-editor-orion.jsm \
source-editor-ui.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -5,3 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TEST_DIRS += ['test']
EXTRA_JS_MODULES += [
'source-editor-orion.jsm',
'source-editor-ui.jsm',
'source-editor.jsm',
]

Просмотреть файл

@ -9,12 +9,6 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
EXTRA_JS_MODULES = \
HUDService.jsm \
NetworkPanel.jsm \
WebConsolePanel.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk
libs::

Просмотреть файл

@ -6,3 +6,9 @@
TEST_DIRS += ['test']
EXTRA_JS_MODULES += [
'HUDService.jsm',
'NetworkPanel.jsm',
'WebConsolePanel.jsm',
]

Просмотреть файл

@ -102,6 +102,12 @@
#ifdef MOZ_METRO
@BINPATH@/vccorlib110.dll
#endif
#elif MOZ_MSVC_REDIST == 1800
@BINPATH@/msvcp120.dll
@BINPATH@/msvcr120.dll
#ifdef MOZ_METRO
@BINPATH@/vccorlib120.dll
#endif
#endif
#endif
#endif

Просмотреть файл

@ -1443,6 +1443,13 @@ xpicleanup@BIN_SUFFIX@
vccorlib110.dll
#endif
#endif
#if MOZ_MSVC_REDIST != 1800
msvcp120.dll
msvcr120.dll
#ifdef MOZ_METRO
vccorlib120.dll
#endif
#endif
plugins/npnul32.dll
#endif
@DLL_PREFIX@xpcom_core@DLL_SUFFIX@

Просмотреть файл

@ -18,6 +18,10 @@ const TOOLBARSTATE_LOADED = 2;
// Page for which the start UI is shown
const kStartOverlayURI = "about:start";
// Devtools Messages
const debugServerStateChanged = "devtools.debugger.remote-enabled";
const debugServerPortChanged = "devtools.debugger.remote-port";
/**
* Cache of commonly used elements.
*/
@ -75,6 +79,14 @@ var BrowserUI = {
lastKnownGoodURL: "", //used when the user wants to escape unfinished url entry
init: function() {
// start the debugger now so we can use it on the startup code as well
if (Services.prefs.getBoolPref(debugServerStateChanged)) {
this.runDebugServer();
}
Services.prefs.addObserver(debugServerStateChanged, this, false);
Services.prefs.addObserver(debugServerPortChanged, this, false);
// listen content messages
messageManager.addMessageListener("DOMTitleChanged", this);
messageManager.addMessageListener("DOMWillOpenModalDialog", this);
@ -181,8 +193,38 @@ var BrowserUI = {
SettingsCharm.uninit();
messageManager.removeMessageListener("Content:StateChange", this);
PageThumbs.uninit();
this.stopDebugServer();
},
/************************************
* Devtools Debugger
*/
runDebugServer: function runDebugServer(aPort) {
let port = aPort || Services.prefs.getIntPref(debugServerPortChanged);
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
DebuggerServer.addActors('chrome://browser/content/dbg-metro-actors.js');
}
DebuggerServer.openListener(port);
},
stopDebugServer: function stopDebugServer() {
if (DebuggerServer.initialized) {
DebuggerServer.destroy();
}
},
// If the server is not on, port changes have nothing to effect. The new value
// will be picked up if the server is started.
// To be consistent with desktop fx, if the port is changed while the server
// is running, restart server.
changeDebugPort:function changeDebugPort(aPort) {
if (DebuggerServer.initialized) {
this.stopDebugServer();
this.runDebugServer(aPort);
}
},
/*********************************
* Content visibility
@ -597,6 +639,16 @@ var BrowserUI = {
case "browser.urlbar.trimURLs":
this._mayTrimURLs = Services.prefs.getBoolPref(aData);
break;
case debugServerStateChanged:
if (Services.prefs.getBoolPref(aData)) {
this.runDebugServer();
} else {
this.stopDebugServer();
}
break;
case debugServerPortChanged:
this.changeDebugPort(Services.prefs.getIntPref(aData));
break;
}
break;
case "metro_viewstate_changed":
@ -1361,12 +1413,6 @@ var StartUI = {
section.init();
});
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addBrowserActors();
DebuggerServer.addActors('chrome://browser/content/dbg-metro-actors.js');
}
DebuggerServer.openListener(6000);
},
uninit: function() {

Просмотреть файл

@ -9,8 +9,4 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
EXTRA_JS_MODULES = \
colorUtils.jsm \
CrossSlide.jsm \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -4,3 +4,8 @@
# 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 += [
'CrossSlide.jsm',
'colorUtils.jsm',
]

Просмотреть файл

@ -413,13 +413,6 @@ pref("app.update.enabled", true);
// the UI easier to construct.
pref("app.update.auto", true);
// Defines how the Application Update Service notifies the user about updates:
//
// AUM Set to: Minor Releases: Major Releases:
// 0 download no prompt download no prompt
// 1 download no prompt download no prompt if no incompatibilities
// 2 download no prompt prompt
//
// See chart in nsUpdateService.js source for more details
pref("app.update.mode", 0);

Просмотреть файл

@ -185,6 +185,7 @@ menulist {
.menu-popup > richlistbox > scrollbox {
width: 100%;
overflow-x: hidden !important;
}
.menu-popup richlistitem {

Просмотреть файл

@ -11,32 +11,11 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/config.mk
EXTRA_JS_MODULES = \
BrowserNewTabPreloader.jsm \
openLocationLastURL.jsm \
NetworkPrioritizer.jsm \
offlineAppCache.jsm \
SignInToWebsite.jsm \
SitePermissions.jsm \
webappsUI.jsm \
webrtcUI.jsm \
Social.jsm \
SharedFrame.jsm \
$(NULL)
EXTRA_PP_JS_MODULES = \
AboutHomeUtils.jsm \
RecentWindow.jsm \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
EXTRA_JS_MODULES += \
WindowsJumpLists.jsm \
WindowsPreviewPerTab.jsm \
$(NULL)
endif
ifdef MOZILLA_OFFICIAL
DEFINES += -DMOZILLA_OFFICIAL=1
endif

Просмотреть файл

@ -6,3 +6,21 @@
TEST_DIRS += ['test']
EXTRA_JS_MODULES += [
'BrowserNewTabPreloader.jsm',
'NetworkPrioritizer.jsm',
'SharedFrame.jsm',
'SignInToWebsite.jsm',
'SitePermissions.jsm',
'Social.jsm',
'offlineAppCache.jsm',
'openLocationLastURL.jsm',
'webappsUI.jsm',
'webrtcUI.jsm',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
EXTRA_JS_MODULES += [
'WindowsJumpLists.jsm',
'WindowsPreviewPerTab.jsm',
]

Просмотреть файл

@ -55,6 +55,7 @@ SEARCH_PATHS = [
MACH_MODULES = [
'addon-sdk/mach_commands.py',
'layout/tools/reftest/mach_commands.py',
'python/mach_commands.py',
'python/mach/mach/commands/commandinfo.py',
'python/mozboot/mozboot/mach_commands.py',
'python/mozbuild/mozbuild/config.py',

Просмотреть файл

@ -56,6 +56,13 @@ REDIST_FILES = \
$(NULL)
endif
ifeq (1800,$(_MSC_VER))
REDIST_FILES = \
msvcp120.dll \
msvcr120.dll \
$(NULL)
endif
ifdef REDIST_FILES
libs-preqs = \
$(call mkdir_deps,$(FINAL_TARGET)) \

Просмотреть файл

@ -46,7 +46,7 @@ static bool URIIsImmutable(nsIURI* aURI)
return
mutableObj &&
NS_SUCCEEDED(mutableObj->GetMutable(&isMutable)) &&
!isMutable;
!isMutable;
}
// Static member variables
@ -344,18 +344,6 @@ nsPrincipal::GetURI(nsIURI** aURI)
return NS_EnsureSafeToReturn(mCodebase, aURI);
}
static bool
URIIsLocalFile(nsIURI *aURI)
{
bool isFile;
nsCOMPtr<nsINetUtil> util = do_GetNetUtil();
return util && NS_SUCCEEDED(util->ProtocolHasFlags(aURI,
nsIProtocolHandler::URI_IS_LOCAL_FILE,
&isFile)) &&
isFile;
}
NS_IMETHODIMP
nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrincipal)
{
@ -367,88 +355,23 @@ nsPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport, bool aAllowIfInheritsPrinc
}
}
if (!nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
URIIsLocalFile(aURI)) {
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(aURI));
if (!URIIsLocalFile(mCodebase)) {
// If the codebase is not also a file: uri then forget it
// (don't want resource: principals in a file: doc)
//
// note: we're not de-nesting jar: uris here, we want to
// keep archive content bottled up in its own little island
if (aReport) {
nsScriptSecurityManager::ReportError(
nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
}
return NS_ERROR_DOM_BAD_URI;
}
//
// pull out the internal files
//
nsCOMPtr<nsIFileURL> codebaseFileURL(do_QueryInterface(mCodebase));
nsCOMPtr<nsIFile> targetFile;
nsCOMPtr<nsIFile> codebaseFile;
bool targetIsDir;
// Make sure targetFile is not a directory (bug 209234)
// and that it exists w/out unescaping (bug 395343)
if (!codebaseFileURL || !fileURL ||
NS_FAILED(fileURL->GetFile(getter_AddRefs(targetFile))) ||
NS_FAILED(codebaseFileURL->GetFile(getter_AddRefs(codebaseFile))) ||
!targetFile || !codebaseFile ||
NS_FAILED(targetFile->Normalize()) ||
#ifndef MOZ_WIDGET_ANDROID
NS_FAILED(codebaseFile->Normalize()) ||
#endif
NS_FAILED(targetFile->IsDirectory(&targetIsDir)) ||
targetIsDir) {
if (aReport) {
nsScriptSecurityManager::ReportError(
nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
}
return NS_ERROR_DOM_BAD_URI;
}
//
// If the file to be loaded is in a subdirectory of the codebase
// (or same-dir if codebase is not a directory) then it will
// inherit its codebase principal and be scriptable by that codebase.
//
bool codebaseIsDir;
bool contained = false;
nsresult rv = codebaseFile->IsDirectory(&codebaseIsDir);
if (NS_SUCCEEDED(rv) && codebaseIsDir) {
rv = codebaseFile->Contains(targetFile, true, &contained);
}
else {
nsCOMPtr<nsIFile> codebaseParent;
rv = codebaseFile->GetParent(getter_AddRefs(codebaseParent));
if (NS_SUCCEEDED(rv) && codebaseParent) {
rv = codebaseParent->Contains(targetFile, true, &contained);
}
}
if (NS_SUCCEEDED(rv) && contained) {
return NS_OK;
}
}
if (aReport) {
nsScriptSecurityManager::ReportError(
nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
}
return NS_ERROR_DOM_BAD_URI;
if (nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
return NS_OK;
}
return NS_OK;
// If strict file origin policy is in effect, local files will always fail
// SecurityCompareURIs unless they are identical. Explicitly check file origin
// policy, in that case.
if (nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
NS_URIIsLocalFile(aURI) &&
NS_RelaxStrictFileOriginPolicy(aURI, mCodebase)) {
return NS_OK;
}
if (aReport) {
nsScriptSecurityManager::ReportError(nullptr, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
}
return NS_ERROR_DOM_BAD_URI;
}
void
@ -562,7 +485,7 @@ NS_IMETHODIMP
nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
{
// For a file URI, we return the file path.
if (URIIsLocalFile(mCodebase)) {
if (NS_URIIsLocalFile(mCodebase)) {
nsCOMPtr<nsIURL> url = do_QueryInterface(mCodebase);
if (url) {

Просмотреть файл

@ -22,10 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=758258
var Ci = Components.interfaces;
if (navigator.platform.startsWith("Linux")) {
SimpleTest.expectAssertions(2, 4);
}
SimpleTest.waitForExplicitFinish();
/*

Просмотреть файл

@ -58,7 +58,6 @@ endif
HEADERS_FILES = \
$(DEPTH)/mozilla-config.h \
$(srcdir)/nsStaticComponents.h \
$(NULL)
HEADERS_DEST := $(DIST)/include
HEADERS_TARGET := export

Просмотреть файл

@ -239,9 +239,7 @@ _ENABLE_PIC=1
ifdef LIBXUL_LIBRARY
ifdef IS_COMPONENT
ifdef MODULE_NAME
DEFINES += -DXPCOM_TRANSLATE_NSGM_ENTRY_POINT=1
else
ifndef MODULE_NAME
$(error Component makefile does not specify MODULE_NAME.)
endif
endif

Просмотреть файл

@ -1,36 +0,0 @@
#line 2 "nsStaticComponents.cpp.in"
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#define XPCOM_TRANSLATE_NSGM_ENTRY_POINT 1
#include "mozilla/ModuleUtils.h"
#include "nsXPCOM.h"
#include "nsMemory.h"
#include "nsStaticComponents.h"
/**
* Declare an NSGetModule() routine for a generic module.
*/
#define MODULE(_name) \
NSMODULE_DECL(_name);
%MODULE_LIST%
#line 57 "nsStaticComponents.cpp.in"
#undef MODULE
#define MODULE(_name) \
&NSMODULE_NAME(_name),
/**
* The nsStaticModuleInfo
*/
const mozilla::Module *const *const kPStaticModules[] = {
%MODULE_LIST%
#line 70 "nsStaticComponents.cpp.in"
NULL
};

Просмотреть файл

@ -1,15 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsStaticComponents_h__
#define nsStaticComponents_h__
#include "mozilla/Module.h"
// These symbols are provided by nsStaticComponents.cpp, and also by other
// static component providers such as nsStaticXULComponents (libxul).
extern mozilla::Module const *const *const kPStaticModules[];
#endif

Просмотреть файл

@ -487,16 +487,18 @@ case "$target" in
AC_MSG_ERROR([The major versions of \$CC and \$CXX do not match.])
fi
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
if test "$_CC_MAJOR_VERSION" = "16"; then
_CC_SUITE=10
_MSVS_VERSION=2010
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "17"; then
_CC_SUITE=11
_MSVS_VERSION=2012
AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
elif test "$_CC_MAJOR_VERSION" = "18"; then
_CC_SUITE=12
_MSVS_VERSION=2013
else
AC_MSG_ERROR([This version ($CC_VERSION) of the MSVC compiler is unsupported. See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
fi

Просмотреть файл

@ -12,12 +12,19 @@
#define BLOBURI_SCHEME "blob"
#define MEDIASTREAMURI_SCHEME "mediastream"
#define MEDIASOURCEURI_SCHEME "mediasource"
class nsIDOMBlob;
class nsIDOMMediaStream;
class nsIPrincipal;
class nsIInputStream;
namespace mozilla {
namespace dom {
class MediaSource;
}
}
class nsHostObjectProtocolHandler : public nsIProtocolHandler
{
public:
@ -55,6 +62,12 @@ public:
NS_IMETHOD GetScheme(nsACString &result) MOZ_OVERRIDE;
};
class nsMediaSourceProtocolHandler : public nsHostObjectProtocolHandler
{
public:
NS_IMETHOD GetScheme(nsACString &result) MOZ_OVERRIDE;
};
inline bool IsBlobURI(nsIURI* aUri)
{
bool isBlob;
@ -67,12 +80,21 @@ inline bool IsMediaStreamURI(nsIURI* aUri)
return NS_SUCCEEDED(aUri->SchemeIs(MEDIASTREAMURI_SCHEME, &isStream)) && isStream;
}
inline bool IsMediaSourceURI(nsIURI* aUri)
{
bool isMediaSource;
return NS_SUCCEEDED(aUri->SchemeIs(MEDIASOURCEURI_SCHEME, &isMediaSource)) && isMediaSource;
}
extern nsresult
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
extern nsresult
NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream);
extern nsresult
NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource);
#define NS_BLOBPROTOCOLHANDLER_CID \
{ 0xb43964aa, 0xa078, 0x44b2, \
{ 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } }
@ -81,4 +103,8 @@ NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream);
{ 0x27d1fa24, 0x2b73, 0x4db3, \
{ 0xab, 0x48, 0xb9, 0x83, 0x83, 0x40, 0xe0, 0x81 } }
#define NS_MEDIASOURCEPROTOCOLHANDLER_CID \
{ 0x12ef31fc, 0xa8fb, 0x4661, \
{ 0x9a, 0x63, 0xfb, 0x61, 0x04,0x5d, 0xb8, 0x61 } }
#endif /* nsHostObjectProtocolHandler_h */

Просмотреть файл

@ -34,10 +34,6 @@ EXTRA_COMPONENTS = \
messageWakeupService.manifest \
$(NULL)
EXTRA_JS_MODULES = \
CSPUtils.jsm \
$(NULL)
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/ipc/chromium/chromium-config.mk
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -157,3 +157,7 @@ CPP_SOURCES += [
EXTRA_PP_COMPONENTS += [
'contentSecurityPolicy.js',
]
EXTRA_JS_MODULES += [
'CSPUtils.jsm',
]

Просмотреть файл

@ -1033,21 +1033,6 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope,
return true;
}
// static
void
nsFrameScriptExecutor::Traverse(nsFrameScriptExecutor *tmp,
nsCycleCollectionTraversalCallback &cb)
{
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
}
// static
void
nsFrameScriptExecutor::Unlink(nsFrameScriptExecutor* aTmp)
{
aTmp->mGlobal = nullptr;
}
NS_IMPL_ISUPPORTS1(nsScriptCacheCleaner, nsIObserver)
nsFrameMessageManager* nsFrameMessageManager::sChildProcessManager = nullptr;

Просмотреть файл

@ -289,9 +289,6 @@ protected:
void TryCacheLoadAndCompileScript(const nsAString& aURL,
CacheFailedBehavior aBehavior = DONT_EXECUTE);
bool InitTabChildGlobalInternal(nsISupports* aScope, const nsACString& aID);
static void Traverse(nsFrameScriptExecutor *tmp,
nsCycleCollectionTraversalCallback &cb);
static void Unlink(nsFrameScriptExecutor* aTmp);
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
nsCOMPtr<nsIPrincipal> mPrincipal;
static nsDataHashtable<nsStringHashKey, nsFrameJSScriptExecutorHolder*>* sCachedScripts;

Просмотреть файл

@ -10,12 +10,13 @@
#include "nsIPrincipal.h"
#include "nsIDOMFile.h"
#include "nsIDOMMediaStream.h"
#include "mozilla/dom/MediaSource.h"
// -----------------------------------------------------------------------
// Hash table
struct DataInfo
{
// mObject must be an nsIDOMBlob or an nsIDOMMediaStream
// mObject is expected to be an nsIDOMBlob, nsIDOMMediaStream, or MediaSource
nsCOMPtr<nsISupports> mObject;
nsCOMPtr<nsIPrincipal> mPrincipal;
};
@ -183,7 +184,8 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
return NS_ERROR_DOM_BAD_URI;
}
nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(info->mObject);
if (!blob) {
nsCOMPtr<mozilla::dom::MediaSource> mediasource = do_QueryInterface(info->mObject);
if (!blob && !mediasource) {
return NS_ERROR_DOM_BAD_URI;
}
@ -197,7 +199,12 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
#endif
nsCOMPtr<nsIInputStream> stream;
nsresult rv = blob->GetInternalStream(getter_AddRefs(stream));
nsresult rv = NS_OK;
if (blob) {
rv = blob->GetInternalStream(getter_AddRefs(stream));
} else {
stream = mediasource->CreateInternalStream();
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> channel;
@ -209,25 +216,30 @@ nsHostObjectProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
nsString type;
rv = blob->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(info->mObject);
if (file) {
nsString filename;
rv = file->GetName(filename);
if (blob) {
rv = blob->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
channel->SetContentDispositionFilename(filename);
}
uint64_t size;
rv = blob->GetSize(&size);
NS_ENSURE_SUCCESS(rv, rv);
uint64_t size;
rv = blob->GetSize(&size);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMFile> file = do_QueryInterface(info->mObject);
if (file) {
nsString filename;
rv = file->GetName(filename);
NS_ENSURE_SUCCESS(rv, rv);
channel->SetContentDispositionFilename(filename);
}
channel->SetContentLength(size);
} else {
type = mediasource->GetType();
}
channel->SetOwner(owner);
channel->SetOriginalURI(uri);
channel->SetContentType(NS_ConvertUTF16toUTF8(type));
channel->SetContentLength(size);
channel.forget(result);
@ -257,6 +269,13 @@ nsMediaStreamProtocolHandler::GetScheme(nsACString &result)
return NS_OK;
}
NS_IMETHODIMP
nsMediaSourceProtocolHandler::GetScheme(nsACString &result)
{
result.AssignLiteral(MEDIASOURCEURI_SCHEME);
return NS_OK;
}
nsresult
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
{
@ -288,3 +307,19 @@ NS_GetStreamForMediaStreamURI(nsIURI* aURI, nsIDOMMediaStream** aStream)
NS_ADDREF(*aStream);
return NS_OK;
}
nsresult
NS_GetSourceForMediaSourceURI(nsIURI* aURI, mozilla::dom::MediaSource** aSource)
{
NS_ASSERTION(IsMediaSourceURI(aURI), "Only call this with mediasource URIs");
*aSource = nullptr;
nsCOMPtr<mozilla::dom::MediaSource> source = do_QueryInterface(GetDataObject(aURI));
if (!source) {
return NS_ERROR_DOM_BAD_URI;
}
source.forget(aSource);
return NS_OK;
}

Просмотреть файл

@ -14,8 +14,9 @@
#include "nsSimpleURI.h"
/**
* These URIs refer to host objects: Blobs, with scheme "blob", and
* MediaStreams, with scheme "mediastream".
* These URIs refer to host objects: Blobs, with scheme "blob",
* MediaStreams, with scheme "mediastream", and MediaSources, with scheme
* "mediasource".
*/
class nsHostObjectURI : public nsSimpleURI,
public nsIURIWithPrincipal

Просмотреть файл

@ -144,18 +144,10 @@ nsInProcessTabChildGlobal::Init()
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
nsFrameScriptExecutor::Unlink(tmp);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
nsFrameScriptExecutor::Traverse(tmp, cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(nsInProcessTabChildGlobal,
nsDOMEventTargetHelper,
mMessageManager,
mGlobal)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)

Просмотреть файл

@ -218,7 +218,8 @@ nsNodeUtils::LastRelease(nsINode* aNode)
static_cast<nsGenericHTMLFormElement*>(aNode)->ClearForm(true);
}
if (aNode->IsElement() && aNode->AsElement()->IsHTML(nsGkAtoms::img)) {
if (aNode->IsElement() && aNode->AsElement()->IsHTML(nsGkAtoms::img) &&
aNode->HasFlag(ADDED_TO_FORM)) {
HTMLImageElement* imageElem = static_cast<HTMLImageElement*>(aNode);
imageElem->ClearForm(true);
}

Просмотреть файл

@ -28,6 +28,7 @@
#include "nsJSNPRuntime.h"
#include "nsIPresShell.h"
#include "nsIScriptGlobalObject.h"
#include "nsScriptSecurityManager.h"
#include "nsIScriptSecurityManager.h"
#include "nsIStreamConverterService.h"
#include "nsIURILoader.h"
@ -1190,6 +1191,46 @@ nsObjectLoadingContent::ObjectState() const
return NS_EVENT_STATE_LOADING;
}
// Returns false if mBaseURI is not acceptable for java applets.
bool
nsObjectLoadingContent::CheckJavaCodebase()
{
nsCOMPtr<nsIContent> thisContent =
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
nsCOMPtr<nsIScriptSecurityManager> secMan =
nsContentUtils::GetSecurityManager();
nsCOMPtr<nsINetUtil> netutil = do_GetNetUtil();
NS_ASSERTION(thisContent && secMan && netutil, "expected interfaces");
// Note that mBaseURI is this tag's requested base URI, not the codebase of
// the document for security purposes
nsresult rv = secMan->CheckLoadURIWithPrincipal(thisContent->NodePrincipal(),
mBaseURI, 0);
if (NS_FAILED(rv)) {
LOG(("OBJLC [%p]: Java codebase check failed", this));
return false;
}
nsCOMPtr<nsIURI> principalBaseURI;
rv = thisContent->NodePrincipal()->GetURI(getter_AddRefs(principalBaseURI));
if (NS_FAILED(rv)) {
NS_NOTREACHED("Failed to URI from node principal?");
return false;
}
// We currently allow java's codebase to be non-same-origin, with
// the exception of URIs that represent local files
if (NS_URIIsLocalFile(mBaseURI) &&
nsScriptSecurityManager::GetStrictFileOriginPolicy() &&
!NS_RelaxStrictFileOriginPolicy(mBaseURI, principalBaseURI)) {
LOG(("OBJLC [%p]: Java failed RelaxStrictFileOriginPolicy for file URI",
this));
return false;
}
return true;
}
bool
nsObjectLoadingContent::CheckLoadPolicy(int16_t *aContentPolicy)
{
@ -1418,12 +1459,15 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
}
if (isJava && hasCodebase && codebaseStr.IsEmpty()) {
// Java treats an empty codebase as the document codebase, but codebase=""
// as "/"
// Java treats codebase="" as "/"
codebaseStr.AssignLiteral("/");
// XXX(johns): This doesn't cover the case of "https:" which java would
// interpret as "https:///" but we interpret as this document's
// URI but with a changed scheme.
} else if (isJava && !hasCodebase) {
// Java expects a directory as the codebase, or else it will construct
// relative URIs incorrectly :(
codebaseStr.AssignLiteral(".");
}
if (!codebaseStr.IsEmpty()) {
@ -1870,14 +1914,7 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
if (mType != eType_Null) {
bool allowLoad = true;
if (nsPluginHost::IsJavaMIMEType(mContentType.get())) {
nsCOMPtr<nsIScriptSecurityManager> secMan =
nsContentUtils::GetSecurityManager();
rv = secMan->CheckLoadURIWithPrincipal(thisContent->NodePrincipal(),
mBaseURI, 0);
if (NS_FAILED(rv)) {
LOG(("OBJLC [%p]: Java codebase check failed", this));
allowLoad = false;
}
allowLoad = CheckJavaCodebase();
}
int16_t contentPolicy = nsIContentPolicy::ACCEPT;
// If mChannelLoaded is set we presumably already passed load policy

Просмотреть файл

@ -378,6 +378,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
*/
bool ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentType);
/*
* Helper to check if mBaseURI can be used by java as a codebase
*/
bool CheckJavaCodebase();
/**
* Helper to check if our current URI passes policy
*

Просмотреть файл

@ -98,9 +98,14 @@
#include "mozilla/dom/TextMetrics.h"
#ifdef USE_SKIA_GPU
#undef free // apparently defined by some windows header, clashing with a free()
// method in SkTypes.h
#include "GLContext.h"
#include "GLContextProvider.h"
#include "GLContextSkia.h"
#include "SurfaceTypes.h"
using mozilla::gl::GLContext;
using mozilla::gl::GLContextProvider;
#endif
#ifdef XP_WIN
@ -440,15 +445,20 @@ public:
CanvasRenderingContext2DUserData* self =
static_cast<CanvasRenderingContext2DUserData*>(aData);
CanvasRenderingContext2D* context = self->mContext;
if (self->mContext && context->mGLContext) {
if (self->mContext->mTarget != nullptr) {
// Since SkiaGL default to store drawing command until flush
// We will have to flush it before present.
self->mContext->mTarget->Flush();
}
context->mGLContext->MakeCurrent();
context->mGLContext->PublishFrame();
if (!context)
return;
GLContext* glContext = static_cast<GLContext*>(context->mTarget->GetGLContext());
if (!glContext)
return;
if (context->mTarget) {
// Since SkiaGL default to store drawing command until flush
// We will have to flush it before present.
context->mTarget->Flush();
}
glContext->MakeCurrent();
glContext->PublishFrame();
}
#endif
@ -547,6 +557,10 @@ CanvasRenderingContext2D::CanvasRenderingContext2D()
{
sNumLivingContexts++;
SetIsDOMBinding();
#if USE_SKIA_GPU
mForceSoftware = false;
#endif
}
CanvasRenderingContext2D::~CanvasRenderingContext2D()
@ -560,6 +574,12 @@ CanvasRenderingContext2D::~CanvasRenderingContext2D()
if (!sNumLivingContexts) {
NS_IF_RELEASE(sErrorTarget);
}
#if USE_SKIA_GPU
std::vector<CanvasRenderingContext2D*>::iterator iter = std::find(DemotableContexts().begin(), DemotableContexts().end(), this);
if (iter != DemotableContexts().end())
DemotableContexts().erase(iter);
#endif
}
JSObject*
@ -757,6 +777,62 @@ CanvasRenderingContext2D::RedrawUser(const gfxRect& r)
Redraw(newr);
}
#if USE_SKIA_GPU
void CanvasRenderingContext2D::Demote()
{
if (!IsTargetValid() || mForceSoftware)
return;
RefPtr<SourceSurface> snapshot = mTarget->Snapshot();
RefPtr<DrawTarget> oldTarget = mTarget;
mTarget = nullptr;
mForceSoftware = true;
// Recreate target, now demoted to software only
EnsureTarget();
if (!IsTargetValid())
return;
// Put back the content from the old DrawTarget
mgfx::Rect r(0, 0, mWidth, mHeight);
mTarget->DrawSurface(snapshot, r, r);
}
std::vector<CanvasRenderingContext2D*>&
CanvasRenderingContext2D::DemotableContexts()
{
static std::vector<CanvasRenderingContext2D*> contexts;
return contexts;
}
void
CanvasRenderingContext2D::DemoteOldestContextIfNecessary()
{
#ifdef MOZ_GFX_OPTIMIZE_MOBILE
const size_t kMaxContexts = 2;
#else
const size_t kMaxContexts = 16;
#endif
std::vector<CanvasRenderingContext2D*>& contexts = DemotableContexts();
if (contexts.size() < kMaxContexts)
return;
CanvasRenderingContext2D* oldest = contexts.front();
contexts.erase(contexts.begin());
oldest->Demote();
}
void
CanvasRenderingContext2D::AddDemotableContext(CanvasRenderingContext2D* context)
{
DemotableContexts().push_back(context);
}
#endif
void
CanvasRenderingContext2D::EnsureTarget()
{
@ -794,19 +870,25 @@ CanvasRenderingContext2D::EnsureTarget()
}
#endif
mGLContext = mozilla::gl::GLContextProvider::CreateOffscreen(gfxIntSize(size.width,
size.height),
caps,
mozilla::gl::GLContext::ContextFlagsNone);
DemoteOldestContextIfNecessary();
if (mGLContext) {
mTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForFBO(0, mGLContext, size, format);
nsRefPtr<GLContext> glContext;
if (!mForceSoftware) {
glContext = GLContextProvider::CreateOffscreen(gfxIntSize(size.width, size.height),
caps, GLContext::ContextFlagsNone);
}
if (glContext) {
SkAutoTUnref<GrGLInterface> i(CreateGrGLInterfaceFromGLContext(glContext));
mTarget = Factory::CreateDrawTargetSkiaWithGLContextAndGrGLInterface(glContext, i, size, format);
AddDemotableContext(this);
} else {
mTarget = layerManager->CreateDrawTarget(size, format);
}
} else
#endif
mTarget = layerManager->CreateDrawTarget(size, format);
mTarget = layerManager->CreateDrawTarget(size, format);
} else {
mTarget = gfxPlatform::GetPlatform()->CreateOffscreenDrawTarget(size, format);
}
@ -891,6 +973,7 @@ CanvasRenderingContext2D::InitializeWithSurface(nsIDocShell *shell,
SetDimensions(width, height);
mTarget = gfxPlatform::GetPlatform()->
CreateDrawTargetForSurface(surface, IntSize(width, height));
if (!mTarget) {
EnsureErrorTarget();
mTarget = sErrorTarget;
@ -3823,10 +3906,11 @@ CanvasRenderingContext2D::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer::Data data;
#ifdef USE_SKIA_GPU
if (mGLContext) {
GLContext* glContext = static_cast<GLContext*>(mTarget->GetGLContext());
if (glContext) {
canvasLayer->SetPreTransactionCallback(
CanvasRenderingContext2DUserData::PreTransactionCallback, userData);
data.mGLContext = mGLContext;
data.mGLContext = glContext;
} else
#endif
{

Просмотреть файл

@ -556,6 +556,19 @@ protected:
return CurrentState().font;
}
#if USE_SKIA_GPU
// Recreate the DrawTarget in software mode
void Demote();
static std::vector<CanvasRenderingContext2D*>& DemotableContexts();
static void DemoteOldestContextIfNecessary();
static void AddDemotableContext(CanvasRenderingContext2D* context);
// Do not use GL
bool mForceSoftware;
#endif
// Member vars
int32_t mWidth, mHeight;
@ -633,11 +646,6 @@ protected:
uint32_t mInvalidateCount;
static const uint32_t kCanvasMaxInvalidateCount = 100;
#ifdef USE_SKIA_GPU
nsRefPtr<gl::GLContext> mGLContext;
#endif
/**
* Returns true if a shadow should be drawn along with a
* drawing operation.

Просмотреть файл

@ -1007,22 +1007,12 @@ WebGLContext::InitAndValidateGL()
// specifically enabled on desktop GLSL.
gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
// we don't do the following glEnable(GL_POINT_SPRITE) on ATI cards on Windows, because bug 602183 shows that it causes
// crashes in the ATI/Windows driver; and point sprites on ATI seem like a lost cause anyway, see
// http://www.gamedev.net/community/forums/topic.asp?topic_id=525643
// Also, if the ATI/Windows driver implements a recent GL spec version, this shouldn't be needed anyway.
#ifdef XP_WIN
if (!(gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLContext::VendorATI))
#else
if (true)
#endif
{
// gl_PointCoord is always available in ES2 GLSL and in newer desktop GLSL versions, but apparently
// not in OpenGL 2 and apparently not (due to a driver bug) on certain NVIDIA setups. See:
// http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=261472
gl->fEnable(LOCAL_GL_POINT_SPRITE);
}
// gl_PointCoord is always available in ES2 GLSL and in newer desktop GLSL versions, but apparently
// not in OpenGL 2 and apparently not (due to a driver bug) on certain NVIDIA setups. See:
// http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=261472
// Note that this used to cause crashes on old ATI drivers... hopefully not a significant
// problem anymore. See bug 602183.
gl->fEnable(LOCAL_GL_POINT_SPRITE);
}
#ifdef XP_MACOSX

Просмотреть файл

@ -40,40 +40,14 @@ MOCHITEST_FILES = \
test_2d.composite.canvas.destination-in.html \
test_2d.composite.canvas.source-in.html \
test_2d.composite.canvas.source-out.html \
test_2d.composite.canvas.multiply.html \
test_2d.composite.canvas.screen.html \
test_2d.composite.canvas.overlay.html \
test_2d.composite.canvas.darken.html \
test_2d.composite.canvas.lighten.html \
test_2d.composite.canvas.color-dodge.html \
test_2d.composite.canvas.color-burn.html \
test_2d.composite.canvas.hard-light.html \
test_2d.composite.canvas.soft-light.html \
test_2d.composite.canvas.difference.html \
test_2d.composite.canvas.exclusion.html \
test_2d.composite.canvas.hue.html \
test_2d.composite.canvas.saturation.html \
test_2d.composite.canvas.color.html \
test_2d.composite.canvas.luminosity.html \
test_2d.composite.image.destination-atop.html \
test_2d.composite.image.destination-in.html \
test_2d.composite.image.source-in.html \
test_2d.composite.image.source-out.html \
test_2d.composite.solid.multiply.html \
test_2d.composite.solid.screen.html \
test_2d.composite.solid.overlay.html \
test_2d.composite.solid.darken.html \
test_2d.composite.solid.lighten.html \
test_2d.composite.solid.color-dodge.html \
test_2d.composite.solid.color-burn.html \
test_2d.composite.solid.hard-light.html \
test_2d.composite.solid.soft-light.html \
test_2d.composite.solid.difference.html \
test_2d.composite.solid.exclusion.html \
test_2d.composite.solid.hue.html \
test_2d.composite.solid.saturation.html \
test_2d.composite.solid.color.html \
test_2d.composite.solid.luminosity.html \
test_2d.composite.uncovered.image.destination-in.html \
test_2d.composite.uncovered.image.source-in.html \
test_2d.composite.uncovered.image.source-out.html \
@ -109,11 +83,48 @@ MOCHITEST_FILES = \
test_bug866575.html \
test_drawImage_edge_cases.html \
test_drawImage_document_domain.html \
test_mozDashOffset.html \
test_mozDashOffset.html \
file_drawImage_document_domain.html \
test_windingRuleUndefined.html \
$(NULL)
ifneq ($(MOZ_WIDGET_TOOLKIT), android)
ifneq ($(MOZ_WIDGET_TOOLKIT), gonk)
# SkiaGL on Android/Gonk does not implement these composite ops yet
MOCHITEST_FILES += \
test_2d.composite.canvas.color-burn.html \
test_2d.composite.canvas.color-dodge.html \
test_2d.composite.canvas.darken.html \
test_2d.composite.canvas.difference.html \
test_2d.composite.canvas.exclusion.html \
test_2d.composite.canvas.hue.html \
test_2d.composite.canvas.lighten.html \
test_2d.composite.canvas.luminosity.html \
test_2d.composite.canvas.multiply.html \
test_2d.composite.canvas.overlay.html \
test_2d.composite.canvas.saturation.html \
test_2d.composite.canvas.screen.html \
test_2d.composite.solid.color-burn.html \
test_2d.composite.solid.color-dodge.html \
test_2d.composite.solid.color.html \
test_2d.composite.solid.darken.html \
test_2d.composite.solid.difference.html \
test_2d.composite.solid.exclusion.html \
test_2d.composite.solid.hue.html \
test_2d.composite.solid.lighten.html \
test_2d.composite.solid.luminosity.html \
test_2d.composite.solid.multiply.html \
test_2d.composite.solid.overlay.html \
test_2d.composite.solid.saturation.html \
test_2d.composite.solid.screen.html \
test_2d.composite.solid.soft-light.html \
$(NULL)
endif
endif
ifneq (1_Linux,$(MOZ_SUITE)_$(OS_ARCH))
# This test fails in Suite on Linux for some reason, disable it there
MOCHITEST_FILES += test_2d.composite.uncovered.image.destination-atop.html
@ -140,8 +151,11 @@ MOCHITEST_FILES += \
test_2d.line.join.parallel.html \
$(NULL)
ifneq ($(MOZ_WIDGET_TOOLKIT), android)
ifneq ($(MOZ_WIDGET_TOOLKIT), gonk)
# This is an issue with Quartz's handling of radial gradients and some numeric
# imprecision that results in errors here.
# imprecision that results in errors here. SkiaGL (on Android/Gonk) also has
# a similar problem.
MOCHITEST_FILES += \
test_2d.gradient.radial.inside2.html \
test_2d.gradient.radial.inside3.html \
@ -149,6 +163,8 @@ MOCHITEST_FILES += \
test_2d.gradient.radial.cone.front.html \
test_2d.gradient.radial.cone.top.html \
$(NULL)
endif
endif
# This is another Quartz bug -- closed paths that don't lie fully within the
# destination bounds seem to have problems with the BEVEL/SQUARE join/cap combo.

Просмотреть файл

@ -51,6 +51,17 @@ function IsAzureSkia() {
return enabled;
}
function IsAcceleratedSkia() {
var enabled = false;
try {
var props = Cc["@mozilla.org/gfx/info;1"].getService(SpecialPowers.Ci.nsIGfxInfo).getInfo();
enabled = props.AzureCanvasBackend == "skia" && props.AzureSkiaAccelerated;
} catch(e) { }
return enabled;
}
function IsAzureCairo() {
var enabled = false;
@ -6641,6 +6652,9 @@ isPixel(ctx, 98,48, 0,255,0,255, 0);
function test_2d_gradient_radial_inside1() {
if (IsAcceleratedSkia())
return;
var canvas = document.getElementById('c240');
var ctx = canvas.getContext('2d');

Просмотреть файл

@ -50,6 +50,7 @@ namespace mozilla {
namespace dom {
class MediaError;
class MediaSource;
class HTMLMediaElement : public nsGenericHTMLElement,
public nsIObserver,
@ -867,6 +868,9 @@ protected:
// Holds a reference to the MediaStreamListener attached to mSrcStream.
nsRefPtr<StreamListener> mSrcStreamListener;
// Holds a reference to the MediaSource supplying data for playback.
nsRefPtr<MediaSource> mMediaSource;
// Holds a reference to the first channel we open to the media resource.
// Once the decoder is created, control over the channel passes to the
// decoder, and we null out this reference. We must store this in case

Просмотреть файл

@ -10,6 +10,8 @@
#include "mozilla/Attributes.h"
#include "nsIDOMHTMLVideoElement.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/VideoPlaybackQuality.h"
#include "nsPerformance.h"
namespace mozilla {
namespace dom {
@ -114,6 +116,8 @@ public:
void NotifyOwnerDocumentActivityChanged() MOZ_OVERRIDE;
already_AddRefed<dom::VideoPlaybackQuality> VideoPlaybackQuality();
protected:
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;

Просмотреть файл

@ -66,6 +66,7 @@
#include "MediaStreamGraph.h"
#include "nsIScriptError.h"
#include "nsHostObjectProtocolHandler.h"
#include "mozilla/dom/MediaSource.h"
#include "MediaMetadataManager.h"
#include "AudioChannelService.h"
@ -402,6 +403,7 @@ NS_IMPL_ADDREF_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_RELEASE_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer)
@ -423,6 +425,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
tmp->EndSrcMediaStreamPlayback();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcAttrStream)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourcePointer)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
@ -590,6 +593,10 @@ void HTMLMediaElement::AbortExistingLoads()
if (mSrcStream) {
EndSrcMediaStreamPlayback();
}
if (mMediaSource) {
mMediaSource->DetachElement();
mMediaSource = nullptr;
}
if (mAudioStream) {
mAudioStream->Shutdown();
mAudioStream = nullptr;
@ -1111,6 +1118,30 @@ nsresult HTMLMediaElement::LoadResource()
return NS_OK;
}
if (IsMediaSourceURI(mLoadingSrc)) {
nsRefPtr<MediaSource> source;
rv = NS_GetSourceForMediaSourceURI(mLoadingSrc, getter_AddRefs(source));
if (NS_FAILED(rv)) {
nsCString specUTF8;
mLoadingSrc->GetSpec(specUTF8);
NS_ConvertUTF8toUTF16 spec(specUTF8);
const PRUnichar* params[] = { spec.get() };
ReportLoadError("MediaLoadInvalidURI", params, ArrayLength(params));
return rv;
}
mMediaSource = source.forget();
if (!mMediaSource->AttachElement(this)) {
// XXX(kinetik): Handle failure: run "If the media data cannot be
// fetched at all, due to network errors, causing the user agent to
// give up trying to fetch the resource" section of resource fetch
// algorithm.
return NS_ERROR_FAILURE;
}
// XXX(kinetik): Bug 881512. Wire this up properly; return from here (as
// MediaStreams setup does) rather than relying on mediasource->channel
// conversion.
}
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
// check for a Content Security Policy to pass down to the channel
@ -1357,7 +1388,17 @@ already_AddRefed<TimeRanges>
HTMLMediaElement::Seekable() const
{
nsRefPtr<TimeRanges> ranges = new TimeRanges();
if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
if (mMediaSource) {
double duration = mMediaSource->Duration();
if (IsNaN(duration)) {
// Return empty range.
} else if (duration > 0 && IsInfinite(duration)) {
nsRefPtr<TimeRanges> bufferedRanges = Buffered();
ranges->Add(0, bufferedRanges->GetFinalEndTime());
} else {
ranges->Add(0, duration);
}
} else if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
mDecoder->GetSeekable(ranges);
}
return ranges.forget();
@ -1942,6 +1983,10 @@ HTMLMediaElement::~HTMLMediaElement()
if (mSrcStream) {
EndSrcMediaStreamPlayback();
}
if (mMediaSource) {
mMediaSource->DetachElement();
mMediaSource = nullptr;
}
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
"Destroyed media element should no longer be in element table");
@ -3494,7 +3539,9 @@ already_AddRefed<TimeRanges>
HTMLMediaElement::Buffered() const
{
nsRefPtr<TimeRanges> ranges = new TimeRanges();
if (mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING && mDecoder) {
if (mMediaSource) {
mMediaSource->GetBuffered(ranges);
} else if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
// If GetBuffered fails we ignore the error result and just return the
// time ranges we found up till the error.
mDecoder->GetBuffered(ranges);

Просмотреть файл

@ -258,6 +258,33 @@ HTMLVideoElement::NotifyOwnerDocumentActivityChanged()
WakeLockUpdate();
}
already_AddRefed<dom::VideoPlaybackQuality>
HTMLVideoElement::VideoPlaybackQuality()
{
nsPIDOMWindow* window = OwnerDoc()->GetInnerWindow();
NS_ENSURE_TRUE(window, nullptr);
nsPerformance* perf = window->GetPerformance();
NS_ENSURE_TRUE(perf, nullptr);
DOMHighResTimeStamp creationTime = perf->GetDOMTiming()->TimeStampToDOMHighRes(TimeStamp::Now());
uint64_t totalFrames = 0;
uint64_t droppedFrames = 0;
uint64_t corruptedFrames = 0;
double playbackJitter = 0.0;
if (mDecoder && sVideoStatsEnabled) {
MediaDecoder::FrameStatistics& stats = mDecoder->GetFrameStatistics();
totalFrames = stats.GetParsedFrames();
droppedFrames = totalFrames - stats.GetPresentedFrames();
corruptedFrames = totalFrames - stats.GetDecodedFrames();
playbackJitter = stats.GetPlaybackJitter();
}
nsRefPtr<dom::VideoPlaybackQuality> playbackQuality =
new dom::VideoPlaybackQuality(this, creationTime, totalFrames, droppedFrames,
corruptedFrames, playbackJitter);
return playbackQuality.forget();
}
void
HTMLVideoElement::WakeLockCreate()
{

Просмотреть файл

@ -818,6 +818,7 @@ public:
FrameStatistics() :
mReentrantMonitor("MediaDecoder::FrameStats"),
mPlaybackJitter(0.0),
mParsedFrames(0),
mDecodedFrames(0),
mPresentedFrames(0) {}
@ -844,6 +845,11 @@ public:
return mPresentedFrames;
}
double GetPlaybackJitter() {
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
return mPlaybackJitter;
}
// Increments the parsed and decoded frame counters by the passed in counts.
// Can be called on any thread.
void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded) {
@ -861,11 +867,22 @@ public:
++mPresentedFrames;
}
// Tracks the sum of display errors.
// Can be called on any thread.
void NotifyPlaybackJitter(double aDisplayError) {
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mPlaybackJitter += aDisplayError;
}
private:
// ReentrantMonitor to protect access of playback statistics.
ReentrantMonitor mReentrantMonitor;
// Sum of display duration error.
// Access protected by mStatsReentrantMonitor.
double mPlaybackJitter;
// Number of frames parsed and demuxed from media.
// Access protected by mStatsReentrantMonitor.
uint32_t mParsedFrames;

Просмотреть файл

@ -2535,8 +2535,12 @@ void MediaDecoderStateMachine::AdvanceFrame()
ScheduleStateMachine();
return;
}
mDecoder->GetFrameStatistics().NotifyPresentedFrame();
MediaDecoder::FrameStatistics& frameStats = mDecoder->GetFrameStatistics();
frameStats.NotifyPresentedFrame();
remainingTime = currentFrame->mEndTime - clock_time;
int64_t frameDuration = currentFrame->mEndTime - currentFrame->mTime;
double displayError = fabs(double(frameDuration - remainingTime) / USECS_PER_S);
frameStats.NotifyPlaybackJitter(displayError);
currentFrame = nullptr;
}

Просмотреть файл

@ -0,0 +1,53 @@
/* -*- 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 "VideoPlaybackQuality.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/VideoPlaybackQualityBinding.h"
#include "nsContentUtils.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "MediaDecoder.h"
namespace mozilla {
namespace dom {
VideoPlaybackQuality::VideoPlaybackQuality(HTMLMediaElement* aElement,
DOMHighResTimeStamp aCreationTime,
uint64_t aTotalFrames,
uint64_t aDroppedFrames,
uint64_t aCorruptedFrames,
double aPlaybackJitter)
: mElement(aElement)
, mCreationTime(aCreationTime)
, mTotalFrames(aTotalFrames)
, mDroppedFrames(aDroppedFrames)
, mCorruptedFrames(aCorruptedFrames)
, mPlaybackJitter(aPlaybackJitter)
{
SetIsDOMBinding();
}
HTMLMediaElement*
VideoPlaybackQuality::GetParentObject() const
{
return mElement;
}
JSObject*
VideoPlaybackQuality::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aScope)
{
return VideoPlaybackQualityBinding::Wrap(aCx, aScope, this);
}
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VideoPlaybackQuality, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VideoPlaybackQuality, Release)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(VideoPlaybackQuality, mElement)
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_VideoPlaybackQuality_h_
#define mozilla_dom_VideoPlaybackQuality_h_
#include "mozilla/dom/HTMLMediaElement.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMNavigationTiming.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class VideoPlaybackQuality MOZ_FINAL : public nsWrapperCache
{
public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VideoPlaybackQuality)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VideoPlaybackQuality)
VideoPlaybackQuality(HTMLMediaElement* aElement, DOMHighResTimeStamp aCreationTime,
uint64_t aTotalFrames, uint64_t aDroppedFrames,
uint64_t aCorruptedFrames, double aPlaybackJitter);
HTMLMediaElement* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
DOMHighResTimeStamp CreationTime() const
{
return mCreationTime;
}
uint64_t TotalVideoFrames()
{
return mTotalFrames;
}
uint64_t DroppedVideoFrames()
{
return mDroppedFrames;
}
uint64_t CorruptedVideoFrames()
{
return mCorruptedFrames;
}
double PlaybackJitter()
{
return mPlaybackJitter;
}
private:
nsRefPtr<HTMLMediaElement> mElement;
DOMHighResTimeStamp mCreationTime;
uint64_t mTotalFrames;
uint64_t mDroppedFrames;
uint64_t mCorruptedFrames;
double mPlaybackJitter;
};
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_VideoPlaybackQuality_h_ */

Просмотреть файл

@ -0,0 +1,35 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_ASYNCEVENTRUNNER_H_
#define MOZILLA_ASYNCEVENTRUNNER_H_
#include "nsThreadUtils.h"
namespace mozilla {
template <typename T>
class AsyncEventRunnner : public nsRunnable
{
public:
AsyncEventRunnner(T* aTarget, const char* aName)
: mTarget(aTarget)
, mName(aName)
{}
NS_IMETHOD Run()
{
mTarget->DispatchSimpleEvent(mName);
return NS_OK;
}
private:
nsRefPtr<T> mTarget;
const char* mName;
};
} // namespace mozilla
#endif /* MOZILLA_ASYNCEVENTRUNNER_H_ */

Просмотреть файл

@ -0,0 +1,18 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
FAIL_ON_WARNINGS := 1
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = gkconmediasource_s
LIBXUL_LIBRARY = 1
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,396 @@
/* -*- 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 "MediaSource.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "MediaSourceInputAdapter.h"
#include "SourceBuffer.h"
#include "SourceBufferList.h"
#include "nsContentUtils.h"
#ifdef PR_LOGGING
PRLogModuleInfo* gMediaSourceLog;
#define LOG(type, msg) PR_LOG(gMediaSourceLog, type, msg)
#else
#define LOG(type, msg)
#endif
namespace mozilla {
namespace dom {
already_AddRefed<nsIInputStream>
MediaSource::CreateInternalStream()
{
nsRefPtr<MediaSourceInputAdapter> adapter = new MediaSourceInputAdapter(this);
mAdapters.AppendElement(adapter);
return adapter.forget();
}
/* static */ already_AddRefed<MediaSource>
MediaSource::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aGlobal.Get());
if (!window) {
aRv.Throw(NS_ERROR_UNEXPECTED);
return nullptr;
}
nsRefPtr<MediaSource> mediaSource = new MediaSource(window);
return mediaSource.forget();
}
SourceBufferList*
MediaSource::SourceBuffers()
{
MOZ_ASSERT_IF(mReadyState == MediaSourceReadyState::Closed, mSourceBuffers->IsEmpty());
return mSourceBuffers;
}
SourceBufferList*
MediaSource::ActiveSourceBuffers()
{
MOZ_ASSERT_IF(mReadyState == MediaSourceReadyState::Closed, mActiveSourceBuffers->IsEmpty());
return mActiveSourceBuffers;
}
MediaSourceReadyState
MediaSource::ReadyState()
{
return mReadyState;
}
double
MediaSource::Duration()
{
if (mReadyState == MediaSourceReadyState::Closed) {
return UnspecifiedNaN();
}
return mDuration;
}
void
MediaSource::SetDuration(double aDuration, ErrorResult& aRv)
{
if (aDuration < 0 || IsNaN(aDuration)) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return;
}
if (mReadyState != MediaSourceReadyState::Open ||
mSourceBuffers->AnyUpdating()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
DurationChange(aDuration, aRv);
}
already_AddRefed<SourceBuffer>
MediaSource::AddSourceBuffer(const nsAString& aType, ErrorResult& aRv)
{
if (!IsTypeSupportedInternal(aType, aRv)) {
return nullptr;
}
// TODO: Temporary limit until multiple decoders are supported. Bug 881512.
if (mSourceBuffers->Length() >= 1) {
aRv.Throw(NS_ERROR_DOM_QUOTA_EXCEEDED_ERR);
return nullptr;
}
if (mReadyState != MediaSourceReadyState::Open) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
mContentType = aType;
nsRefPtr<SourceBuffer> sourceBuffer = new SourceBuffer(this);
mSourceBuffers->Append(sourceBuffer);
sourceBuffer->Attach();
return sourceBuffer.forget();
}
void
MediaSource::RemoveSourceBuffer(SourceBuffer& aSourceBuffer, ErrorResult& aRv)
{
SourceBuffer* sourceBuffer = &aSourceBuffer;
if (!mSourceBuffers->Contains(sourceBuffer)) {
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
return;
}
if (sourceBuffer->Updating()) {
// TODO:
// abort stream append loop (if running)
// set updating to false
// fire "abort" at sourceBuffer
// fire "updateend" at sourceBuffer
}
// TODO:
// For all sourceBuffer audioTracks, videoTracks, textTracks:
// set sourceBuffer to null
// remove sourceBuffer video, audio, text Tracks from MediaElement tracks
// remove sourceBuffer video, audio, text Tracks and fire "removetrack" at affected lists
// fire "removetrack" at modified MediaElement track lists
// If removed enabled/selected, fire "change" at affected MediaElement list.
if (mActiveSourceBuffers->Contains(sourceBuffer)) {
mActiveSourceBuffers->Remove(sourceBuffer);
}
mSourceBuffers->Remove(sourceBuffer);
sourceBuffer->Detach();
// TODO: Free all resources associated with sourceBuffer
}
void
MediaSource::EndOfStream(const Optional<MediaSourceEndOfStreamError>& aError, ErrorResult& aRv)
{
if (mReadyState != MediaSourceReadyState::Open ||
mSourceBuffers->AnyUpdating()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
EndOfStreamInternal(aError, aRv);
}
/* static */ bool
MediaSource::IsTypeSupported(const GlobalObject& aGlobal, const nsAString& aType)
{
ErrorResult unused;
return IsTypeSupportedInternal(aType, unused);
}
void
MediaSource::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
MonitorAutoLock mon(mMonitor);
LOG(PR_LOG_DEBUG, ("%p Append(ArrayBuffer=%u) mData=%u", this, aLength, mData.Length()));
mData.AppendElements(aData, aLength);
NotifyListeners();
}
bool
MediaSource::AttachElement(HTMLMediaElement* aElement)
{
LOG(PR_LOG_DEBUG, ("%p Attaching element %p", this, aElement));
MOZ_ASSERT(aElement);
mElement = aElement;
if (mReadyState != MediaSourceReadyState::Closed) {
return false;
}
SetReadyState(MediaSourceReadyState::Open);
return true;
}
void
MediaSource::DetachElement()
{
LOG(PR_LOG_DEBUG, ("%p Detaching element %p", this, mElement.get()));
MOZ_ASSERT(mElement);
mElement = nullptr;
mDuration = UnspecifiedNaN();
mActiveSourceBuffers->Clear();
mSourceBuffers->DetachAndClear();
SetReadyState(MediaSourceReadyState::Closed);
for (uint32_t i = 0; i < mAdapters.Length(); ++i) {
mAdapters[i]->Close();
}
mAdapters.Clear();
}
MediaSource::MediaSource(nsPIDOMWindow* aWindow)
: nsDOMEventTargetHelper(aWindow)
, mDuration(UnspecifiedNaN())
, mMonitor("mozilla::dom::MediaSource::mMonitor")
, mReadyState(MediaSourceReadyState::Closed)
{
mSourceBuffers = new SourceBufferList(this);
mActiveSourceBuffers = new SourceBufferList(this);
#ifdef PR_LOGGING
if (!gMediaSourceLog) {
gMediaSourceLog = PR_NewLogModule("MediaSource");
}
#endif
}
void
MediaSource::SetReadyState(MediaSourceReadyState aState)
{
MOZ_ASSERT(aState != mReadyState);
MonitorAutoLock mon(mMonitor);
NotifyListeners();
if ((mReadyState == MediaSourceReadyState::Closed ||
mReadyState == MediaSourceReadyState::Ended) &&
aState == MediaSourceReadyState::Open) {
mReadyState = aState;
QueueAsyncSimpleEvent("sourceopen");
return;
}
if (mReadyState == MediaSourceReadyState::Open &&
aState == MediaSourceReadyState::Ended) {
mReadyState = aState;
QueueAsyncSimpleEvent("sourceended");
return;
}
if ((mReadyState == MediaSourceReadyState::Open ||
mReadyState == MediaSourceReadyState::Ended) &&
aState == MediaSourceReadyState::Closed) {
mReadyState = aState;
QueueAsyncSimpleEvent("sourceclose");
return;
}
NS_WARNING("Invalid MediaSource readyState transition");
}
void
MediaSource::GetBuffered(TimeRanges* aRanges)
{
if (mActiveSourceBuffers->Length() == 0) {
return;
}
// TODO: Implement intersection computation.
}
void
MediaSource::DispatchSimpleEvent(const char* aName)
{
LOG(PR_LOG_DEBUG, ("%p Dispatching event %s to MediaSource", this, aName));
DispatchTrustedEvent(NS_ConvertUTF8toUTF16(aName));
}
void
MediaSource::QueueAsyncSimpleEvent(const char* aName)
{
LOG(PR_LOG_DEBUG, ("%p Queuing event %s to MediaSource", this, aName));
nsCOMPtr<nsIRunnable> event = new AsyncEventRunnner<MediaSource>(this, aName);
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
void
MediaSource::NotifyListeners()
{
for (uint32_t i = 0; i < mAdapters.Length(); ++i) {
mAdapters[i]->NotifyListener();
}
}
void
MediaSource::DurationChange(double aNewDuration, ErrorResult& aRv)
{
if (mDuration == aNewDuration) {
return;
}
double oldDuration = mDuration;
mDuration = aNewDuration;
if (aNewDuration < oldDuration) {
mSourceBuffers->Remove(aNewDuration, oldDuration, aRv);
if (aRv.Failed()) {
return;
}
}
// TODO: If partial audio frames/text cues exist, clamp duration based on mSourceBuffers.
// TODO: Update media element's duration and run element's duration change algorithm.
}
void
MediaSource::EndOfStreamInternal(const Optional<MediaSourceEndOfStreamError>& aError, ErrorResult& aRv)
{
SetReadyState(MediaSourceReadyState::Ended);
if (!aError.WasPassed()) {
// TODO:
// Run duration change algorithm.
// DurationChange(highestDurationOfSourceBuffers, aRv);
// if (aRv.Failed()) {
// return;
// }
// Notify media element that all data is now available.
return;
}
switch (aError.Value()) {
case MediaSourceEndOfStreamError::Network:
// TODO: If media element has a readyState of:
// HAVE_NOTHING -> run resource fetch algorithm
// > HAVE_NOTHING -> run "interrupted" steps of resource fetch
break;
case MediaSourceEndOfStreamError::Decode:
// TODO: If media element has a readyState of:
// HAVE_NOTHING -> run "unsupported" steps of resource fetch
// > HAVE_NOTHING -> run "corrupted" steps of resource fetch
break;
default:
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
}
}
static const char* const gMediaSourceTypes[5] = {
"video/webm",
"audio/webm",
"video/mp4",
"audio/mp4",
nullptr
};
/* static */ bool
MediaSource::IsTypeSupportedInternal(const nsAString& aType, ErrorResult& aRv)
{
if (aType.IsEmpty()) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return false;
}
// TODO: Further restrict this to formats in the spec.
nsContentTypeParser parser(aType);
nsAutoString mimeType;
nsresult rv = parser.GetType(mimeType);
if (NS_FAILED(rv)) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return false;
}
bool found = false;
for (uint32_t i = 0; gMediaSourceTypes[i]; ++i) {
if (mimeType.EqualsASCII(gMediaSourceTypes[i])) {
found = true;
break;
}
}
if (!found) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return false;
}
// Check aType against HTMLMediaElement list of MIME types. Since we've
// already restricted the container format, this acts as a specific check
// of any specified "codecs" parameter of aType.
if (HTMLMediaElement::GetCanPlay(aType) == CANPLAY_NO) {
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
return false;
}
return true;
}
nsPIDOMWindow*
MediaSource::GetParentObject() const
{
return GetOwner();
}
JSObject*
MediaSource::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return MediaSourceBinding::Wrap(aCx, aScope, this);
}
NS_IMPL_CYCLE_COLLECTION_INHERITED_4(MediaSource, nsDOMEventTargetHelper,
mSourceBuffers, mActiveSourceBuffers, mAdapters, mElement)
NS_IMPL_ADDREF_INHERITED(MediaSource, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(MediaSource, nsDOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaSource)
NS_INTERFACE_MAP_ENTRY(mozilla::dom::MediaSource)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,134 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_MediaSource_h_
#define mozilla_dom_MediaSource_h_
#include "AsyncEventRunner.h"
#include "mozilla/Attributes.h"
#include "mozilla/Monitor.h"
#include "mozilla/dom/MediaSourceBinding.h"
#include "mozilla/dom/TypedArray.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
#include "nsWrapperCache.h"
#include "nscore.h"
namespace mozilla {
namespace dom {
class HTMLMediaElement;
class MediaSourceInputAdapter;
class SourceBufferList;
class SourceBuffer;
class TimeRanges;
#define MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID \
{ 0x3839d699, 0x22c5, 0x439f, \
{ 0x94, 0xca, 0x0e, 0x0b, 0x26, 0xf9, 0xca, 0xbf } }
class MediaSource MOZ_FINAL : public nsDOMEventTargetHelper
{
public:
/** WebIDL Methods. */
static already_AddRefed<MediaSource> Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
SourceBufferList* SourceBuffers();
SourceBufferList* ActiveSourceBuffers();
MediaSourceReadyState ReadyState();
double Duration();
void SetDuration(double aDuration, ErrorResult& aRv);
already_AddRefed<SourceBuffer> AddSourceBuffer(const nsAString& aType, ErrorResult& aRv);
void RemoveSourceBuffer(SourceBuffer& aSourceBuffer, ErrorResult& aRv);
void EndOfStream(const Optional<MediaSourceEndOfStreamError>& aError, ErrorResult& aRv);
static bool IsTypeSupported(const GlobalObject& aGlobal, const nsAString& aType);
/** End WebIDL Methods. */
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaSource, nsDOMEventTargetHelper)
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID)
nsPIDOMWindow* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
const nsString& GetType()
{
return mContentType;
}
already_AddRefed<nsIInputStream> CreateInternalStream();
void AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv);
// Semi-private, for MediaSourceInputAdapter only.
nsTArray<uint8_t> const& GetData()
{
return mData;
}
Monitor& GetMonitor()
{
return mMonitor;
}
bool AppendDone() const
{
return mReadyState == MediaSourceReadyState::Closed;
}
// Attach this MediaSource to MediaElement aElement. Returns false if already attached.
bool AttachElement(HTMLMediaElement* aElement);
void DetachElement();
// Set mReadyState to aState and fire the required events at the MediaSource.
void SetReadyState(MediaSourceReadyState aState);
void GetBuffered(TimeRanges* aRanges);
private:
explicit MediaSource(nsPIDOMWindow* aWindow);
friend class AsyncEventRunnner<MediaSource>;
void DispatchSimpleEvent(const char* aName);
void QueueAsyncSimpleEvent(const char* aName);
void NotifyListeners();
void DurationChange(double aNewDuration, ErrorResult& aRv);
void EndOfStreamInternal(const Optional<MediaSourceEndOfStreamError>& aError, ErrorResult& aRv);
static bool IsTypeSupportedInternal(const nsAString& aType, ErrorResult& aRv);
double mDuration;
nsTArray<nsRefPtr<MediaSourceInputAdapter> > mAdapters;
// Protected by monitor.
nsTArray<uint8_t> mData;
// Protects access to mData.
Monitor mMonitor;
nsRefPtr<SourceBufferList> mSourceBuffers;
nsRefPtr<SourceBufferList> mActiveSourceBuffers;
nsRefPtr<HTMLMediaElement> mElement;
nsString mContentType;
MediaSourceReadyState mReadyState;
};
NS_DEFINE_STATIC_IID_ACCESSOR(MediaSource, MOZILLA_DOM_MEDIASOURCE_IMPLEMENTATION_IID)
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_MediaSource_h_ */

Просмотреть файл

@ -0,0 +1,176 @@
/* -*- 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 "MediaSourceInputAdapter.h"
#include "nsStreamUtils.h"
#include "nsCycleCollectionParticipant.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gMediaSourceLog;
#define LOG(type, msg) PR_LOG(gMediaSourceLog, type, msg)
#else
#define LOG(type, msg)
#endif
namespace mozilla {
namespace dom {
NS_IMETHODIMP
MediaSourceInputAdapter::Close()
{
MonitorAutoLock mon(mMediaSource->GetMonitor());
LOG(PR_LOG_DEBUG, ("%p IA::Close", this));
//MOZ_ASSERT(!mClosed);
mClosed = true;
NotifyListener();
return NS_OK;
}
NS_IMETHODIMP
MediaSourceInputAdapter::Available(uint64_t* aAvailable)
{
MonitorAutoLock mon(mMediaSource->GetMonitor());
if (mClosed) {
LOG(PR_LOG_DEBUG, ("%p IA::Available (closed)", this));
return NS_BASE_STREAM_CLOSED;
}
*aAvailable = Available();
LOG(PR_LOG_DEBUG, ("%p IA::Available available=%llu", this, *aAvailable));
return NS_OK;
}
NS_IMETHODIMP
MediaSourceInputAdapter::Read(char* aBuf, uint32_t aCount, uint32_t* aWriteCount)
{
return ReadSegments(NS_CopySegmentToBuffer, aBuf, aCount, aWriteCount);
}
NS_IMETHODIMP
MediaSourceInputAdapter::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
uint32_t aCount, uint32_t* aWriteCount)
{
MonitorAutoLock mon(mMediaSource->GetMonitor());
uint32_t available = Available();
LOG(PR_LOG_DEBUG, ("%p IA::ReadSegments aCount=%u available=%u appendDone=%d rv=%x",
this, aCount, available, mMediaSource->AppendDone(),
mMediaSource->AppendDone() ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK));
if (available == 0) {
*aWriteCount = 0;
return mMediaSource->AppendDone() ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
}
uint32_t count = std::min(aCount, available);
nsresult rv = aWriter(this, aClosure,
reinterpret_cast<const char*>(&mMediaSource->GetData()[mOffset]),
0, count, aWriteCount);
if (NS_SUCCEEDED(rv)) {
MOZ_ASSERT(*aWriteCount <= count);
mOffset += *aWriteCount;
}
return NS_OK;
}
NS_IMETHODIMP
MediaSourceInputAdapter::IsNonBlocking(bool* aNonBlocking)
{
LOG(PR_LOG_DEBUG, ("%p IA::IsNonBlocking", this));
*aNonBlocking = true;
return NS_OK;
}
NS_IMETHODIMP
MediaSourceInputAdapter::CloseWithStatus(nsresult aStatus)
{
return Close();
}
NS_IMETHODIMP
MediaSourceInputAdapter::AsyncWait(nsIInputStreamCallback* aCallback, uint32_t aFlags,
uint32_t aRequestedCount, nsIEventTarget* aTarget)
{
LOG(PR_LOG_DEBUG, ("%p IA::AsyncWait aCallback=%p aFlags=%u aRequestedCount=%u aTarget=%p",
this, aCallback, aFlags, aRequestedCount, aTarget));
if (aFlags != 0) {
return NS_ERROR_NOT_IMPLEMENTED;
}
if (mCallback || mCallbackTarget) {
return NS_ERROR_UNEXPECTED;
}
mCallback = aCallback;
mCallbackTarget = aTarget;
mNotifyThreshold = aRequestedCount;
if (!aRequestedCount) {
mNotifyThreshold = 1024;
}
NotifyListener();
return NS_OK;
}
void
MediaSourceInputAdapter::NotifyListener()
{
if (!mCallback) {
return;
}
// Don't notify unless more data is available than the threshold, except
// in the case that there's no more data coming.
if (Available() < mNotifyThreshold && !mClosed && !mMediaSource->AppendDone()) {
return;
}
nsCOMPtr<nsIInputStreamCallback> callback;
if (mCallbackTarget) {
callback = NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget);
} else {
callback = mCallback;
}
MOZ_ASSERT(callback);
mCallback = nullptr;
mCallbackTarget = nullptr;
mNotifyThreshold = 0;
LOG(PR_LOG_DEBUG, ("%p IA::NotifyListener", this));
callback->OnInputStreamReady(this);
}
uint64_t
MediaSourceInputAdapter::Available()
{
return mMediaSource->GetData().Length() - mOffset;
}
MediaSourceInputAdapter::~MediaSourceInputAdapter()
{
LOG(PR_LOG_DEBUG, ("%p Destroy input adapter", this));
}
MediaSourceInputAdapter::MediaSourceInputAdapter(MediaSource* aMediaSource)
: mMediaSource(aMediaSource)
, mOffset(0)
, mClosed(false)
{
LOG(PR_LOG_DEBUG, ("%p Create input adapter for %p", this, aMediaSource));
}
NS_IMPL_CYCLE_COLLECTION_1(MediaSourceInputAdapter, mMediaSource)
NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaSourceInputAdapter)
NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaSourceInputAdapter)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(MediaSourceInputAdapter)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
NS_INTERFACE_MAP_ENTRY(nsIAsyncInputStream)
NS_INTERFACE_MAP_END
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MOZILLA_MEDIASOURCEINPUTADAPTER_H_
#define MOZILLA_MEDIASOURCEINPUTADAPTER_H_
#include "nsIAsyncInputStream.h"
#include "nsCycleCollectionParticipant.h"
#include "MediaSource.h"
namespace mozilla {
namespace dom {
class MediaSourceInputAdapter MOZ_FINAL : public nsIAsyncInputStream
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(MediaSourceInputAdapter)
NS_DECL_NSIINPUTSTREAM
NS_DECL_NSIASYNCINPUTSTREAM
MediaSourceInputAdapter(MediaSource* aMediaSource);
~MediaSourceInputAdapter();
void NotifyListener();
private:
uint64_t Available();
nsRefPtr<MediaSource> mMediaSource;
nsCOMPtr<nsIInputStreamCallback> mCallback;
nsCOMPtr<nsIEventTarget> mCallbackTarget;
int64_t mOffset;
uint32_t mNotifyThreshold;
bool mClosed;
};
} // namespace dom
} // namespace mozilla
#endif /* MOZILLA_MEDIASOURCEINPUTADAPTER_H_ */

Просмотреть файл

@ -0,0 +1,249 @@
/* 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 "SourceBuffer.h"
#include "nsContentUtils.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gMediaSourceLog;
#define LOG(type, msg) PR_LOG(gMediaSourceLog, type, msg)
#else
#define LOG(type, msg)
#endif
namespace mozilla {
namespace dom {
void
SourceBuffer::SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv)
{
if (!mAttached || mUpdating) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
mMediaSource->SetReadyState(MediaSourceReadyState::Open);
}
// TODO:: Test append state.
// TODO:: If aMode is "sequence", set sequence start time.
mAppendMode = aMode;
}
void
SourceBuffer::SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv)
{
if (!mAttached || mUpdating) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
mMediaSource->SetReadyState(MediaSourceReadyState::Open);
}
// TODO: Test append state.
// TODO: If aMode is "sequence", set sequence start time.
mTimestampOffset = aTimestampOffset;
}
already_AddRefed<TimeRanges>
SourceBuffer::GetBuffered(ErrorResult& aRv)
{
if (!mAttached) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return nullptr;
}
nsRefPtr<TimeRanges> ranges = new TimeRanges();
// TODO: Populate ranges.
return ranges.forget();
}
void
SourceBuffer::SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv)
{
if (!mAttached || mUpdating) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (aAppendWindowStart < 0 || aAppendWindowStart >= mAppendWindowEnd) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return;
}
mAppendWindowStart = aAppendWindowStart;
}
void
SourceBuffer::SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv)
{
if (!mAttached || mUpdating) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (IsNaN(aAppendWindowEnd) ||
aAppendWindowEnd <= mAppendWindowStart) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return;
}
mAppendWindowEnd = aAppendWindowEnd;
}
void
SourceBuffer::AppendBuffer(ArrayBuffer& aData, ErrorResult& aRv)
{
AppendData(aData.Data(), aData.Length(), aRv);
}
void
SourceBuffer::AppendBuffer(ArrayBufferView& aData, ErrorResult& aRv)
{
AppendData(aData.Data(), aData.Length(), aRv);
}
void
SourceBuffer::Abort(ErrorResult& aRv)
{
if (!mAttached) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (mMediaSource->ReadyState() != MediaSourceReadyState::Open) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (mUpdating) {
// TODO: Abort segment parser loop, buffer append, and stream append loop algorithms.
AbortUpdating();
}
// TODO: Run reset parser algorithm.
// XXX: Need to run these two resets through setters?
mAppendWindowStart = 0;
mAppendWindowEnd = PositiveInfinity();
}
void
SourceBuffer::Remove(double aStart, double aEnd, ErrorResult& aRv)
{
if (aStart < 0 || aStart > mMediaSource->Duration() ||
aEnd <= aStart) {
aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
return;
}
if (!mAttached || mUpdating ||
mMediaSource->ReadyState() != MediaSourceReadyState::Open) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
StartUpdating();
/// TODO: Run coded frame removal algorithm asynchronously (would call StopUpdating()).
StopUpdating();
}
void
SourceBuffer::Attach()
{
MOZ_ASSERT(!mAttached);
mAttached = true;
}
void
SourceBuffer::Detach()
{
MOZ_ASSERT(mAttached);
mAttached = false;
}
SourceBuffer::SourceBuffer(MediaSource* aMediaSource)
: nsDOMEventTargetHelper(aMediaSource->GetParentObject())
, mMediaSource(aMediaSource)
, mAppendWindowStart(0)
, mAppendWindowEnd(PositiveInfinity())
, mTimestampOffset(0)
, mAppendMode(SourceBufferAppendMode::Segments)
, mUpdating(false)
, mAttached(false)
{
MOZ_ASSERT(aMediaSource);
}
MediaSource*
SourceBuffer::GetParentObject() const
{
return mMediaSource;
}
JSObject*
SourceBuffer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SourceBufferBinding::Wrap(aCx, aScope, this);
}
void
SourceBuffer::DispatchSimpleEvent(const char* aName)
{
LOG(PR_LOG_DEBUG, ("%p Dispatching event %s to SourceBuffer", this, aName));
DispatchTrustedEvent(NS_ConvertUTF8toUTF16(aName));
}
void
SourceBuffer::QueueAsyncSimpleEvent(const char* aName)
{
LOG(PR_LOG_DEBUG, ("%p Queuing event %s to SourceBuffer", this, aName));
nsCOMPtr<nsIRunnable> event = new AsyncEventRunnner<SourceBuffer>(this, aName);
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
void
SourceBuffer::StartUpdating()
{
MOZ_ASSERT(!mUpdating);
mUpdating = true;
QueueAsyncSimpleEvent("updatestart");
}
void
SourceBuffer::StopUpdating()
{
MOZ_ASSERT(mUpdating);
mUpdating = false;
QueueAsyncSimpleEvent("update");
QueueAsyncSimpleEvent("updateend");
}
void
SourceBuffer::AbortUpdating()
{
MOZ_ASSERT(mUpdating);
mUpdating = false;
QueueAsyncSimpleEvent("abort");
QueueAsyncSimpleEvent("updateend");
}
void
SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv)
{
if (!mAttached || mUpdating) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
if (mMediaSource->ReadyState() == MediaSourceReadyState::Ended) {
mMediaSource->SetReadyState(MediaSourceReadyState::Open);
}
// TODO: Run coded frame eviction algorithm.
// TODO: Test buffer full flag.
mMediaSource->AppendData(aData, aLength, aRv); // XXX: Appending to input buffer.
StartUpdating();
// TODO: Run buffer append algorithm asynchronously (would call StopUpdating()).
StopUpdating();
}
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(SourceBuffer, nsDOMEventTargetHelper, mMediaSource)
NS_IMPL_ADDREF_INHERITED(SourceBuffer, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(SourceBuffer, nsDOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SourceBuffer)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,115 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SourceBuffer_h_
#define mozilla_dom_SourceBuffer_h_
#include "AsyncEventRunner.h"
#include "MediaSource.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/SourceBufferBinding.h"
#include "mozilla/dom/TimeRanges.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/ErrorResult.h"
#include "nsCOMPtr.h"
#include "nscore.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
class SourceBuffer MOZ_FINAL : public nsDOMEventTargetHelper
{
public:
/** WebIDL Methods. */
SourceBufferAppendMode Mode() const
{
return mAppendMode;
}
void SetMode(SourceBufferAppendMode aMode, ErrorResult& aRv);
bool Updating() const
{
return mUpdating;
}
already_AddRefed<TimeRanges> GetBuffered(ErrorResult& aRv);
double TimestampOffset() const
{
return mTimestampOffset;
}
void SetTimestampOffset(double aTimestampOffset, ErrorResult& aRv);
double AppendWindowStart() const
{
return mAppendWindowStart;
}
void SetAppendWindowStart(double aAppendWindowStart, ErrorResult& aRv);
double AppendWindowEnd() const
{
return mAppendWindowEnd;
}
void SetAppendWindowEnd(double aAppendWindowEnd, ErrorResult& aRv);
void AppendBuffer(ArrayBuffer& aData, ErrorResult& aRv);
void AppendBuffer(ArrayBufferView& aData, ErrorResult& aRv);
void Abort(ErrorResult& aRv);
void Remove(double aStart, double aEnd, ErrorResult& aRv);
/** End WebIDL Methods. */
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SourceBuffer, nsDOMEventTargetHelper)
explicit SourceBuffer(MediaSource* aMediaSource);
MediaSource* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
// Notify the SourceBuffer that it has been attached to or detached from
// the MediaSource's sourceBuffer list.
void Attach();
void Detach();
private:
friend class AsyncEventRunnner<SourceBuffer>;
void DispatchSimpleEvent(const char* aName);
void QueueAsyncSimpleEvent(const char* aName);
// Update mUpdating and fire the appropriate events.
void StartUpdating();
void StopUpdating();
void AbortUpdating();
// Shared implementation of AppendBuffer overloads.
void AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aRv);
nsRefPtr<MediaSource> mMediaSource;
double mAppendWindowStart;
double mAppendWindowEnd;
double mTimestampOffset;
SourceBufferAppendMode mAppendMode;
bool mUpdating;
bool mAttached;
};
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_SourceBuffer_h_ */

Просмотреть файл

@ -0,0 +1,143 @@
/* -*- 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 "SourceBufferList.h"
#include "mozilla/dom/SourceBufferListBinding.h"
#include "nsContentUtils.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* gMediaSourceLog;
#define LOG(type, msg) PR_LOG(gMediaSourceLog, type, msg)
#else
#define LOG(type, msg)
#endif
namespace mozilla {
namespace dom {
SourceBuffer*
SourceBufferList::IndexedGetter(uint32_t aIndex, bool& aFound)
{
aFound = aIndex < mSourceBuffers.Length();
return aFound ? mSourceBuffers[aIndex] : nullptr;
}
uint32_t
SourceBufferList::Length()
{
return mSourceBuffers.Length();
}
void
SourceBufferList::Append(SourceBuffer* aSourceBuffer)
{
mSourceBuffers.AppendElement(aSourceBuffer);
QueueAsyncSimpleEvent("addsourcebuffer");
}
void
SourceBufferList::Remove(SourceBuffer* aSourceBuffer)
{
MOZ_ALWAYS_TRUE(mSourceBuffers.RemoveElement(aSourceBuffer));
QueueAsyncSimpleEvent("removesourcebuffer");
}
bool
SourceBufferList::Contains(SourceBuffer* aSourceBuffer)
{
return mSourceBuffers.Contains(aSourceBuffer);
}
void
SourceBufferList::Clear()
{
mSourceBuffers.Clear();
QueueAsyncSimpleEvent("removesourcebuffer");
}
bool
SourceBufferList::IsEmpty()
{
return mSourceBuffers.IsEmpty();
}
void
SourceBufferList::DetachAndClear()
{
for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
mSourceBuffers[i]->Detach();
}
Clear();
}
bool
SourceBufferList::AnyUpdating()
{
for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
if (mSourceBuffers[i]->Updating()) {
return true;
}
}
return false;
}
void
SourceBufferList::Remove(double aStart, double aEnd, ErrorResult& aRv)
{
for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
mSourceBuffers[i]->Remove(aStart, aEnd, aRv);
if (aRv.Failed()) {
return;
}
}
}
void
SourceBufferList::DispatchSimpleEvent(const char* aName)
{
LOG(PR_LOG_DEBUG, ("%p Dispatching event %s to SourceBufferList", this, aName));
DispatchTrustedEvent(NS_ConvertUTF8toUTF16(aName));
}
void
SourceBufferList::QueueAsyncSimpleEvent(const char* aName)
{
LOG(PR_LOG_DEBUG, ("%p Queuing event %s to SourceBufferList", this, aName));
nsCOMPtr<nsIRunnable> event = new AsyncEventRunnner<SourceBufferList>(this, aName);
NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
}
SourceBufferList::SourceBufferList(MediaSource* aMediaSource)
: nsDOMEventTargetHelper(aMediaSource->GetParentObject())
, mMediaSource(aMediaSource)
{
MOZ_ASSERT(aMediaSource);
}
MediaSource*
SourceBufferList::GetParentObject() const
{
return mMediaSource;
}
JSObject*
SourceBufferList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
{
return SourceBufferListBinding::Wrap(aCx, aScope, this);
}
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(SourceBufferList, nsDOMEventTargetHelper,
mMediaSource, mSourceBuffers)
NS_IMPL_ADDREF_INHERITED(SourceBufferList, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(SourceBufferList, nsDOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(SourceBufferList)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SourceBufferList_h_
#define mozilla_dom_SourceBufferList_h_
#include "AsyncEventRunner.h"
#include "MediaSource.h"
#include "SourceBuffer.h"
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
#include "nsWrapperCache.h"
#include "nscore.h"
namespace mozilla {
namespace dom {
class MediaSource;
class SourceBufferList MOZ_FINAL : public nsDOMEventTargetHelper
{
public:
/** WebIDL Methods. */
SourceBuffer* IndexedGetter(uint32_t aIndex, bool& aFound);
uint32_t Length();
/** End WebIDL methods. */
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SourceBufferList, nsDOMEventTargetHelper)
explicit SourceBufferList(MediaSource* aMediaSource);
MediaSource* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
// Append a SourceBuffer and fire "addsourcebuffer" at the list.
void Append(SourceBuffer* aSourceBuffer);
// Remove a SourceBuffer and fire "removesourcebuffer" at the list.
void Remove(SourceBuffer* aSourceBuffer);
// Returns true if aSourceBuffer is present in the list.
bool Contains(SourceBuffer* aSourceBuffer);
// Remove all SourceBuffers and fire a single "removesourcebuffer" at the list.
void Clear();
// True if list has zero entries.
bool IsEmpty();
// Detach and remove all SourceBuffers and fire a single "removesourcebuffer" at the list.
void DetachAndClear();
// Returns true if updating is true on any SourceBuffers in the list.
bool AnyUpdating();
// Calls Remove(aStart, aEnd) on each SourceBuffer in the list. Aborts on
// first error, with result returned in aRv.
void Remove(double aStart, double aEnd, ErrorResult& aRv);
private:
friend class AsyncEventRunnner<SourceBufferList>;
void DispatchSimpleEvent(const char* aName);
void QueueAsyncSimpleEvent(const char* aName);
nsRefPtr<MediaSource> mMediaSource;
nsTArray<nsRefPtr<SourceBuffer> > mSourceBuffers;
};
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_SourceBufferList_h_ */

Просмотреть файл

@ -0,0 +1,28 @@
# 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/.
PARALLEL_DIRS += [
'test'
]
MODULE = 'content'
EXPORTS += [
'AsyncEventRunner.h',
]
EXPORTS.mozilla.dom += [
'MediaSource.h',
'SourceBuffer.h',
'SourceBufferList.h',
]
CPP_SOURCES += [
'MediaSource.cpp',
'MediaSourceInputAdapter.cpp',
'SourceBuffer.cpp',
'SourceBufferList.cpp',
]

Просмотреть файл

@ -0,0 +1,18 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH := @DEPTH@
topsrcdir := @top_srcdir@
srcdir := @srcdir@
VPATH := @srcdir@
relativesrcdir := @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES = \
test_MediaSource.html \
seek.webm \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -1,7 +1,4 @@
# 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/.
toolkit.jar:
content/global/cpow/test.xul (tests/adhoc/test.xul)
content/global/cpow/child.html (tests/adhoc/child.html)

Двоичные данные
content/media/mediasource/test/seek.webm Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test whether we can create an MediaSource interface</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
ok(!window.MediaSource, "MediaSource should be hidden behind a pref");
if (navigator.appVersion.indexOf("Android") != -1) {
todo(false, "Fix this test on Android: bug 889712.");
SimpleTest.finish();
return;
}
var accessThrows = false;
try {
new MediaSource();
} catch (e) {
accessThrows = true;
}
ok(accessThrows, "MediaSource should be hidden behind a pref");
SpecialPowers.setBoolPref("media.mediasource.enabled", true);
var ms = new MediaSource();
ok(ms, "Create a MediaSource object");
ok(ms instanceof EventTarget, "MediaSource must be an EventTarget");
is(ms.readyState, "closed", "New MediaSource must be in closed state");
// Force wrapper creation, tests for leaks.
ms.foo = null;
var o = URL.createObjectURL(ms);
ok(o, "Create an objectURL from the MediaSource");
var v = document.createElement("video");
document.body.appendChild(v);
v.src = o;
ms.addEventListener("sourceopen", function () {
ok(true, "Receive a sourceopen event");
is(ms.readyState, "open", "MediaSource must be in open state after sourceopen");
var sb = ms.addSourceBuffer("video/webm");
ok(sb, "Create a SourceBuffer");
is(ms.sourceBuffers.length, 1, "MediaSource.sourceBuffers is expected length");
is(ms.sourceBuffers[0], sb, "SourceBuffer in list matches our SourceBuffer");
fetch("seek.webm", function (blob) {
var r = new FileReader();
r.addEventListener("load", function (e) {
sb.appendBuffer(new Uint8Array(e.target.result));
ms.endOfStream();
v.play();
});
r.readAsArrayBuffer(blob);
});
});
ms.addEventListener("sourceended", function () {
ok(true, "Receive a sourceended event");
is(ms.readyState, "ended", "MediaSource must be in ended state after sourceended");
});
v.addEventListener("playing", function () {
is(v.duration, 4, "Video has correct duration");
v.parentNode.removeChild(v);
SpecialPowers.clearUserPref("media.mediasource.enabled");
SimpleTest.finish();
});
});
function fetch(src, cb) {
var xhr = new XMLHttpRequest();
xhr.open("GET", src, true);
xhr.responseType = "blob";
xhr.addEventListener("load", function (e) {
if (xhr.status != 200) {
return false;
}
cb(xhr.response);
});
xhr.send();
};
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -6,6 +6,8 @@
PARALLEL_DIRS += ['encoder']
PARALLEL_DIRS += ['mediasource']
PARALLEL_DIRS += ['webaudio']
if CONFIG['MOZ_RAW']:
@ -85,6 +87,7 @@ EXPORTS.mozilla.dom += [
'TextTrackCue.h',
'TextTrackCueList.h',
'TextTrackList.h',
'VideoPlaybackQuality.h',
'VideoStreamTrack.h',
]
@ -112,6 +115,7 @@ CPP_SOURCES += [
'TextTrackCueList.cpp',
'TextTrackList.cpp',
'VideoFrameContainer.cpp',
'VideoPlaybackQuality.cpp',
'VideoSegment.cpp',
'VideoStreamTrack.cpp',
'VideoUtils.cpp',

Просмотреть файл

@ -11,7 +11,6 @@
#include "MediaPluginHost.h"
#include "nsXPCOMStrings.h"
#include "nsISeekableStream.h"
#include "pratom.h"
#include "MediaPluginReader.h"
#include "nsIGfxInfo.h"
#include "gfxCrashReporterUtils.h"

Просмотреть файл

@ -0,0 +1,4 @@
<!DOCTYPE html>
<script>
(new AudioContext()).createConvolver().buffer = null;
</script>

Просмотреть файл

@ -49,3 +49,4 @@ load 881775.html
load 882956.html
test-pref(media.webvtt.enabled,true) load 882549.html
load 884459.html
load 889042.html

Просмотреть файл

@ -168,15 +168,17 @@ ConvolverNode::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
void
ConvolverNode::SetBuffer(JSContext* aCx, AudioBuffer* aBuffer, ErrorResult& aRv)
{
switch (aBuffer->NumberOfChannels()) {
case 1:
case 2:
case 4:
// Supported number of channels
break;
default:
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
if (aBuffer) {
switch (aBuffer->NumberOfChannels()) {
case 1:
case 2:
case 4:
// Supported number of channels
break;
default:
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return;
}
}
mBuffer = aBuffer;

Просмотреть файл

@ -19,6 +19,7 @@
#include "mozilla/dom/SVGMatrix.h"
#include "DOMSVGPoint.h"
#include "nsIFrame.h"
#include "nsFrameSelection.h"
#include "nsISVGSVGFrame.h" //XXX
#include "mozilla/dom/SVGRect.h"
#include "nsError.h"
@ -364,6 +365,16 @@ SVGSVGElement::SetCurrentTime(float seconds)
// else we're not the outermost <svg> or not bound to a tree, so silently fail
}
void
SVGSVGElement::DeselectAll()
{
nsIFrame* frame = GetPrimaryFrame();
if (frame) {
nsRefPtr<nsFrameSelection> frameSelection = frame->GetFrameSelection();
frameSelection->ClearNormalSelection();
}
}
already_AddRefed<nsIDOMSVGNumber>
SVGSVGElement::CreateSVGNumber()
{

Просмотреть файл

@ -237,6 +237,7 @@ public:
bool AnimationsPaused();
float GetCurrentTime();
void SetCurrentTime(float seconds);
void DeselectAll();
already_AddRefed<nsIDOMSVGNumber> CreateSVGNumber();
already_AddRefed<nsIDOMSVGLength> CreateSVGLength();
already_AddRefed<SVGAngle> CreateSVGAngle();

Просмотреть файл

@ -331,16 +331,23 @@ this.AlarmService = {
},
_getAlarmTime: function _getAlarmTime(aAlarm) {
let alarmTime = (new Date(aAlarm.date)).getTime();
// Avoid casting a Date object to a Date again to
// preserve milliseconds. See bug 810973.
let alarmTime;
if (aAlarm.date instanceof Date) {
alarmTime = aAlarm.date.getTime();
} else {
alarmTime = (new Date(aAlarm.date)).getTime();
}
// For an alarm specified with "ignoreTimezone", it must be fired respect
// to the user's timezone. Supposing an alarm was set at 7:00pm at Tokyo,
// it must be gone off at 7:00pm respect to Paris' local time when the user
// is located at Paris. We can adjust the alarm UTC time by calculating
// the difference of the orginal timezone and the current timezone.
if (aAlarm.ignoreTimezone)
if (aAlarm.ignoreTimezone) {
alarmTime += (this._currentTimezoneOffset - aAlarm.timezoneOffset) * 60000;
}
return alarmTime;
},

Просмотреть файл

@ -8,6 +8,7 @@
#include "nsGlobalWindow.h"
#include "nsIDOMFile.h"
#include "DOMMediaStream.h"
#include "mozilla/dom/MediaSource.h"
#include "nsIDocument.h"
#include "nsIPrincipal.h"
#include "nsContentUtils.h"
@ -38,6 +39,17 @@ URL::CreateObjectURL(const GlobalObject& aGlobal, DOMMediaStream& aStream,
aResult, aError);
}
void
URL::CreateObjectURL(const GlobalObject& aGlobal, MediaSource& aSource,
const objectURLOptions& aOptions,
nsString& aResult,
ErrorResult& aError)
{
CreateObjectURLInternal(aGlobal.Get(), &aSource,
NS_LITERAL_CSTRING(MEDIASOURCEURI_SCHEME), aOptions,
aResult, aError);
}
void
URL::CreateObjectURLInternal(nsISupports* aGlobal, nsISupports* aObject,
const nsACString& aScheme,

Просмотреть файл

@ -16,6 +16,8 @@ class DOMMediaStream;
namespace dom {
class MediaSource;
class URL MOZ_FINAL
{
public:
@ -29,6 +31,11 @@ public:
const mozilla::dom::objectURLOptions& aOptions,
nsString& aResult,
mozilla::ErrorResult& aError);
static void CreateObjectURL(const GlobalObject& aGlobal,
MediaSource& aSource,
const objectURLOptions& aOptions,
nsString& aResult,
mozilla::ErrorResult& aError);
static void RevokeObjectURL(const GlobalObject& aGlobal,
const nsAString& aURL);

Просмотреть файл

@ -28,6 +28,7 @@ EXPORTS += [
'nsDOMClassInfoClasses.h',
'nsDOMClassInfoID.h',
'nsDOMJSUtils.h',
'nsDOMNavigationTiming.h',
'nsDOMString.h',
'nsFocusManager.h',
'nsIDOMClassInfo.h',
@ -47,6 +48,7 @@ EXPORTS += [
'nsJSUtils.h',
'nsPIDOMWindow.h',
'nsPIWindowRoot.h',
'nsPerformance.h',
'nsStructuredCloneContainer.h',
'nsWindowMemoryReporter.h',
'nsWrapperCache.h',

Просмотреть файл

@ -4026,6 +4026,12 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
if (name_struct->mChromeOnly && !nsContentUtils::IsCallerChrome())
return NS_OK;
// Before defining a global property, check for a named subframe of the
// same name. If it exists, we don't want to shadow it.
nsCOMPtr<nsIDOMWindow> childWin = aWin->GetChildWindow(name);
if (childWin)
return NS_OK;
nsCOMPtr<nsISupports> native(do_CreateInstance(name_struct->mCID, &rv));
NS_ENSURE_SUCCESS(rv, rv);

Просмотреть файл

@ -609,6 +609,15 @@ DOMInterfaces = {
'register': False
},
'MediaSource': [{
'resultNotAddRefed': [ 'sourceBuffers', 'activeSourceBuffers' ],
},
{
'nativeType': 'JSObject',
'workers': True,
'skipGen': True
}],
'MediaStream': [{
'headerFile': 'DOMMediaStream.h',
'nativeType': 'mozilla::DOMMediaStream'
@ -807,6 +816,10 @@ DOMInterfaces = {
'nativeType': 'nsDOMSimpleGestureEvent',
},
'SourceBufferList': {
'resultNotAddRefed': [ '__indexedGetter' ],
},
'StyleSheet': {
'nativeType': 'nsCSSStyleSheet',
},
@ -1126,6 +1139,10 @@ DOMInterfaces = {
'workers': True,
}],
'VideoPlaybackQuality': {
'nativeOwnership': 'refcounted',
},
'VideoStreamTrack': {
},

Просмотреть файл

@ -29,11 +29,11 @@
#include <cstdio>
#include <dbus/dbus.h>
#include "pratom.h"
#include "nsAutoPtr.h"
#include "nsThreadUtils.h"
#include "nsDebug.h"
#include "nsDataHashtable.h"
#include "mozilla/Atomics.h"
#include "mozilla/Hal.h"
#include "mozilla/ipc/UnixSocket.h"
#include "mozilla/ipc/DBusThread.h"
@ -151,7 +151,7 @@ static const char* sBluetoothDBusSignals[] =
static nsAutoPtr<RawDBusConnection> gThreadConnection;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sPairingReqTable;
static nsDataHashtable<nsStringHashKey, DBusMessage* > sAuthorizeReqTable;
static int32_t sIsPairing = 0;
static Atomic<int32_t> sIsPairing;
static nsString sAdapterPath;
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
@ -456,7 +456,7 @@ GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
if (sIsPairing) {
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
UnpackObjectPathMessage);
PR_AtomicDecrement(&sIsPairing);
sIsPairing--;
}
}
@ -1678,7 +1678,7 @@ BluetoothDBusService::StopInternal()
sAuthorizeReqTable.EnumerateRead(UnrefDBusMessages, nullptr);
sAuthorizeReqTable.Clear();
PR_AtomicSet(&sIsPairing, 0);
sIsPairing = 0;
StopDBus();
return NS_OK;
@ -2173,7 +2173,7 @@ BluetoothDBusService::CreatePairedDeviceInternal(
*
* Please see Bug 818696 for more information.
*/
PR_AtomicIncrement(&sIsPairing);
sIsPairing++;
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
// Then send CreatePairedDevice, it will register a temp device agent then

Просмотреть файл

@ -27,6 +27,7 @@ DOM_SRCDIRS = \
content/base/src \
content/html/content/src \
content/html/document/src \
content/media/mediasource \
content/media/webaudio \
content/svg/content/src \
layout/generic \

Просмотреть файл

@ -25,7 +25,6 @@
#include "mozilla/ipc/GeckoChildProcessHost.h"
#include "mozilla/ipc/TestShellChild.h"
#include "mozilla/ipc/XPCShellEnvironment.h"
#include "mozilla/jsipc/PContextWrapperChild.h"
#include "mozilla/layers/CompositorChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/PCompositorChild.h"
@ -50,6 +49,7 @@
#include "nsDebugImpl.h"
#include "nsHashPropertyBag.h"
#include "nsLayoutStylesheetCache.h"
#include "nsIJSRuntimeService.h"
#include "IHistory.h"
#include "nsDocShellCID.h"
@ -64,6 +64,7 @@
#include "nsFrameMessageManager.h"
#include "nsIGeolocationProvider.h"
#include "JavaScriptParent.h"
#include "mozilla/dom/PMemoryReportRequestChild.h"
#ifdef MOZ_PERMISSIONS
@ -109,6 +110,7 @@
#include "nsIPrincipal.h"
#include "nsDeviceStorage.h"
#include "AudioChannelService.h"
#include "JavaScriptChild.h"
#include "ProcessPriorityManager.h"
using namespace base;
@ -123,6 +125,7 @@ using namespace mozilla::hal_sandbox;
using namespace mozilla::ipc;
using namespace mozilla::layers;
using namespace mozilla::net;
using namespace mozilla::jsipc;
#if defined(MOZ_WIDGET_GONK)
using namespace mozilla::system;
#endif
@ -552,6 +555,31 @@ static void FirstIdle(void)
ContentChild::GetSingleton()->SendFirstIdle();
}
mozilla::jsipc::PJavaScriptChild *
ContentChild::AllocPJavaScript()
{
nsCOMPtr<nsIJSRuntimeService> svc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
NS_ENSURE_TRUE(svc, NULL);
JSRuntime *rt;
svc->GetRuntime(&rt);
NS_ENSURE_TRUE(svc, NULL);
mozilla::jsipc::JavaScriptChild *child = new mozilla::jsipc::JavaScriptChild(rt);
if (!child->init()) {
delete child;
return NULL;
}
return child;
}
bool
ContentChild::DeallocPJavaScript(PJavaScriptChild *child)
{
delete child;
return true;
}
PBrowserChild*
ContentChild::AllocPBrowser(const IPCTabContext& aContext,
const uint32_t& aChromeFlags)
@ -760,10 +788,19 @@ ContentChild::DeallocPTestShell(PTestShellChild* shell)
return true;
}
jsipc::JavaScriptChild *
ContentChild::GetCPOWManager()
{
if (ManagedPJavaScriptChild().Length()) {
return static_cast<JavaScriptChild*>(ManagedPJavaScriptChild()[0]);
}
JavaScriptChild* actor = static_cast<JavaScriptChild*>(SendPJavaScriptConstructor());
return actor;
}
bool
ContentChild::RecvPTestShellConstructor(PTestShellChild* actor)
{
actor->SendPContextWrapperConstructor()->SendPObjectWrapperConstructor(true);
return true;
}

Просмотреть файл

@ -28,6 +28,10 @@ class OptionalURIParams;
class URIParams;
}// namespace ipc
namespace jsipc {
class JavaScriptChild;
}
namespace layers {
class PCompositorChild;
} // namespace layers
@ -126,6 +130,7 @@ public:
virtual PTestShellChild* AllocPTestShell();
virtual bool DeallocPTestShell(PTestShellChild*);
virtual bool RecvPTestShellConstructor(PTestShellChild*);
jsipc::JavaScriptChild *GetCPOWManager();
virtual PNeckoChild* AllocPNecko();
virtual bool DeallocPNecko(PNeckoChild*);
@ -156,6 +161,9 @@ public:
const InfallibleTArray<OverrideMapping>& overrides,
const nsCString& locale);
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScript();
virtual bool DeallocPJavaScript(mozilla::jsipc::PJavaScriptChild*);
virtual bool RecvSetOffline(const bool& offline);
virtual bool RecvNotifyVisited(const URIParams& aURI);

Просмотреть файл

@ -119,6 +119,7 @@ using namespace mozilla::system;
#include "BluetoothService.h"
#endif
#include "JavaScriptParent.h"
#include "Crypto.h"
#ifdef MOZ_WEBSPEECH
@ -140,6 +141,7 @@ using namespace mozilla::idl;
using namespace mozilla::ipc;
using namespace mozilla::layers;
using namespace mozilla::net;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
@ -905,8 +907,6 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
threadInt(do_QueryInterface(NS_GetCurrentThread()));
if (threadInt)
threadInt->RemoveObserver(this);
if (mRunToCompletionDepth)
mRunToCompletionDepth = 0;
MarkAsDead();
@ -1010,6 +1010,16 @@ ContentParent::NotifyTabDestroyed(PBrowserParent* aTab,
}
}
jsipc::JavaScriptParent*
ContentParent::GetCPOWManager()
{
if (ManagedPJavaScriptParent().Length()) {
return static_cast<JavaScriptParent*>(ManagedPJavaScriptParent()[0]);
}
JavaScriptParent* actor = static_cast<JavaScriptParent*>(SendPJavaScriptConstructor());
return actor;
}
TestShellParent*
ContentParent::CreateTestShell()
{
@ -1039,8 +1049,6 @@ ContentParent::ContentParent(mozIApplication* aApp,
, mOSPrivileges(aOSPrivileges)
, mChildID(gContentChildID++)
, mGeolocationWatchID(-1)
, mRunToCompletionDepth(0)
, mShouldCallUnblockChild(false)
, mForceKillTask(nullptr)
, mNumDestroyingTabs(0)
, mIsAlive(true)
@ -1582,6 +1590,24 @@ ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline)
return true;
}
mozilla::jsipc::PJavaScriptParent *
ContentParent::AllocPJavaScript()
{
mozilla::jsipc::JavaScriptParent *parent = new mozilla::jsipc::JavaScriptParent();
if (!parent->init()) {
delete parent;
return NULL;
}
return parent;
}
bool
ContentParent::DeallocPJavaScript(PJavaScriptParent *parent)
{
static_cast<mozilla::jsipc::JavaScriptParent *>(parent)->destroyFromContent();
return true;
}
PBrowserParent*
ContentParent::AllocPBrowser(const IPCTabContext& aContext,
const uint32_t &aChromeFlags)
@ -2051,32 +2077,6 @@ ContentParent::RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor)
#endif
}
void
ContentParent::ReportChildAlreadyBlocked()
{
if (!mRunToCompletionDepth) {
#ifdef DEBUG
printf("Running to completion...\n");
#endif
mRunToCompletionDepth = 1;
mShouldCallUnblockChild = false;
}
}
bool
ContentParent::RequestRunToCompletion()
{
if (!mRunToCompletionDepth &&
BlockChild()) {
#ifdef DEBUG
printf("Running to completion...\n");
#endif
mRunToCompletionDepth = 1;
mShouldCallUnblockChild = true;
}
return !!mRunToCompletionDepth;
}
bool
ContentParent::RecvStartVisitedQuery(const URIParams& aURI)
{
@ -2245,9 +2245,6 @@ ContentParent::OnProcessNextEvent(nsIThreadInternal *thread,
bool mayWait,
uint32_t recursionDepth)
{
if (mRunToCompletionDepth)
++mRunToCompletionDepth;
return NS_OK;
}
@ -2256,17 +2253,6 @@ NS_IMETHODIMP
ContentParent::AfterProcessNextEvent(nsIThreadInternal *thread,
uint32_t recursionDepth)
{
if (mRunToCompletionDepth &&
!--mRunToCompletionDepth) {
#ifdef DEBUG
printf("... ran to completion.\n");
#endif
if (mShouldCallUnblockChild) {
mShouldCallUnblockChild = false;
UnblockChild();
}
}
return NS_OK;
}

Просмотреть файл

@ -44,6 +44,10 @@ class URIParams;
class TestShellParent;
} // namespace ipc
namespace jsipc {
class JavaScriptParent;
}
namespace layers {
class PCompositorParent;
} // namespace layers
@ -126,6 +130,7 @@ public:
TestShellParent* CreateTestShell();
bool DestroyTestShell(TestShellParent* aTestShell);
TestShellParent* GetTestShellSingleton();
jsipc::JavaScriptParent *GetCPOWManager();
void ReportChildAlreadyBlocked();
bool RequestRunToCompletion();
@ -194,6 +199,7 @@ private:
// using them.
using PContentParent::SendPBrowserConstructor;
using PContentParent::SendPTestShellConstructor;
using PContentParent::SendPJavaScriptConstructor;
// No more than one of !!aApp, aIsForBrowser, and aIsForPreallocated may be
// true.
@ -251,6 +257,9 @@ private:
bool* aIsForBrowser) MOZ_OVERRIDE;
virtual bool RecvGetXPCOMProcessAttributes(bool* aIsOffline) MOZ_OVERRIDE;
virtual mozilla::jsipc::PJavaScriptParent* AllocPJavaScript();
virtual bool DeallocPJavaScript(mozilla::jsipc::PJavaScriptParent*);
virtual PBrowserParent* AllocPBrowser(const IPCTabContext& aContext,
const uint32_t& aChromeFlags);
virtual bool DeallocPBrowser(PBrowserParent* frame);
@ -414,8 +423,6 @@ private:
uint64_t mChildID;
int32_t mGeolocationWatchID;
int mRunToCompletionDepth;
bool mShouldCallUnblockChild;
// This is a cache of all of the memory reporters
// registered in the child process. To update this, one

Просмотреть файл

@ -42,6 +42,7 @@ LOCAL_INCLUDES += \
-I$(topsrcdir)/dom/bluetooth \
-I$(topsrcdir)/dom/bluetooth/ipc \
-I$(topsrcdir)/content/media/webspeech/synth/ipc \
-I$(topsrcdir)/js/ipc \
$(NULL)
DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'

Просмотреть файл

@ -20,6 +20,7 @@ include protocol PSms;
include protocol PSpeechSynthesis;
include protocol PStorage;
include protocol PTestShell;
include protocol PJavaScript;
include DOMTypes;
include InputStreamParams;
include URIParams;
@ -252,6 +253,7 @@ rpc protocol PContent
manages PSpeechSynthesis;
manages PStorage;
manages PTestShell;
manages PJavaScript;
both:
// Depending on exactly how the new browser is being created, it might be
@ -281,6 +283,8 @@ both:
async PBlob(BlobConstructorParams params);
PJavaScript();
child:
/**
* Update OS process privileges to |privs|. Can usually only be

Просмотреть файл

@ -1529,7 +1529,10 @@ TabChild::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
utils->SetScrollPositionClampingScrollPortSize(
cssCompositedRect.width, cssCompositedRect.height);
ScrollWindowTo(window, aFrameMetrics.mScrollOffset);
CSSToScreenScale resolution = aFrameMetrics.CalculateResolution();
LayoutDeviceToLayerScale resolution =
aFrameMetrics.CalculateResolution()
/ aFrameMetrics.mDevPixelsPerCSSPixel
* ScreenToLayerScale(1);
utils->SetResolution(resolution.scale, resolution.scale);
nsCOMPtr<nsIDOMDocument> domDoc;

Просмотреть файл

@ -15,6 +15,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=857555
addLoadEvent(function() {
is(content, $("t").contentWindow, "'content' as iframe name should work");
is(sidebar, $("u").contentWindow, "'sidebar' as iframe name should work");
is(external, $("v").contentWindow, "'external' as iframe name should work");
SimpleTest.finish();
});
</script>
@ -24,6 +26,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=857555
<p id="display"></p>
<div id="content" style="display: none">
<iframe name="content" id="t"></iframe>
<iframe name="sidebar" id="u"></iframe>
<iframe name="external" id="v"></iframe>
</div>
<pre id="test">
</pre>

Просмотреть файл

@ -45,3 +45,9 @@ partial interface HTMLVideoElement {
// True if the video has an audio track available.
readonly attribute boolean mozHasAudio;
};
// https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#idl-def-HTMLVideoElement
partial interface HTMLVideoElement {
[Pref="media.mediasource.enabled"]
readonly attribute VideoPlaybackQuality videoPlaybackQuality;
};

Просмотреть файл

@ -0,0 +1,38 @@
/* -*- Mode: IDL; 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/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
enum MediaSourceReadyState {
"closed",
"open",
"ended"
};
enum MediaSourceEndOfStreamError {
"network",
"decode"
};
[Constructor, Pref="media.mediasource.enabled"]
interface MediaSource : EventTarget {
readonly attribute SourceBufferList sourceBuffers;
readonly attribute SourceBufferList activeSourceBuffers;
readonly attribute MediaSourceReadyState readyState;
[SetterThrows]
attribute unrestricted double duration;
[Creator, Throws]
SourceBuffer addSourceBuffer(DOMString type);
[Throws]
void removeSourceBuffer(SourceBuffer sourceBuffer);
[Throws]
void endOfStream(optional MediaSourceEndOfStreamError error);
static boolean isTypeSupported(DOMString type);
};

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше