merge mozilla-inbound to mozilla-central a=merge

--HG--
extra : amend_source : 5c7cfd30ad208d681883eed78a694e7dcbd22dad
This commit is contained in:
Carsten "Tomcat" Book 2014-07-17 16:01:43 +02:00
commit 7e32490248
331 changed files with 5499 additions and 2795 deletions

View File

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1038799 - And be wary of your ccache too.
Clobber to work around bug 959928.

View File

@ -29,8 +29,9 @@ XPCOMUtils.defineLazyModuleGetter(this, 'States',
this.EXPORTED_SYMBOLS = ['EventManager'];
this.EventManager = function EventManager(aContentScope) {
this.EventManager = function EventManager(aContentScope, aContentControl) {
this.contentScope = aContentScope;
this.contentControl = aContentControl;
this.addEventListener = this.contentScope.addEventListener.bind(
this.contentScope);
this.removeEventListener = this.contentScope.removeEventListener.bind(
@ -99,7 +100,7 @@ this.EventManager.prototype = {
{
let attempts = 0;
let delta = aEvent.deltaX || aEvent.deltaY;
this.contentScope.contentControl.autoMove(
this.contentControl.autoMove(
null,
{ moveMethod: delta > 0 ? 'moveNext' : 'movePrevious',
onScreenOnly: true, noOpIfOnScreen: true, delay: 500 });
@ -183,7 +184,7 @@ this.EventManager.prototype = {
}
case Events.SCROLLING_START:
{
this.contentScope.contentControl.autoMove(aEvent.accessible);
this.contentControl.autoMove(aEvent.accessible);
break;
}
case Events.TEXT_CARET_MOVED:
@ -254,7 +255,7 @@ this.EventManager.prototype = {
if (vc.position &&
(Utils.getState(vc.position).contains(States.DEFUNCT) ||
Utils.isInSubtree(vc.position, aEvent.accessible))) {
this.contentScope.contentControl.autoMove(
this.contentControl.autoMove(
evt.targetPrevSibling || evt.targetParent,
{ moveToFocused: true, delay: 500 });
}
@ -279,19 +280,19 @@ this.EventManager.prototype = {
let acc = aEvent.accessible;
let doc = aEvent.accessibleDocument;
if (acc.role != Roles.DOCUMENT && doc.role != Roles.CHROME_WINDOW) {
this.contentScope.contentControl.autoMove(acc);
this.contentControl.autoMove(acc);
}
break;
}
case Events.DOCUMENT_LOAD_COMPLETE:
{
this.contentScope.contentControl.autoMove(
this.contentControl.autoMove(
aEvent.accessible, { delay: 500 });
break;
}
case Events.VALUE_CHANGE:
{
let position = this.contentScope.contentControl.vc.position;
let position = this.contentControl.vc.position;
let target = aEvent.accessible;
if (position === target ||
Utils.getEmbeddedControl(position) === target) {

View File

@ -140,16 +140,16 @@ addMessageListener(
addMessageListener('AccessFu:Scroll', scroll);
addMessageListener('AccessFu:AdjustRange', adjustRange);
if (!eventManager) {
eventManager = new EventManager(this);
}
eventManager.start();
if (!contentControl) {
contentControl = new ContentControl(this);
}
contentControl.start();
if (!eventManager) {
eventManager = new EventManager(this, contentControl);
}
eventManager.start();
sendAsyncMessage('AccessFu:ContentStarted');
});

View File

@ -124,14 +124,9 @@ else # MOZ_WIDGET_TOOLKIT != cocoa
libs::
ifdef LIBXUL_SDK
cp $(LIBXUL_DIST)/bin/xulrunner-stub$(BIN_SUFFIX) $(DIST)/bin/$(APP_BINARY)
endif
ifndef SKIP_COPY_XULRUNNER
ifdef LIBXUL_SDK
$(NSINSTALL) -D $(DIST)/bin/xulrunner
(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
endif
endif # SKIP_COPY_XULRUNNER
$(NSINSTALL) -D $(DIST)/bin/chrome/icons/default
# Copy the app icon for b2g-desktop

View File

@ -473,17 +473,6 @@ pref("services.push.adaptive.gap", 60000); // 1 minute
pref("services.push.adaptive.upperLimit", 1740000); // 29 min
// enable udp wakeup support
pref("services.push.udp.wakeupEnabled", true);
// This value should be the prefix to be added to the current PDP context[1]
// domain or a full-qualified domain name.
// If finished with a dot, it will be added as a prefix to the PDP context
// domain. If not, will be used as the DNS query.
// If the DNS query is unsuccessful, the push agent will send a null netid and
// is a server decision what to do with the device. If the MCC-MNC identifies a
// unique network the server will change to UDP mode. Otherwise, a websocket
// connection will be maintained.
// [1] Packet Data Protocol
// http://en.wikipedia.org/wiki/GPRS_core_network#PDP_context
pref("services.push.udp.well-known_netidAddress", "_wakeup_.");
// NetworkStats
#ifdef MOZ_WIDGET_GONK

View File

@ -10,4 +10,5 @@ support-files =
[test_filepicker_path.html]
[test_permission_deny.html]
[test_permission_gum_remember.html]
skip-if = (toolkit == 'gonk' && debug) # Bug 1019572 - debug-only timeout
[test_systemapp.html]

View File

@ -135,7 +135,6 @@ tools repackage:: $(PROGRAM)
endif
ifdef LIBXUL_SDK #{
ifndef SKIP_COPY_XULRUNNER #{
libs::
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT)) #{
rsync -a --copy-unsafe-links $(LIBXUL_DIST)/XUL.framework $(dist_dest)/Contents/Frameworks
@ -143,5 +142,4 @@ else
$(NSINSTALL) -D $(DIST)/bin/xulrunner
(cd $(LIBXUL_SDK)/bin && tar $(TAR_CREATE_FLAGS) - .) | (cd $(DIST)/bin/xulrunner && tar -xf -)
endif #} cocoa
endif #} SKIP_COPY_XULRUNNER
endif #} LIBXUL_SDK

View File

@ -1519,6 +1519,7 @@ pref("loop.enabled", false);
#endif
pref("loop.server", "https://loop.services.mozilla.com");
pref("loop.seenToS", "unseen");
pref("loop.do_not_disturb", false);
pref("loop.ringtone", "chrome://browser/content/loop/shared/sounds/Firefox-Long.ogg");

View File

@ -540,7 +540,7 @@ var gPopupBlockerObserver = {
// xxxdz this should make the option say "Show file picker" and do it (Bug 590306)
if (!blockedPopup.popupWindowURI)
continue;
var popupURIspec = blockedPopup.popupWindowURI;
var popupURIspec = blockedPopup.popupWindowURI.spec;
// Sometimes the popup URI that we get back from the blockedPopup
// isn't useful (for instance, netscape.com's popup URI ends up

View File

@ -1024,7 +1024,7 @@
this._appendStatusPanel();
if (updateBlockedPopups)
this.mCurrentBrowser.updateBlockedPopups(false);
this.mCurrentBrowser.updateBlockedPopups();
// Update the URL bar.
var loc = this.mCurrentBrowser.currentURI;

View File

@ -13,7 +13,7 @@ let crash = function() { // this will crash when called.
};
TestHelper = {
let TestHelper = {
init: function() {
addMessageListener("social-test:crash", this);
},

View File

@ -113,7 +113,7 @@ loop.panel = (function(_, mozL10n) {
"privacy_notice_url": "www.mozilla.org/privacy/"
});
if (!this.state.seenToS) {
if (this.state.seenToS == "unseen") {
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
return React.DOM.p( {className:"terms-service",
dangerouslySetInnerHTML:{__html: tosHTML}});

View File

@ -113,7 +113,7 @@ loop.panel = (function(_, mozL10n) {
"privacy_notice_url": "www.mozilla.org/privacy/"
});
if (!this.state.seenToS) {
if (this.state.seenToS == "unseen") {
navigator.mozLoop.setLoopCharPref('seenToS', 'seen');
return <p className="terms-service"
dangerouslySetInnerHTML={{__html: tosHTML}}></p>;

View File

@ -220,10 +220,6 @@ loop.shared.views = (function(_, OT, l10n) {
},
componentDidMount: function() {
this.props.model.startSession();
},
componentWillMount: function() {
this.listenTo(this.props.model, "session:connected",
this.startPublishing);
this.listenTo(this.props.model, "session:stream-created",
@ -232,9 +228,13 @@ loop.shared.views = (function(_, OT, l10n) {
"session:network-disconnected",
"session:ended"].join(" "),
this.stopPublishing);
this.props.model.startSession();
},
componentWillUnmount: function() {
// Unregister all local event listeners
this.stopListening();
this.hangup();
},
@ -279,20 +279,19 @@ loop.shared.views = (function(_, OT, l10n) {
outgoing, this.publisherConfig);
// Suppress OT GuM custom dialog, see bug 1018875
function preventOpeningAccessDialog(event) {
event.preventDefault();
}
this.publisher.on("accessDialogOpened", preventOpeningAccessDialog);
this.publisher.on("accessDenied", preventOpeningAccessDialog);
this.listenTo(this.publisher, "accessDialogOpened accessDenied",
function(event) {
event.preventDefault();
});
this.publisher.on("streamCreated", function(event) {
this.listenTo(this.publisher, "streamCreated", function(event) {
this.setState({
audio: {enabled: event.stream.hasAudio},
video: {enabled: event.stream.hasVideo}
});
}.bind(this));
this.publisher.on("streamDestroyed", function() {
this.listenTo(this.publisher, "streamDestroyed", function() {
this.setState({
audio: {enabled: false},
video: {enabled: false}
@ -322,9 +321,8 @@ loop.shared.views = (function(_, OT, l10n) {
* Unpublishes local stream.
*/
stopPublishing: function() {
// Unregister access OT GuM custom dialog listeners, see bug 1018875
this.publisher.off("accessDialogOpened");
this.publisher.off("accessDenied");
// Unregister listeners for publisher events
this.stopListening(this.publisher);
this.props.model.session.unpublish(this.publisher);
},

View File

@ -220,10 +220,6 @@ loop.shared.views = (function(_, OT, l10n) {
},
componentDidMount: function() {
this.props.model.startSession();
},
componentWillMount: function() {
this.listenTo(this.props.model, "session:connected",
this.startPublishing);
this.listenTo(this.props.model, "session:stream-created",
@ -232,9 +228,13 @@ loop.shared.views = (function(_, OT, l10n) {
"session:network-disconnected",
"session:ended"].join(" "),
this.stopPublishing);
this.props.model.startSession();
},
componentWillUnmount: function() {
// Unregister all local event listeners
this.stopListening();
this.hangup();
},
@ -279,20 +279,19 @@ loop.shared.views = (function(_, OT, l10n) {
outgoing, this.publisherConfig);
// Suppress OT GuM custom dialog, see bug 1018875
function preventOpeningAccessDialog(event) {
event.preventDefault();
}
this.publisher.on("accessDialogOpened", preventOpeningAccessDialog);
this.publisher.on("accessDenied", preventOpeningAccessDialog);
this.listenTo(this.publisher, "accessDialogOpened accessDenied",
function(event) {
event.preventDefault();
});
this.publisher.on("streamCreated", function(event) {
this.listenTo(this.publisher, "streamCreated", function(event) {
this.setState({
audio: {enabled: event.stream.hasAudio},
video: {enabled: event.stream.hasVideo}
});
}.bind(this));
this.publisher.on("streamDestroyed", function() {
this.listenTo(this.publisher, "streamDestroyed", function() {
this.setState({
audio: {enabled: false},
video: {enabled: false}
@ -322,9 +321,8 @@ loop.shared.views = (function(_, OT, l10n) {
* Unpublishes local stream.
*/
stopPublishing: function() {
// Unregister access OT GuM custom dialog listeners, see bug 1018875
this.publisher.off("accessDialogOpened");
this.publisher.off("accessDenied");
// Unregister listeners for publisher events
this.stopListening(this.publisher);
this.props.model.session.unpublish(this.publisher);
},

View File

@ -0,0 +1,11 @@
#!/bin/sh
# Run from topsrcdir, no args
set -e
# Main tests
./mach xpcshell-test browser/components/loop/
./mach marionette-test browser/components/loop/manifest.ini
# The browser_parsable_css.js can fail if we add some css that isn't parsable.
./mach mochitest browser/components/loop/test/mochitest browser/base/content/test/general/browser_parsable_css.js

View File

@ -48,7 +48,7 @@ describe("loop.panel", function() {
return "en-US";
},
setLoopCharPref: sandbox.stub(),
getLoopCharPref: sandbox.stub()
getLoopCharPref: sandbox.stub().returns("unseen")
};
document.mozL10n.initialize(navigator.mozLoop);

View File

@ -194,12 +194,10 @@ describe("loop.shared.views", function() {
unpublish: sandbox.spy(),
subscribe: sandbox.spy()
}, Backbone.Events);
fakePublisher = {
on: sandbox.spy(),
off: sandbox.spy(),
fakePublisher = _.extend({
publishAudio: sandbox.spy(),
publishVideo: sandbox.spy()
};
}, Backbone.Events);
fakeSDK = {
initPublisher: sandbox.stub().returns(fakePublisher),
initSession: sandbox.stub().returns(fakeSession)
@ -248,6 +246,10 @@ describe("loop.shared.views", function() {
});
describe("#startPublishing", function() {
beforeEach(function() {
sandbox.stub(fakePublisher, "on");
});
it("should publish local stream", function() {
comp.startPublishing();
@ -261,13 +263,14 @@ describe("loop.shared.views", function() {
comp.startPublishing();
sinon.assert.called(fakePublisher.on);
sinon.assert.calledWith(fakePublisher.on, "accessDialogOpened");
sinon.assert.calledWith(fakePublisher.on, "accessDenied");
sinon.assert.calledWith(fakePublisher.on,
"accessDialogOpened accessDenied");
});
});
describe("#stopPublishing", function() {
beforeEach(function() {
sandbox.stub(fakePublisher, "off");
comp.startPublishing();
});
@ -277,13 +280,12 @@ describe("loop.shared.views", function() {
sinon.assert.calledOnce(fakeSession.unpublish);
});
it("should unsubscribe from accessDialogOpened and accessDenied events",
it("should unsubscribe from publisher events",
function() {
comp.stopPublishing();
sinon.assert.calledTwice(fakePublisher.off);
sinon.assert.calledWith(fakePublisher.off, "accessDialogOpened");
sinon.assert.calledWith(fakePublisher.off, "accessDenied");
// Note: Backbone.Events#stopListening calls off() on passed object.
sinon.assert.calledOnce(fakePublisher.off);
});
});
@ -367,6 +369,35 @@ describe("loop.shared.views", function() {
sinon.assert.calledOnce(fakeSession.unpublish);
});
});
describe("Publisher events", function() {
beforeEach(function() {
comp.startPublishing();
});
it("should set audio state on streamCreated", function() {
fakePublisher.trigger("streamCreated", {stream: {hasAudio: true}});
expect(comp.state.audio.enabled).eql(true);
fakePublisher.trigger("streamCreated", {stream: {hasAudio: false}});
expect(comp.state.audio.enabled).eql(false);
});
it("should set video state on streamCreated", function() {
fakePublisher.trigger("streamCreated", {stream: {hasVideo: true}});
expect(comp.state.video.enabled).eql(true);
fakePublisher.trigger("streamCreated", {stream: {hasVideo: false}});
expect(comp.state.video.enabled).eql(false);
});
it("should set media state on streamDestroyed", function() {
fakePublisher.trigger("streamDestroyed");
expect(comp.state.audio.enabled).eql(false);
expect(comp.state.video.enabled).eql(false);
});
});
});
});

View File

@ -65,7 +65,7 @@ add_task(function() {
add_task(function () {
const FRAME_SCRIPT = "data:," +
"docShell.QueryInterface%28Ci.nsILoadContext%29.usePrivateBrowsing%3Dtrue";
"docShell.QueryInterface%28Components.interfaces.nsILoadContext%29.usePrivateBrowsing%3Dtrue";
// Clear the list of closed windows.
while (ss.getClosedWindowCount()) {

View File

@ -4,6 +4,8 @@
"use strict";
let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
/**
* This frame script is only loaded for sessionstore mochitests. It contains
* a bunch of utility functions used to test form data collection and

View File

@ -16,11 +16,9 @@ MOZ_PKG_MANIFEST_P += $(topsrcdir)/b2g/installer/package-manifest.in
endif
# Some files have been already bundled with xulrunner
ifndef SYSTEM_LIBXUL
ifndef MOZ_MULET
MOZ_PKG_FATAL_WARNINGS = 1
endif
endif
DEFINES += -DAB_CD=$(AB_CD) -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)

View File

@ -746,8 +746,8 @@
@BINPATH@/components/pipnss.xpt
@BINPATH@/components/pippki.xpt
; For content sandboxing
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
; For process sandboxing
#if defined(XP_WIN)
@BINPATH@/@DLL_PREFIX@sandboxbroker@DLL_SUFFIX@
#endif

View File

@ -78,10 +78,6 @@
!define MOZ_METRO
#endif
#ifdef MOZ_CONTENT_SANDBOX
!define MOZ_CONTENT_SANDBOX
#endif
# File details shared by both the installer and uninstaller
VIProductVersion "1.0.0.0"
VIAddVersionKey "ProductName" "${BrandShortName}"

View File

@ -1499,9 +1499,7 @@ FunctionEnd
Push "nspr4.dll"
Push "nssdbm3.dll"
Push "mozsqlite3.dll"
!ifdef MOZ_CONTENT_SANDBOX
Push "sandboxbroker.dll"
!endif
Push "xpcom.dll"
Push "crashreporter.exe"
Push "updater.exe"

View File

@ -1,14 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
XPIDL_SOURCES += [
'nsIDomainPolicy.idl',
'nsIPrincipal.idl',
'nsIScriptSecurityManager.idl',
]
XPIDL_MODULE = 'caps'

View File

@ -1,11 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'nsJSPrincipals.h',
'nsNullPrincipal.h',
]

View File

@ -4,6 +4,37 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += ['idl', 'include', 'src']
TEST_DIRS += ['tests/mochitest']
XPIDL_SOURCES += [
'nsIDomainPolicy.idl',
'nsIPrincipal.idl',
'nsIScriptSecurityManager.idl',
]
XPIDL_MODULE = 'caps'
EXPORTS += [
'nsJSPrincipals.h',
'nsNullPrincipal.h',
]
UNIFIED_SOURCES += [
'DomainPolicy.cpp',
'nsJSPrincipals.cpp',
'nsNullPrincipal.cpp',
'nsNullPrincipalURI.cpp',
'nsPrincipal.cpp',
'nsScriptSecurityManager.cpp',
'nsSystemPrincipal.cpp',
]
MSVC_ENABLE_PGO = True
LOCAL_INCLUDES += [
'/dom/base',
'/js/xpconnect/src',
]
FINAL_LIBRARY = 'gklayout'

View File

@ -1,25 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES += [
'DomainPolicy.cpp',
'nsJSPrincipals.cpp',
'nsNullPrincipal.cpp',
'nsNullPrincipalURI.cpp',
'nsPrincipal.cpp',
'nsScriptSecurityManager.cpp',
'nsSystemPrincipal.cpp',
]
MSVC_ENABLE_PGO = True
LOCAL_INCLUDES += [
'../include',
'/dom/base',
'/js/xpconnect/src',
]
FINAL_LIBRARY = 'gklayout'

View File

@ -43,11 +43,6 @@ endif
EXEC = exec
# Don't copy xulrunner files at install time, when using system xulrunner
ifdef SYSTEM_LIBXUL
SKIP_COPY_XULRUNNER=1
endif
# ELOG prints out failed command when building silently (gmake -s). Pymake
# prints out failed commands anyway, so ELOG just makes things worse by
# forcing shell invocations.

View File

@ -2118,6 +2118,11 @@ ia64*-hpux*)
_DEFINES_CXXFLAGS='-FI $(DEPTH)/dist/include/mozilla-config.h -DMOZILLA_CLIENT'
CFLAGS="$CFLAGS -W3 -Gy"
CXXFLAGS="$CXXFLAGS -W3 -Gy"
if test "$_CC_SUITE" -ge "11"; then
dnl VS2012+ defaults to -arch:SSE2.
CFLAGS="$CFLAGS -arch:IA32"
CXXFLAGS="$CXXFLAGS -arch:IA32"
fi
if test "$_CC_SUITE" -ge "12"; then
dnl VS2013+ requires -FS when parallel building by make -jN.
dnl If nothing, compiler sometimes causes C1041 error.
@ -3422,33 +3427,11 @@ MOZ_ARG_HEADER(External Packages)
MOZ_ARG_WITH_STRING(libxul-sdk,
[ --with-libxul-sdk=PFX Use the libXUL SDK at <PFX>],
LIBXUL_SDK_DIR=$withval)
AC_MSG_ERROR([--with-libxul-sdk is not supported anymore.]))
if test "$LIBXUL_SDK_DIR" = "yes"; then
AC_MSG_ERROR([--with-libxul-sdk must specify a path])
elif test -n "$LIBXUL_SDK_DIR" -a "$LIBXUL_SDK_DIR" != "no"; then
LIBXUL_SDK=`cd "$LIBXUL_SDK_DIR" && pwd`
if test ! -f "$LIBXUL_SDK/include/xpcom-config.h"; then
AC_MSG_ERROR([$LIBXUL_SDK/include/xpcom-config.h doesn't exist])
fi
fi
AC_SUBST(LIBXUL_SDK)
if test -n "$LIBXUL_SDK"; then
LIBXUL_DIST="$LIBXUL_SDK"
else
LIBXUL_DIST="$MOZ_BUILD_ROOT/dist"
fi
LIBXUL_DIST="$MOZ_BUILD_ROOT/dist"
AC_SUBST(LIBXUL_DIST)
SYSTEM_LIBXUL=
MOZ_ARG_WITH_BOOL(system-libxul,
[ --with-system-libxul Use system installed libxul SDK],
SYSTEM_LIBXUL=1)
dnl ========================================================
dnl = If NSPR was not detected in the system,
dnl = use the one in the source tree (mozilla/nsprpub)
@ -3867,6 +3850,7 @@ MOZ_GSTREAMER=
MOZ_DIRECTSHOW=
MOZ_WMF=
MOZ_FMP4=
MOZ_EME=1
MOZ_FFMPEG=
MOZ_WEBRTC=1
MOZ_PEERCONNECTION=
@ -3874,7 +3858,7 @@ MOZ_SRTP=
MOZ_WEBRTC_SIGNALING=
MOZ_WEBRTC_ASSERT_ALWAYS=1
MOZ_SCTP=
MOZ_MEDIA_PLUGINS=
MOZ_ANDROID_OMX=
MOZ_MEDIA_NAVIGATOR=
MOZ_OMX_PLUGIN=
MOZ_VPX=
@ -5246,22 +5230,34 @@ if test -n "$MOZ_FMP4"; then
AC_DEFINE(MOZ_FMP4)
fi;
dnl ========================================================
dnl = EME support
dnl ========================================================
MOZ_ARG_DISABLE_BOOL(eme,
[ --disable-eme Disable support for Encrypted Media Extensions],
MOZ_EME=,
MOZ_EME=1)
if test -n "$MOZ_EME"; then
AC_DEFINE(MOZ_EME)
fi;
dnl ========================================================
dnl = Enable media plugin support
dnl ========================================================
if test "$OS_TARGET" = Android -a x"$MOZ_WIDGET_TOOLKIT" != x"gonk"; then
dnl Enable support on android by default
MOZ_MEDIA_PLUGINS=1
MOZ_ANDROID_OMX=1
fi
MOZ_ARG_ENABLE_BOOL(media-plugins,
[ --enable-media-plugins Enable support for media plugins],
MOZ_MEDIA_PLUGINS=1,
MOZ_MEDIA_PLUGINS=)
MOZ_ARG_ENABLE_BOOL(android-omx,
[ --enable-android-omx Enable support for Android OMX media backend],
MOZ_ANDROID_OMX=1,
MOZ_ANDROID_OMX=)
if test -n "$MOZ_MEDIA_PLUGINS"; then
AC_DEFINE(MOZ_MEDIA_PLUGINS)
if test -n "$MOZ_ANDROID_OMX"; then
AC_DEFINE(MOZ_ANDROID_OMX)
fi
dnl ========================================================
@ -8717,7 +8713,6 @@ HOST_CXXFLAGS=`echo \
$HOST_CXXFLAGS \
$_DEPEND_CFLAGS`
AC_SUBST(SYSTEM_LIBXUL)
AC_SUBST(MOZ_NATIVE_JPEG)
AC_SUBST(MOZ_NATIVE_PNG)
AC_SUBST(MOZ_NATIVE_BZ2)
@ -8825,8 +8820,9 @@ AC_SUBST(MOZ_WEBM)
AC_SUBST(MOZ_WMF)
AC_SUBST(MOZ_FFMPEG)
AC_SUBST(MOZ_FMP4)
AC_SUBST(MOZ_EME)
AC_SUBST(MOZ_DIRECTSHOW)
AC_SUBST(MOZ_MEDIA_PLUGINS)
AC_SUBST(MOZ_ANDROID_OMX)
AC_SUBST(MOZ_APPLEMEDIA)
AC_SUBST(MOZ_OMX_PLUGIN)
AC_SUBST(MOZ_VPX_ERROR_CONCEALMENT)

View File

@ -79,7 +79,8 @@ struct DOMPointInit;
} // namespace dom
} // namespace mozilla
#define NODE_FLAG_BIT(n_) (1U << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_)))
#define NODE_FLAG_BIT(n_) \
(nsWrapperCache::FlagsType(1U) << (WRAPPER_CACHE_FLAGS_BITS_USED + (n_)))
enum {
// This bit will be set if the node has a listener manager.

View File

@ -219,7 +219,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'gklayout'
LOCAL_INCLUDES += [
'/caps/include',
'/caps',
'/content/html/content/src',
'/content/html/document/src',
'/content/svg/content/src',

View File

@ -14,6 +14,7 @@
#include "nsError.h"
#include "nsIXPConnect.h"
#include "jsapi.h"
#include "jsfriendapi.h"
#include "nsJSUtils.h"
#include "nsJSPrincipals.h"
#include "nsNetUtil.h"
@ -429,9 +430,6 @@ nsFrameMessageManager::LoadFrameScript(const nsAString& aURL,
bool aAllowDelayedLoad,
bool aRunInGlobalScope)
{
// FIXME: Bug 673569 is currently disabled.
aRunInGlobalScope = true;
if (aAllowDelayedLoad) {
if (IsGlobal() || IsBroadcaster()) {
// Cache for future windows or frames
@ -1435,35 +1433,33 @@ nsFrameScriptExecutor::LoadFrameScriptInternal(const nsAString& aURL,
AutoSafeJSContext cx;
JS::Rooted<JSScript*> script(cx);
JS::Rooted<JSObject*> funobj(cx);
nsFrameScriptObjectExecutorHolder* holder = sCachedScripts->Get(aURL);
if (holder && holder->WillRunInGlobalScope() == aRunInGlobalScope) {
script = holder->mScript;
funobj = holder->mFunction;
} else {
// Don't put anything in the cache if we already have an entry
// with a different WillRunInGlobalScope() value.
bool shouldCache = !holder;
TryCacheLoadAndCompileScript(aURL, aRunInGlobalScope,
shouldCache, &script, &funobj);
shouldCache, &script);
}
JS::Rooted<JSObject*> global(cx, mGlobal->GetJSObject());
if (global) {
JSAutoCompartment ac(cx, global);
bool ok = true;
if (funobj) {
JS::Rooted<JSObject*> method(cx, JS_CloneFunctionObject(cx, funobj, global));
if (!method) {
return;
if (script) {
if (aRunInGlobalScope) {
ok = JS::CloneAndExecuteScript(cx, global, script);
} else {
JS::Rooted<JSObject*> scope(cx);
ok = js::ExecuteInGlobalAndReturnScope(cx, global, script, &scope);
if (ok){
// Force the scope to stay alive.
mAnonymousGlobalScopes.AppendElement(scope);
}
}
JS::Rooted<JS::Value> rval(cx);
JS::Rooted<JS::Value> methodVal(cx, JS::ObjectValue(*method));
ok = JS_CallFunctionValue(cx, global, methodVal,
JS::HandleValueArray::empty(), &rval);
} else if (script) {
ok = JS::CloneAndExecuteScript(cx, global, script);
}
if (!ok) {
@ -1476,8 +1472,7 @@ void
nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
bool aRunInGlobalScope,
bool aShouldCache,
JS::MutableHandle<JSScript*> aScriptp,
JS::MutableHandle<JSObject*> aFunp)
JS::MutableHandle<JSScript*> aScriptp)
{
nsCString url = NS_ConvertUTF16toUTF8(aURL);
nsCOMPtr<nsIURI> uri;
@ -1531,30 +1526,22 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
JSAutoCompartment ac(cx, global);
JS::CompileOptions options(cx);
options.setFileAndLine(url.get(), 1);
options.setNoScriptRval(true);
JS::Rooted<JSScript*> script(cx);
JS::Rooted<JSObject*> funobj(cx);
if (aRunInGlobalScope) {
options.setNoScriptRval(true);
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
return;
}
} else {
JS::Rooted<JSFunction *> fun(cx);
if (!JS::CompileFunction(cx, JS::NullPtr(), options,
nullptr, 0, nullptr, /* name, nargs, args */
srcBuf, &fun))
{
// We can't clone compile-and-go scripts.
options.setCompileAndGo(false);
if (!JS::Compile(cx, JS::NullPtr(), options, srcBuf, &script)) {
return;
}
funobj = JS_GetFunctionObject(fun);
}
if (!script && !funobj) {
return;
}
aScriptp.set(script);
aFunp.set(funobj);
nsAutoCString scheme;
uri->GetScheme(scheme);
@ -1564,9 +1551,7 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
// Root the object also for caching.
if (script) {
holder = new nsFrameScriptObjectExecutorHolder(cx, script);
} else {
holder = new nsFrameScriptObjectExecutorHolder(cx, funobj);
holder = new nsFrameScriptObjectExecutorHolder(cx, script, aRunInGlobalScope);
}
sCachedScripts->Put(aURL, holder);
}
@ -1580,8 +1565,7 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
{
AutoSafeJSContext cx;
JS::Rooted<JSScript*> script(cx);
JS::Rooted<JSObject*> funobj(cx);
TryCacheLoadAndCompileScript(aURL, aRunInGlobalScope, true, &script, &funobj);
TryCacheLoadAndCompileScript(aURL, aRunInGlobalScope, true, &script);
}
bool

View File

@ -360,21 +360,17 @@ class nsScriptCacheCleaner;
struct nsFrameScriptObjectExecutorHolder
{
nsFrameScriptObjectExecutorHolder(JSContext* aCx, JSScript* aScript)
: mScript(aCx, aScript), mFunction(aCx, nullptr)
{ MOZ_COUNT_CTOR(nsFrameScriptObjectExecutorHolder); }
nsFrameScriptObjectExecutorHolder(JSContext* aCx, JSObject* aFunction)
: mScript(aCx, nullptr), mFunction(aCx, aFunction)
nsFrameScriptObjectExecutorHolder(JSContext* aCx, JSScript* aScript, bool aRunInGlobalScope)
: mScript(aCx, aScript), mRunInGlobalScope(aRunInGlobalScope)
{ MOZ_COUNT_CTOR(nsFrameScriptObjectExecutorHolder); }
~nsFrameScriptObjectExecutorHolder()
{ MOZ_COUNT_DTOR(nsFrameScriptObjectExecutorHolder); }
bool WillRunInGlobalScope() { return mScript; }
bool WillRunInGlobalScope() { return mRunInGlobalScope; }
JS::PersistentRooted<JSScript*> mScript;
JS::PersistentRooted<JSObject*> mFunction;
bool mRunInGlobalScope;
};
class nsFrameScriptObjectExecutorStackHolder;
@ -390,22 +386,22 @@ public:
}
protected:
friend class nsFrameScriptCx;
nsFrameScriptExecutor()
{ MOZ_COUNT_CTOR(nsFrameScriptExecutor); }
~nsFrameScriptExecutor()
{ MOZ_COUNT_DTOR(nsFrameScriptExecutor); }
nsFrameScriptExecutor() { MOZ_COUNT_CTOR(nsFrameScriptExecutor); }
~nsFrameScriptExecutor() { MOZ_COUNT_DTOR(nsFrameScriptExecutor); }
void DidCreateGlobal();
void LoadFrameScriptInternal(const nsAString& aURL, bool aRunInGlobalScope);
void TryCacheLoadAndCompileScript(const nsAString& aURL,
bool aRunInGlobalScope,
bool aShouldCache,
JS::MutableHandle<JSScript*> aScriptp,
JS::MutableHandle<JSObject*> aFunp);
JS::MutableHandle<JSScript*> aScriptp);
void TryCacheLoadAndCompileScript(const nsAString& aURL,
bool aRunInGlobalScope);
bool InitTabChildGlobalInternal(nsISupports* aScope, const nsACString& aID);
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsAutoTArray<JS::Heap<JSObject*>, 2> mAnonymousGlobalScopes;
static nsDataHashtable<nsStringHashKey, nsFrameScriptObjectExecutorHolder*>* sCachedScripts;
static nsScriptCacheCleaner* sScriptCacheCleaner;
};

View File

@ -103,6 +103,7 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
: mDocShell(aShell), mInitialized(false), mLoadingScript(false),
mOwner(aOwner), mChromeMessageManager(aChrome)
{
mozilla::HoldJSObjects(this);
// If owner corresponds to an <iframe mozbrowser> or <iframe mozapp>, we'll
// have to tweak our PreHandleEvent implementation.
@ -117,6 +118,8 @@ nsInProcessTabChildGlobal::nsInProcessTabChildGlobal(nsIDocShell* aShell,
nsInProcessTabChildGlobal::~nsInProcessTabChildGlobal()
{
mAnonymousGlobalScopes.Clear();
mozilla::DropJSObjects(this);
}
/* [notxpcom] boolean markForCC (); */
@ -143,10 +146,28 @@ nsInProcessTabChildGlobal::Init()
return NS_OK;
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal,
DOMEventTargetHelper,
mMessageManager,
mGlobal)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
DOMEventTargetHelper)
for (uint32_t i = 0; i < tmp->mAnonymousGlobalScopes.Length(); ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAnonymousGlobalScopes[i])
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnonymousGlobalScopes)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsInProcessTabChildGlobal)
NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)

View File

@ -39,8 +39,9 @@ public:
nsInProcessTabChildGlobal(nsIDocShell* aShell, nsIContent* aOwner,
nsFrameMessageManager* aChrome);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsInProcessTabChildGlobal,
mozilla::DOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(nsInProcessTabChildGlobal,
mozilla::DOMEventTargetHelper)
NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,

View File

@ -1417,7 +1417,7 @@ nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
}
rv = NS_OK;
} else {
NS_Free(const_cast<uint8_t *>(aString));
moz_free(const_cast<uint8_t *>(aString));
rv = NS_SUCCESS_ADOPTED_DATA;
}

View File

@ -125,6 +125,8 @@ function async_test()
async_obj);
}
var rpc_obj;
function rpc_test()
{
dump('beginning cpow rpc test\n');

View File

@ -2173,7 +2173,7 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
mBoundFramebuffer->ColorAttachmentCount() &&
mBoundFramebuffer->ColorAttachment(0).IsDefined())
{
isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsReadableFloat();
isSourceTypeFloat = mBoundFramebuffer->ColorAttachment(0).IsFloatType();
}
if (isReadTypeFloat != isSourceTypeFloat)

View File

@ -62,14 +62,17 @@ WebGLFramebuffer::Attachment::HasAlpha() const
}
bool
WebGLFramebuffer::Attachment::IsReadableFloat() const
WebGLFramebuffer::Attachment::IsFloatType(FloatType floatType) const
{
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
GLenum type = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLType();
switch (type) {
case LOCAL_GL_FLOAT:
return floatType == FloatType::Full ||
floatType == FloatType::Any;
case LOCAL_GL_HALF_FLOAT_OES:
return true;
return floatType == FloatType::Half ||
floatType == FloatType::Any;
}
return false;
}
@ -79,9 +82,12 @@ WebGLFramebuffer::Attachment::IsReadableFloat() const
switch (format) {
case LOCAL_GL_RGB16F:
case LOCAL_GL_RGBA16F:
return floatType == FloatType::Half ||
floatType == FloatType::Any;
case LOCAL_GL_RGB32F:
case LOCAL_GL_RGBA32F:
return true;
return floatType == FloatType::Full ||
floatType == FloatType::Any;
}
return false;
}
@ -630,6 +636,26 @@ WebGLFramebuffer::HasIncompleteAttachments() const
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
hasIncomplete |= IsIncomplete(mColorAttachments[i]);
if (mColorAttachments[i].IsDefined()) {
// Excerpt from http://www.khronos.org/registry/webgl/extensions/OES_texture_float/
// New implementations should not implicitly support float rendering and
// applications should be modified to explicitly enable WEBGL_color_buffer_float.
if (mColorAttachments[i].IsFloatType(Attachment::FloatType::Full) &&
!Context()->IsExtensionEnabled(WebGLExtensionID::WEBGL_color_buffer_float))
{
hasIncomplete |= true;
}
// Excerpt from http://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/
// New implementations should not implicitly support float rendering and
// applications should be modified to explicitly enable OES_color_buffer_half_float.
if (mColorAttachments[i].IsFloatType(Attachment::FloatType::Half) &&
!Context()->IsExtensionEnabled(WebGLExtensionID::EXT_color_buffer_half_float))
{
hasIncomplete |= true;
}
}
}
hasIncomplete |= IsIncomplete(mDepthAttachment);

View File

@ -11,6 +11,7 @@
#include "nsWrapperCache.h"
#include "mozilla/LinkedList.h"
#include "mozilla/TypedEnum.h"
namespace mozilla {
@ -52,7 +53,15 @@ public:
bool IsDeleteRequested() const;
bool HasAlpha() const;
bool IsReadableFloat() const;
// For IsFloatType()
MOZ_BEGIN_NESTED_ENUM_CLASS(FloatType)
Any = 0,
Half,
Full
MOZ_END_NESTED_ENUM_CLASS(FloatType)
bool IsFloatType(FloatType floatType = FloatType::Any) const;
void SetTexImage(WebGLTexture* tex, GLenum target, GLint level);
void SetRenderbuffer(WebGLRenderbuffer* rb);
@ -196,6 +205,8 @@ private:
mDepthStencilAttachment;
};
MOZ_FINISH_NESTED_ENUM_CLASS(WebGLFramebuffer::Attachment::FloatType)
} // namespace mozilla
#endif

View File

@ -156,14 +156,10 @@ function runRenderTargetTest(testProgram)
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.bindTexture(gl.TEXTURE_2D, null);
shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
// While strictly speaking it is probably legal for a WebGL implementation to support
// floating-point textures but not as attachments to framebuffer objects, any such
// implementation is so poor that it arguably should not advertise support for the
// OES_texture_float extension. For this reason the conformance test requires that the
// framebuffer is complete here.
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
debug("floating-point " + formatString + " render target not supported -- this is legal");
return;
}
var renderProgram =
wtu.setupProgram(gl,

View File

@ -1,4 +1,3 @@
conformance/extensions/oes-texture-float.html
conformance/extensions/oes-vertex-array-object.html
conformance/glsl/functions/glsl-function-abs.html
conformance/glsl/functions/glsl-function-faceforward.html

View File

@ -1,5 +1,4 @@
# Failures for our android x86 and arm emulator test environments.
conformance/extensions/oes-texture-float.html
conformance/programs/get-active-test.html
conformance/textures/texture-npot.html

View File

@ -1,3 +1,2 @@
conformance/textures/texture-size-cube-maps.html
conformance/extensions/oes-texture-float.html
conformance/glsl/functions/glsl-function-sin.html

View File

@ -1,3 +1,10 @@
# OES-texture-float is failing on Android 2.3, but not Android 4.0 when
# there is a way to differentiate these two slaves this should be removed
# and updated as appropriately. The Android 2.3 slave is returning red
# when it should be green. This is believed to be a driver bug and not
# FF bug at the moment.
conformance/extensions/oes-texture-float.html
conformance/extensions/oes-vertex-array-object.html
conformance/glsl/functions/glsl-function-abs.html
conformance/glsl/functions/glsl-function-faceforward.html

View File

@ -18,9 +18,12 @@
#include "nsIAudioChannelAgent.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/TextTrackManager.h"
#include "MediaDecoder.h"
#ifdef MOZ_EME
#include "mozilla/dom/MediaKeys.h"
#endif
// Something on Linux #defines None, which is an entry in the
// MediaWaitingFor enum, so undef it here before including the binfing,
@ -521,6 +524,7 @@ public:
// XPCOM MozPreservesPitch() is OK
#ifdef MOZ_EME
MediaKeys* GetMediaKeys() const;
already_AddRefed<Promise> SetMediaKeys(MediaKeys* mediaKeys,
@ -536,6 +540,7 @@ public:
bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
#endif // MOZ_EME
bool MozAutoplayEnabled() const
{
@ -1076,8 +1081,10 @@ protected:
// Range of time played.
nsRefPtr<TimeRanges> mPlayed;
#ifdef MOZ_EME
// Encrypted Media Extension media keys.
nsRefPtr<MediaKeys> mMediaKeys;
#endif
// Stores the time at the start of the current 'played' range.
double mCurrentPlayRangeStart;

View File

@ -17,6 +17,7 @@
#include "nsIDOMNode.h"
#include "nsIDOMNodeList.h"
#include "nsIFormControl.h"
#include "RadioNodeList.h"
#include "jsfriendapi.h"
namespace mozilla {
@ -347,18 +348,18 @@ HTMLFormControlsCollection::GetParentObject()
/* virtual */ Element*
HTMLFormControlsCollection::GetFirstNamedElement(const nsAString& aName, bool& aFound)
{
Nullable<OwningNodeListOrElement> maybeResult;
Nullable<OwningRadioNodeListOrElement> maybeResult;
NamedGetter(aName, aFound, maybeResult);
if (!aFound) {
return nullptr;
}
MOZ_ASSERT(!maybeResult.IsNull());
const OwningNodeListOrElement& result = maybeResult.Value();
const OwningRadioNodeListOrElement& result = maybeResult.Value();
if (result.IsElement()) {
return result.GetAsElement().get();
}
if (result.IsNodeList()) {
nsINodeList& nodelist = result.GetAsNodeList();
if (result.IsRadioNodeList()) {
RadioNodeList& nodelist = result.GetAsRadioNodeList();
return nodelist.Item(0)->AsElement();
}
MOZ_ASSERT_UNREACHABLE("Should only have Elements and NodeLists here.");
@ -368,7 +369,7 @@ HTMLFormControlsCollection::GetFirstNamedElement(const nsAString& aName, bool& a
void
HTMLFormControlsCollection::NamedGetter(const nsAString& aName,
bool& aFound,
Nullable<OwningNodeListOrElement>& aResult)
Nullable<OwningRadioNodeListOrElement>& aResult)
{
nsISupports* item = NamedItemInternal(aName, true);
if (!item) {
@ -380,8 +381,8 @@ HTMLFormControlsCollection::NamedGetter(const nsAString& aName,
aResult.SetValue().SetAsElement() = element;
return;
}
if (nsCOMPtr<nsINodeList> nodelist = do_QueryInterface(item)) {
aResult.SetValue().SetAsNodeList() = nodelist;
if (nsCOMPtr<RadioNodeList> nodelist = do_QueryInterface(item)) {
aResult.SetValue().SetAsRadioNodeList() = nodelist;
return;
}
MOZ_ASSERT_UNREACHABLE("Should only have Elements and NodeLists here.");

View File

@ -20,7 +20,7 @@ namespace mozilla {
namespace dom {
class HTMLFormElement;
class HTMLImageElement;
class OwningNodeListOrElement;
class OwningRadioNodeListOrElement;
template<typename> struct Nullable;
class HTMLFormControlsCollection : public nsIHTMLCollection
@ -45,10 +45,10 @@ public:
void
NamedGetter(const nsAString& aName,
bool& aFound,
Nullable<OwningNodeListOrElement>& aResult);
Nullable<OwningRadioNodeListOrElement>& aResult);
void
NamedItem(const nsAString& aName,
Nullable<OwningNodeListOrElement>& aResult)
Nullable<OwningRadioNodeListOrElement>& aResult)
{
bool dummy;
NamedGetter(aName, dummy, aResult);

View File

@ -48,6 +48,7 @@
// radio buttons
#include "mozilla/dom/HTMLInputElement.h"
#include "nsIRadioVisitor.h"
#include "RadioNodeList.h"
#include "nsLayoutUtils.h"
@ -2282,7 +2283,7 @@ HTMLFormElement::AddElementToTableInternal(
// Found an element, create a list, add the element to the list and put
// the list in the hash
nsSimpleContentList *list = new nsSimpleContentList(this);
RadioNodeList *list = new RadioNodeList(this);
// If an element has a @form, we can assume it *might* be able to not have
// a parent and still be in the form.
@ -2306,8 +2307,8 @@ HTMLFormElement::AddElementToTableInternal(
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE);
// Upcast, uggly, but it works!
nsSimpleContentList *list =
static_cast<nsSimpleContentList*>(nodeList.get());
RadioNodeList *list =
static_cast<RadioNodeList*>(nodeList.get());
NS_ASSERTION(list->Length() > 1,
"List should have been converted back to a single element");

View File

@ -10,8 +10,10 @@
#include "mozilla/dom/ElementInlines.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/MathAlgorithms.h"
#include "mozilla/dom/MediaKeyNeededEvent.h"
#include "mozilla/AsyncEventDispatcher.h"
#ifdef MOZ_EME
#include "mozilla/dom/MediaKeyNeededEvent.h"
#endif
#include "base/basictypes.h"
#include "nsIDOMHTMLMediaElement.h"
@ -430,7 +432,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTM
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTextTrackManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioTrackList)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVideoTrackList)
#ifdef MOZ_EME
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeys)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
@ -453,7 +457,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLE
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTextTrackManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioTrackList)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mVideoTrackList)
#ifdef MOZ_EME
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMediaKeys)
#endif
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLMediaElement)
@ -3943,6 +3949,7 @@ NS_IMETHODIMP HTMLMediaElement::CanPlayChanged(int32_t canPlay)
return NS_OK;
}
#ifdef MOZ_EME
MediaKeys*
HTMLMediaElement::GetMediaKeys() const
{
@ -4008,6 +4015,7 @@ HTMLMediaElement::IsEventAttributeName(nsIAtom* aName)
return aName == nsGkAtoms::onneedkey ||
nsGenericHTMLElement::IsEventAttributeName(aName);
}
#endif // MOZ_EME
NS_IMETHODIMP HTMLMediaElement::WindowVolumeChanged()
{

View File

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/RadioNodeList.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/RadioNodeListBinding.h"
#include "js/TypeDecls.h"
#include "HTMLInputElement.h"
namespace mozilla {
namespace dom {
/* virtual */ JSObject*
RadioNodeList::WrapObject(JSContext* aCx)
{
return RadioNodeListBinding::Wrap(aCx, this);
}
HTMLInputElement*
GetAsRadio(nsIContent* node)
{
HTMLInputElement* el = HTMLInputElement::FromContent(node);
if (el && el->GetType() == NS_FORM_INPUT_RADIO) {
return el;
}
return nullptr;
}
void
RadioNodeList::GetValue(nsString& retval)
{
for (uint32_t i = 0; i < Length(); i++) {
HTMLInputElement* maybeRadio = GetAsRadio(Item(i));
if (maybeRadio && maybeRadio->Checked()) {
maybeRadio->GetValue(retval);
return;
}
}
retval.Truncate();
}
void
RadioNodeList::SetValue(const nsAString& value)
{
for (uint32_t i = 0; i < Length(); i++) {
HTMLInputElement* maybeRadio = GetAsRadio(Item(i));
if (!maybeRadio) {
continue;
}
nsString curval = nsString();
maybeRadio->GetValue(curval);
if (curval.Equals(value)) {
maybeRadio->SetChecked(true);
return;
}
}
}
NS_IMPL_ISUPPORTS_INHERITED(RadioNodeList, nsSimpleContentList, RadioNodeList)
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,41 @@
/* -*- 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_RadioNodeList_h
#define mozilla_dom_RadioNodeList_h
#include "nsContentList.h"
#include "nsCOMPtr.h"
#include "HTMLFormElement.h"
#define MOZILLA_DOM_RADIONODELIST_IMPLEMENTATION_IID \
{ 0xbba7f3e8, 0xf3b5, 0x42e5, \
{ 0x82, 0x08, 0xa6, 0x8b, 0xe0, 0xbc, 0x22, 0x19 } }
namespace mozilla {
namespace dom {
class RadioNodeList : public nsSimpleContentList
{
public:
RadioNodeList(HTMLFormElement* aForm) : nsSimpleContentList(aForm) { }
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
void GetValue(nsString& retval);
void SetValue(const nsAString& value);
NS_DECL_ISUPPORTS_INHERITED
NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOM_RADIONODELIST_IMPLEMENTATION_IID)
private:
~RadioNodeList() { }
};
NS_DEFINE_STATIC_IID_ACCESSOR(RadioNodeList, MOZILLA_DOM_RADIONODELIST_IMPLEMENTATION_IID)
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_RadioNodeList_h

View File

@ -72,6 +72,7 @@ EXPORTS.mozilla.dom += [
'HTMLTrackElement.h',
'HTMLUnknownElement.h',
'MediaError.h',
'RadioNodeList.h',
'TextTrackManager.h',
'TimeRanges.h',
'UndoManager.h',
@ -154,6 +155,7 @@ UNIFIED_SOURCES += [
'nsIConstraintValidation.cpp',
'nsRadioVisitor.cpp',
'nsTextEditorState.cpp',
'RadioNodeList.cpp',
'TextTrackManager.cpp',
'TimeRanges.cpp',
'UndoManager.cpp',

View File

@ -72,6 +72,7 @@ skip-if = e10s
[test_output_element.html]
[test_pattern_attribute.html]
[test_progress_element.html]
[test_radio_radionodelist.html]
[test_required_attribute.html]
skip-if = e10s
[test_restore_form_elements.html]

View File

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=779723
-->
<head>
<title>Test for Bug 779723</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=779723">Mozilla Bug 779723</a>
<p id="display"></p>
<form>
<input type="checkbox" name="rdo" value="0" id="r0" checked="checked">
<input type="radio" name="rdo" id="r1">
<input type="radio" name="rdo" id="r2" value="2">
</form>
<script class="testbody" type="text/javascript">
/** Test for Bug 779723 **/
var rdoList = document.forms[0].elements.namedItem('rdo');
ise(rdoList.value, "", "The value attribute should be empty");
document.getElementById('r2').checked = true;
ok(rdoList.value, "2", "The value attribute should be 2");
document.getElementById('r1').checked = true;
ok(rdoList.value, "on", "The value attribute should be on");
document.getElementById('r1').value = 1;
ok(rdoList.value, "1", "The value attribute should be 1");
ise(rdoList.value, document.getElementById('r1').value,
"The value attribute should be equal to the first checked radio input element's value");
ok(!document.getElementById('r2').checked,
"The second radio input element should not be checked");
rdoList.value = '2';
ise(rdoList.value, document.getElementById('r2').value,
"The value attribute should be equal to the second radio input element's value");
ok(document.getElementById('r2').checked,
"The second radio input element should be checked");
rdoList.value = '3';
ise(rdoList.value, document.getElementById('r2').value,
"The value attribute should be the second radio input element's value");
ok(document.getElementById('r2').checked,
"The second radio input element should be checked");
</script>
</pre>
</body>
</html>

View File

@ -33,7 +33,7 @@ MSVC_ENABLE_PGO = True
LOCAL_INCLUDES += [
'../../content/src',
'/caps/include',
'/caps',
'/content/base/src',
'/docshell/base',
'/dom/base',

View File

@ -9,8 +9,8 @@
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/Preferences.h"
#ifdef MOZ_MEDIA_PLUGINS
#include "MediaPluginHost.h"
#ifdef MOZ_ANDROID_OMX
#include "AndroidMediaPluginHost.h"
#endif
#include "OggDecoder.h"
@ -31,11 +31,11 @@
#include "GStreamerDecoder.h"
#include "GStreamerReader.h"
#endif
#ifdef MOZ_MEDIA_PLUGINS
#include "MediaPluginHost.h"
#include "MediaPluginDecoder.h"
#include "MediaPluginReader.h"
#include "MediaPluginHost.h"
#ifdef MOZ_ANDROID_OMX
#include "AndroidMediaPluginHost.h"
#include "AndroidMediaDecoder.h"
#include "AndroidMediaReader.h"
#include "AndroidMediaPluginHost.h"
#endif
#ifdef MOZ_OMX_DECODER
#include "MediaOmxDecoder.h"
@ -283,11 +283,11 @@ bool DecoderTraits::DecoderWaitsForOnConnected(const nsACString& aMimeType) {
#endif
}
#ifdef MOZ_MEDIA_PLUGINS
#ifdef MOZ_ANDROID_OMX
static bool
IsMediaPluginsType(const nsACString& aType)
IsAndroidMediaType(const nsACString& aType)
{
if (!MediaDecoder::IsMediaPluginsEnabled()) {
if (!MediaDecoder::IsAndroidMediaEnabled()) {
return false;
}
@ -451,9 +451,9 @@ DecoderTraits::CanHandleMediaType(const char* aMIMEType,
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_MEDIA_PLUGINS
if (MediaDecoder::IsMediaPluginsEnabled() &&
GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaEnabled() &&
GetAndroidMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
result = CANPLAY_MAYBE;
#endif
#ifdef NECKO_PROTOCOL_rtsp
@ -547,10 +547,10 @@ InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
return decoder.forget();
}
#endif
#ifdef MOZ_MEDIA_PLUGINS
if (MediaDecoder::IsMediaPluginsEnabled() &&
GetMediaPluginHost()->FindDecoder(aType, nullptr)) {
decoder = new MediaPluginDecoder(aType);
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaEnabled() &&
GetAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
decoder = new AndroidMediaDecoder(aType);
return decoder.forget();
}
#endif
@ -630,10 +630,10 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
decoderReader = new MediaOmxReader(aDecoder);
} else
#endif
#ifdef MOZ_MEDIA_PLUGINS
if (MediaDecoder::IsMediaPluginsEnabled() &&
GetMediaPluginHost()->FindDecoder(aType, nullptr)) {
decoderReader = new MediaPluginReader(aDecoder, aType);
#ifdef MOZ_ANDROID_OMX
if (MediaDecoder::IsAndroidMediaEnabled() &&
GetAndroidMediaPluginHost()->FindDecoder(aType, nullptr)) {
decoderReader = new AndroidMediaReader(aDecoder, aType);
} else
#endif
#ifdef MOZ_WEBM
@ -679,8 +679,8 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
#ifdef MOZ_GSTREAMER
IsGStreamerSupportedType(aType) ||
#endif
#ifdef MOZ_MEDIA_PLUGINS
(MediaDecoder::IsMediaPluginsEnabled() && IsMediaPluginsType(aType)) ||
#ifdef MOZ_ANDROID_OMX
(MediaDecoder::IsAndroidMediaEnabled() && IsAndroidMediaType(aType)) ||
#endif
#ifdef MOZ_FMP4
IsMP4SupportedType(aType) ||

View File

@ -1719,9 +1719,9 @@ MediaDecoder::IsOmxEnabled()
}
#endif
#ifdef MOZ_MEDIA_PLUGINS
#ifdef MOZ_ANDROID_OMX
bool
MediaDecoder::IsMediaPluginsEnabled()
MediaDecoder::IsAndroidMediaEnabled()
{
return Preferences::GetBool("media.plugins.enabled");
}

View File

@ -875,8 +875,8 @@ public:
static bool IsOmxEnabled();
#endif
#ifdef MOZ_MEDIA_PLUGINS
static bool IsMediaPluginsEnabled();
#ifdef MOZ_ANDROID_OMX
static bool IsAndroidMediaEnabled();
#endif
#ifdef MOZ_WMF

View File

@ -49,11 +49,7 @@ public:
// Forward behaviour to wrapped thread pool implementation.
NS_FORWARD_SAFE_NSITHREADPOOL(mPool);
NS_FORWARD_SAFE_NSIEVENTTARGET(GetEventTarget());
nsIEventTarget* GetEventTarget() {
return mEventTarget;
}
NS_FORWARD_SAFE_NSIEVENTTARGET(mEventTarget);
private:

View File

@ -5,18 +5,18 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaDecoderStateMachine.h"
#include "MediaPluginDecoder.h"
#include "MediaPluginReader.h"
#include "AndroidMediaDecoder.h"
#include "AndroidMediaReader.h"
namespace mozilla {
MediaPluginDecoder::MediaPluginDecoder(const nsACString& aType) : mType(aType)
AndroidMediaDecoder::AndroidMediaDecoder(const nsACString& aType) : mType(aType)
{
}
MediaDecoderStateMachine* MediaPluginDecoder::CreateStateMachine()
MediaDecoderStateMachine* AndroidMediaDecoder::CreateStateMachine()
{
return new MediaDecoderStateMachine(this, new MediaPluginReader(this, mType));
return new MediaDecoderStateMachine(this, new AndroidMediaReader(this, mType));
}
} // namespace mozilla

View File

@ -3,26 +3,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(MediaPluginDecoder_h_)
#define MediaPluginDecoder_h_
#if !defined(AndroidMediaDecoder_h_)
#define AndroidMediaDecoder_h_
#include "MediaDecoder.h"
#include "MediaPluginDecoder.h"
#include "AndroidMediaDecoder.h"
namespace mozilla {
class MediaPluginDecoder : public MediaDecoder
class AndroidMediaDecoder : public MediaDecoder
{
nsCString mType;
public:
MediaPluginDecoder(const nsACString& aType);
AndroidMediaDecoder(const nsACString& aType);
const nsresult GetContentType(nsACString& aType) const {
aType = mType;
return NS_OK;
}
virtual MediaDecoder* Clone() { return new MediaPluginDecoder(mType); }
virtual MediaDecoder* Clone() { return new AndroidMediaDecoder(mType); }
virtual MediaDecoderStateMachine* CreateStateMachine();
};

View File

@ -7,15 +7,15 @@
#include "mozilla/dom/TimeRanges.h"
#include "MediaResource.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "MediaPluginHost.h"
#include "AndroidMediaPluginHost.h"
#include "nsXPCOMStrings.h"
#include "nsISeekableStream.h"
#include "MediaPluginReader.h"
#include "AndroidMediaReader.h"
#include "nsIGfxInfo.h"
#include "gfxCrashReporterUtils.h"
#include "prmem.h"
#include "prlink.h"
#include "MediaResourceServer.h"
#include "AndroidMediaResourceServer.h"
#include "nsServiceManagerUtils.h"
#include "MPAPI.h"
@ -24,7 +24,7 @@
#if defined(ANDROID) || defined(MOZ_WIDGET_GONK)
#include "android/log.h"
#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "MediaPluginHost" , ## args)
#define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidMediaPluginHost" , ## args)
#else
#define ALOG(args...) /* do nothing */
#endif
@ -213,10 +213,10 @@ static const char* GetOmxLibraryName()
#endif
}
MediaPluginHost::MediaPluginHost() {
MOZ_COUNT_CTOR(MediaPluginHost);
AndroidMediaPluginHost::AndroidMediaPluginHost() {
MOZ_COUNT_CTOR(AndroidMediaPluginHost);
mResourceServer = MediaResourceServer::Start();
mResourceServer = AndroidMediaResourceServer::Start();
const char* name = GetOmxLibraryName();
ALOG("Loading OMX Plugin: %s", name ? name : "nullptr");
@ -246,12 +246,12 @@ MediaPluginHost::MediaPluginHost() {
}
}
MediaPluginHost::~MediaPluginHost() {
AndroidMediaPluginHost::~AndroidMediaPluginHost() {
mResourceServer->Stop();
MOZ_COUNT_DTOR(MediaPluginHost);
MOZ_COUNT_DTOR(AndroidMediaPluginHost);
}
bool MediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const** aCodecs)
bool AndroidMediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const** aCodecs)
{
const char *chars;
size_t len = NS_CStringGetData(aMimeType, &chars, nullptr);
@ -267,7 +267,7 @@ bool MediaPluginHost::FindDecoder(const nsACString& aMimeType, const char* const
return false;
}
MPAPI::Decoder *MediaPluginHost::CreateDecoder(MediaResource *aResource, const nsACString& aMimeType)
MPAPI::Decoder *AndroidMediaPluginHost::CreateDecoder(MediaResource *aResource, const nsACString& aMimeType)
{
NS_ENSURE_TRUE(aResource, nullptr);
@ -299,7 +299,7 @@ MPAPI::Decoder *MediaPluginHost::CreateDecoder(MediaResource *aResource, const n
return nullptr;
}
void MediaPluginHost::DestroyDecoder(Decoder *aDecoder)
void AndroidMediaPluginHost::DestroyDecoder(Decoder *aDecoder)
{
aDecoder->DestroyDecoder(aDecoder);
char* resource = GetResource(aDecoder);
@ -312,19 +312,19 @@ void MediaPluginHost::DestroyDecoder(Decoder *aDecoder)
delete aDecoder;
}
MediaPluginHost *sMediaPluginHost = nullptr;
MediaPluginHost *GetMediaPluginHost()
AndroidMediaPluginHost *sAndroidMediaPluginHost = nullptr;
AndroidMediaPluginHost *GetAndroidMediaPluginHost()
{
if (!sMediaPluginHost) {
sMediaPluginHost = new MediaPluginHost();
if (!sAndroidMediaPluginHost) {
sAndroidMediaPluginHost = new AndroidMediaPluginHost();
}
return sMediaPluginHost;
return sAndroidMediaPluginHost;
}
void MediaPluginHost::Shutdown()
void AndroidMediaPluginHost::Shutdown()
{
delete sMediaPluginHost;
sMediaPluginHost = nullptr;
delete sAndroidMediaPluginHost;
sAndroidMediaPluginHost = nullptr;
}
} // namespace mozilla

View File

@ -3,26 +3,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(MediaPluginHost_h_)
#define MediaPluginHost_h_
#if !defined(AndroidMediaPluginHost_h_)
#define AndroidMediaPluginHost_h_
#include "nsTArray.h"
#include "MediaResource.h"
#include "MPAPI.h"
#include "MediaResourceServer.h"
#include "AndroidMediaResourceServer.h"
namespace mozilla {
class MediaPluginReader;
class AndroidMediaReader;
class MediaPluginHost {
nsRefPtr<MediaResourceServer> mResourceServer;
class AndroidMediaPluginHost {
nsRefPtr<AndroidMediaResourceServer> mResourceServer;
nsTArray<MPAPI::Manifest *> mPlugins;
MPAPI::Manifest *FindPlugin(const nsACString& aMimeType);
public:
MediaPluginHost();
~MediaPluginHost();
AndroidMediaPluginHost();
~AndroidMediaPluginHost();
static void Shutdown();
@ -31,7 +31,7 @@ public:
void DestroyDecoder(MPAPI::Decoder *aDecoder);
};
MediaPluginHost *GetMediaPluginHost();
AndroidMediaPluginHost *GetAndroidMediaPluginHost();
} // namespace mozilla

View File

@ -3,14 +3,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MediaPluginReader.h"
#include "AndroidMediaReader.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/TimeRanges.h"
#include "mozilla/gfx/Point.h"
#include "MediaResource.h"
#include "VideoUtils.h"
#include "MediaPluginDecoder.h"
#include "MediaPluginHost.h"
#include "AndroidMediaDecoder.h"
#include "AndroidMediaPluginHost.h"
#include "MediaDecoderStateMachine.h"
#include "ImageContainer.h"
#include "AbstractMediaDecoder.h"
@ -23,8 +23,8 @@ using namespace mozilla::gfx;
typedef mozilla::layers::Image Image;
typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage;
MediaPluginReader::MediaPluginReader(AbstractMediaDecoder *aDecoder,
const nsACString& aContentType) :
AndroidMediaReader::AndroidMediaReader(AbstractMediaDecoder *aDecoder,
const nsACString& aContentType) :
MediaDecoderReader(aDecoder),
mType(aContentType),
mPlugin(nullptr),
@ -35,18 +35,18 @@ MediaPluginReader::MediaPluginReader(AbstractMediaDecoder *aDecoder,
{
}
nsresult MediaPluginReader::Init(MediaDecoderReader* aCloneDonor)
nsresult AndroidMediaReader::Init(MediaDecoderReader* aCloneDonor)
{
return NS_OK;
}
nsresult MediaPluginReader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
nsresult AndroidMediaReader::ReadMetadata(MediaInfo* aInfo,
MetadataTags** aTags)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
if (!mPlugin) {
mPlugin = GetMediaPluginHost()->CreateDecoder(mDecoder->GetResource(), mType);
mPlugin = GetAndroidMediaPluginHost()->CreateDecoder(mDecoder->GetResource(), mType);
if (!mPlugin) {
return NS_ERROR_FAILURE;
}
@ -99,17 +99,17 @@ nsresult MediaPluginReader::ReadMetadata(MediaInfo* aInfo,
return NS_OK;
}
void MediaPluginReader::Shutdown()
void AndroidMediaReader::Shutdown()
{
ResetDecode();
if (mPlugin) {
GetMediaPluginHost()->DestroyDecoder(mPlugin);
GetAndroidMediaPluginHost()->DestroyDecoder(mPlugin);
mPlugin = nullptr;
}
}
// Resets all state related to decoding, emptying all buffers etc.
nsresult MediaPluginReader::ResetDecode()
nsresult AndroidMediaReader::ResetDecode()
{
if (mLastVideoFrame) {
mLastVideoFrame = nullptr;
@ -117,8 +117,8 @@ nsresult MediaPluginReader::ResetDecode()
return MediaDecoderReader::ResetDecode();
}
bool MediaPluginReader::DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold)
bool AndroidMediaReader::DecodeVideoFrame(bool &aKeyframeSkip,
int64_t aTimeThreshold)
{
// Record number of frames decoded and parsed. Automatically update the
// stats counters using the AutoNotifyDecoded stack-based class.
@ -248,10 +248,10 @@ bool MediaPluginReader::DecodeVideoFrame(bool &aKeyframeSkip,
}
parsed++;
decoded++;
NS_ASSERTION(decoded <= parsed, "Expect to decode fewer frames than parsed in MediaPlugin...");
NS_ASSERTION(decoded <= parsed, "Expect to decode fewer frames than parsed in AndroidMedia...");
// Since MPAPI doesn't give us the end time of frames, we keep one frame
// buffered in MediaPluginReader and push it into the queue as soon
// buffered in AndroidMediaReader and push it into the queue as soon
// we read the following frame so we can use that frame's start time as
// the end time of the buffered frame.
if (!mLastVideoFrame) {
@ -284,7 +284,7 @@ bool MediaPluginReader::DecodeVideoFrame(bool &aKeyframeSkip,
return true;
}
bool MediaPluginReader::DecodeAudioData()
bool AndroidMediaReader::DecodeAudioData()
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
@ -316,7 +316,7 @@ bool MediaPluginReader::DecodeAudioData()
source.mAudioChannels));
}
nsresult MediaPluginReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
nsresult AndroidMediaReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aEndTime, int64_t aCurrentTime)
{
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
@ -339,14 +339,14 @@ nsresult MediaPluginReader::Seek(int64_t aTarget, int64_t aStartTime, int64_t aE
return NS_OK;
}
MediaPluginReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
AndroidMediaReader::ImageBufferCallback::ImageBufferCallback(mozilla::layers::ImageContainer *aImageContainer) :
mImageContainer(aImageContainer)
{
}
void *
MediaPluginReader::ImageBufferCallback::operator()(size_t aWidth, size_t aHeight,
MPAPI::ColorFormat aColorFormat)
AndroidMediaReader::ImageBufferCallback::operator()(size_t aWidth, size_t aHeight,
MPAPI::ColorFormat aColorFormat)
{
if (!mImageContainer) {
NS_WARNING("No image container to construct an image");
@ -375,8 +375,8 @@ MediaPluginReader::ImageBufferCallback::operator()(size_t aWidth, size_t aHeight
}
uint8_t *
MediaPluginReader::ImageBufferCallback::CreateI420Image(size_t aWidth,
size_t aHeight)
AndroidMediaReader::ImageBufferCallback::CreateI420Image(size_t aWidth,
size_t aHeight)
{
mImage = mImageContainer->CreateImage(ImageFormat::PLANAR_YCBCR);
PlanarYCbCrImage *yuvImage = static_cast<PlanarYCbCrImage *>(mImage.get());
@ -418,7 +418,7 @@ MediaPluginReader::ImageBufferCallback::CreateI420Image(size_t aWidth,
}
already_AddRefed<Image>
MediaPluginReader::ImageBufferCallback::GetImage()
AndroidMediaReader::ImageBufferCallback::GetImage()
{
return mImage.forget();
}

View File

@ -3,8 +3,8 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(MediaPluginReader_h_)
#define MediaPluginReader_h_
#if !defined(AndroidMediaReader_h_)
#define AndroidMediaReader_h_
#include "mozilla/Attributes.h"
#include "MediaResource.h"
@ -29,7 +29,7 @@ namespace dom {
class TimeRanges;
}
class MediaPluginReader : public MediaDecoderReader
class AndroidMediaReader : public MediaDecoderReader
{
nsCString mType;
MPAPI::Decoder *mPlugin;
@ -41,8 +41,8 @@ class MediaPluginReader : public MediaDecoderReader
int64_t mAudioSeekTimeUs;
nsAutoPtr<VideoData> mLastVideoFrame;
public:
MediaPluginReader(AbstractMediaDecoder* aDecoder,
const nsACString& aContentType);
AndroidMediaReader(AbstractMediaDecoder* aDecoder,
const nsACString& aContentType);
virtual nsresult Init(MediaDecoderReader* aCloneDonor);
virtual nsresult ResetDecode();

View File

@ -16,7 +16,7 @@
#include "nsNetCID.h"
#include "VideoUtils.h"
#include "MediaResource.h"
#include "MediaResourceServer.h"
#include "AndroidMediaResourceServer.h"
#if defined(_MSC_VER)
#define strtoll _strtoi64
@ -111,9 +111,9 @@ private:
// Writing to this sends data to the client.
nsCOMPtr<nsIOutputStream> mOutput;
// The MediaResourceServer that owns the MediaResource instances
// The AndroidMediaResourceServer that owns the MediaResource instances
// served. This is used to lookup the MediaResource from the URL.
nsRefPtr<MediaResourceServer> mServer;
nsRefPtr<AndroidMediaResourceServer> mServer;
// Write 'aBufferLength' bytes from 'aBuffer' to 'mOutput'. This
// method ensures all the data is written by checking the number
@ -123,7 +123,7 @@ private:
public:
ServeResourceEvent(nsIInputStream* aInput, nsIOutputStream* aOutput,
MediaResourceServer* aServer)
AndroidMediaResourceServer* aServer)
: mInput(aInput), mOutput(aOutput), mServer(aServer) {}
// This method runs on the thread and exits when it has completed the
@ -336,20 +336,20 @@ ServeResourceEvent::Shutdown()
to the output stream of the request.
The MediaResource used for providing the request data is obtained
from the MediaResourceServer that created this listener, using the
from the AndroidMediaResourceServer that created this listener, using the
URL the client requested.
*/
class ResourceSocketListener : public nsIServerSocketListener
{
public:
// The MediaResourceServer used to look up the MediaResource
// The AndroidMediaResourceServer used to look up the MediaResource
// on requests.
nsRefPtr<MediaResourceServer> mServer;
nsRefPtr<AndroidMediaResourceServer> mServer;
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISERVERSOCKETLISTENER
ResourceSocketListener(MediaResourceServer* aServer) :
ResourceSocketListener(AndroidMediaResourceServer* aServer) :
mServer(aServer)
{
}
@ -388,13 +388,13 @@ ResourceSocketListener::OnStopListening(nsIServerSocket* aServ, nsresult aStatus
return NS_OK;
}
MediaResourceServer::MediaResourceServer() :
mMutex("MediaResourceServer")
AndroidMediaResourceServer::AndroidMediaResourceServer() :
mMutex("AndroidMediaResourceServer")
{
}
NS_IMETHODIMP
MediaResourceServer::Run()
AndroidMediaResourceServer::Run()
{
MutexAutoLock lock(mMutex);
@ -415,16 +415,16 @@ MediaResourceServer::Run()
}
/* static */
already_AddRefed<MediaResourceServer>
MediaResourceServer::Start()
already_AddRefed<AndroidMediaResourceServer>
AndroidMediaResourceServer::Start()
{
nsRefPtr<MediaResourceServer> server = new MediaResourceServer();
nsRefPtr<AndroidMediaResourceServer> server = new AndroidMediaResourceServer();
NS_DispatchToMainThread(server, NS_DISPATCH_SYNC);
return server.forget();
}
void
MediaResourceServer::Stop()
AndroidMediaResourceServer::Stop()
{
MutexAutoLock lock(mMutex);
mSocket->Close();
@ -432,7 +432,7 @@ MediaResourceServer::Stop()
}
nsresult
MediaResourceServer::AppendRandomPath(nsCString& aUrl)
AndroidMediaResourceServer::AppendRandomPath(nsCString& aUrl)
{
// Use a cryptographic quality PRNG to generate raw random bytes
// and convert that to a base64 string for use as an URL path. This
@ -474,7 +474,7 @@ MediaResourceServer::AppendRandomPath(nsCString& aUrl)
}
nsresult
MediaResourceServer::AddResource(mozilla::MediaResource* aResource, nsCString& aUrl)
AndroidMediaResourceServer::AddResource(mozilla::MediaResource* aResource, nsCString& aUrl)
{
nsCString url = GetURLPrefix();
nsresult rv = AppendRandomPath(url);
@ -494,14 +494,14 @@ MediaResourceServer::AddResource(mozilla::MediaResource* aResource, nsCString& a
}
void
MediaResourceServer::RemoveResource(nsCString const& aUrl)
AndroidMediaResourceServer::RemoveResource(nsCString const& aUrl)
{
MutexAutoLock lock(mMutex);
mResources.erase(aUrl);
}
nsCString
MediaResourceServer::GetURLPrefix()
AndroidMediaResourceServer::GetURLPrefix()
{
MutexAutoLock lock(mMutex);
@ -517,7 +517,7 @@ MediaResourceServer::GetURLPrefix()
}
already_AddRefed<MediaResource>
MediaResourceServer::GetResource(nsCString const& aUrl)
AndroidMediaResourceServer::GetResource(nsCString const& aUrl)
{
MutexAutoLock lock(mMutex);
ResourceMap::const_iterator it = mResources.find(aUrl);

View File

@ -3,8 +3,8 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#if !defined(MediaResourceServer_h_)
#define MediaResourceServer_h_
#if !defined(AndroidMediaResourceServer_h_)
#define AndroidMediaResourceServer_h_
#include <map>
#include "nsIServerSocket.h"
@ -15,7 +15,7 @@ namespace mozilla {
class MediaResource;
/*
MediaResourceServer instantiates a socket server that understands
AndroidMediaResourceServer instantiates a socket server that understands
HTTP requests for MediaResource instances. The server runs on an
automatically selected port and MediaResource instances are registered.
The registration returns a string URL than can be used to fetch the
@ -31,16 +31,16 @@ class MediaResource;
requests are made against this server which then uses standard
Gecko network requests and media cache usage.
The MediaResourceServer can be instantiated on any thread and
The AndroidMediaResourceServer can be instantiated on any thread and
its methods are threadsafe - they can be called on any thread.
The server socket itself is always run on the main thread and
this is done by the Start() static method by synchronously
dispatching to the main thread.
*/
class MediaResourceServer : public nsRunnable
class AndroidMediaResourceServer : public nsRunnable
{
private:
// Mutex protecting private members of MediaResourceServer.
// Mutex protecting private members of AndroidMediaResourceServer.
// All member variables below this point in the class definition
// must acquire the mutex before access.
mozilla::Mutex mMutex;
@ -54,10 +54,10 @@ private:
nsRefPtr<mozilla::MediaResource> > ResourceMap;
ResourceMap mResources;
// Create a MediaResourceServer that will listen on an automatically
// Create a AndroidMediaResourceServer that will listen on an automatically
// selected port when started. This is private as it should only be
// called internally from the public 'Start' method.
MediaResourceServer();
AndroidMediaResourceServer();
NS_IMETHOD Run();
// Append a random URL path to a string. This is used for creating a
@ -67,9 +67,9 @@ private:
nsresult AppendRandomPath(nsCString& aURL);
public:
// Create a MediaResourceServer and start it listening. This call will
// Create a AndroidMediaResourceServer and start it listening. This call will
// perform a synchronous request on the main thread.
static already_AddRefed<MediaResourceServer> Start();
static already_AddRefed<AndroidMediaResourceServer> Start();
// Stops the server from listening and accepting further connections.
void Stop();

View File

@ -5,18 +5,18 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS += [
'MediaPluginDecoder.h',
'MediaPluginHost.h',
'MediaPluginReader.h',
'MediaResourceServer.h',
'AndroidMediaDecoder.h',
'AndroidMediaPluginHost.h',
'AndroidMediaReader.h',
'AndroidMediaResourceServer.h',
'MPAPI.h',
]
UNIFIED_SOURCES += [
'MediaPluginDecoder.cpp',
'MediaPluginHost.cpp',
'MediaPluginReader.cpp',
'MediaResourceServer.cpp',
'AndroidMediaDecoder.cpp',
'AndroidMediaPluginHost.cpp',
'AndroidMediaReader.cpp',
'AndroidMediaResourceServer.cpp',
]
LOCAL_INCLUDES += [

View File

@ -39,7 +39,7 @@ namespace mozilla {
// Uncomment to enable verbose per-sample logging.
//#define LOG_SAMPLE_DECODE 1
#ifdef LOG_SAMPLE_DECODE
#ifdef PR_LOGGING
static const char*
TrackTypeToStr(TrackType aTrack)
{
@ -351,9 +351,8 @@ MP4Reader::Decode(TrackType aTrack)
if (!compressed) {
// EOS, or error. Let the state machine know there are no more
// frames coming.
#ifdef LOG_SAMPLE_DECODE
LOG("PopSample %s nullptr", TrackTypeToStr(aTrack));
#endif
LOG("Draining %s", TrackTypeToStr(aTrack));
data.mDecoder->Drain();
return false;
} else {
#ifdef LOG_SAMPLE_DECODE

View File

@ -179,6 +179,8 @@ public:
// that are required to decode samples that it expects to get in future.
// This is called when the demuxer reaches end of stream.
// The MP4Reader will not call Input() while it's calling Drain().
// This function is synchronous. Once it's returned, all samples to be
// output should have been returned via callback to the MP4Reader.
virtual nsresult Drain() = 0;
// Cancels all init/input/drain operations, and shuts down the

View File

@ -120,7 +120,7 @@ WMFMediaDataDecoder::ProcessDrain()
{
// Order the decoder to drain...
if (FAILED(mDecoder->SendMFTMessage(MFT_MESSAGE_COMMAND_DRAIN, 0))) {
NS_WARNING("Failed to send DRAIN command to audio MFT");
NS_WARNING("Failed to send DRAIN command to MFT");
}
// Then extract all available output.
ProcessOutput();

View File

@ -205,7 +205,7 @@ WMFVideoMFTManager::ConfigureVideoFrameGeometry()
mVideoHeight = height;
mPictureRegion = pictureRegion;
LOG("WMFReader frame geometry frame=(%u,%u) stride=%u picture=(%d, %d, %d, %d) display=(%d,%d) PAR=%d:%d",
LOG("WMFVideoMFTManager frame geometry frame=(%u,%u) stride=%u picture=(%d, %d, %d, %d) display=(%d,%d) PAR=%d:%d",
width, height,
mVideoStride,
mPictureRegion.x, mPictureRegion.y, mPictureRegion.width, mPictureRegion.height,

View File

@ -19,6 +19,11 @@
#include <unistd.h> // for _exit()
#endif
#if defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS
#include "mozilla/sandboxTarget.h"
#endif
namespace mozilla {
namespace gmp {
@ -39,6 +44,9 @@ GMPChild::Init(const std::string& aPluginPath,
MessageLoop* aIOLoop,
IPC::Channel* aChannel)
{
#if defined(XP_WIN)
mozilla::SandboxTarget::Instance()->StartSandbox();
#endif
return LoadPluginLibrary(aPluginPath) &&
Open(aChannel, aParentProcessHandle, aIOLoop);
}

View File

@ -51,6 +51,7 @@ GMPProcessParent::Delete()
MessageLoop* ioLoop = XRE_GetIOMessageLoop();
if (currentLoop == ioLoop) {
Join();
delete this;
return;
}

View File

@ -14,6 +14,7 @@
#include "mozilla/Services.h"
#include "nsNativeCharsetUtils.h"
#include "nsIConsoleService.h"
#include "mozilla/unused.h"
namespace mozilla {
namespace gmp {
@ -113,6 +114,10 @@ GeckoMediaPluginService::Init()
MOZ_ASSERT(obsService);
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false)));
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, false)));
// Kick off scanning for plugins
nsCOMPtr<nsIThread> thread;
unused << GetThread(getter_AddRefs(thread));
}
NS_IMETHODIMP
@ -255,6 +260,7 @@ GeckoMediaPluginService::UnloadPlugins()
MOZ_ASSERT(!mShuttingDownOnGMPThread);
mShuttingDownOnGMPThread = true;
MutexAutoLock lock(mMutex);
for (uint32_t i = 0; i < mPlugins.Length(); i++) {
mPlugins[i]->UnloadProcess();
}
@ -330,13 +336,28 @@ GeckoMediaPluginService::RemovePluginDirectory(const nsAString& aDirectory)
return NS_OK;
}
NS_IMETHODIMP
GeckoMediaPluginService::HasPluginForAPI(const nsAString& aOrigin,
const nsACString& aAPI,
nsTArray<nsCString>* aTags,
bool* aResult)
{
NS_ENSURE_ARG(aTags && aTags->Length() > 0);
NS_ENSURE_ARG(aResult);
nsCString temp(aAPI);
GMPParent *parent = SelectPluginForAPI(aOrigin, temp, *aTags);
*aResult = !!parent;
return NS_OK;
}
GMPParent*
GeckoMediaPluginService::SelectPluginForAPI(const nsAString& aOrigin,
const nsCString& aAPI,
const nsTArray<nsCString>& aTags)
{
MOZ_ASSERT(NS_GetCurrentThread() == mGMPThread);
MutexAutoLock lock(mMutex);
for (uint32_t i = 0; i < mPlugins.Length(); i++) {
GMPParent* gmp = mPlugins[i];
bool supportsAllTags = true;
@ -402,6 +423,7 @@ GeckoMediaPluginService::AddOnGMPThread(const nsAString& aDirectory)
return;
}
MutexAutoLock lock(mMutex);
mPlugins.AppendElement(gmp);
}
@ -416,6 +438,7 @@ GeckoMediaPluginService::RemoveOnGMPThread(const nsAString& aDirectory)
return;
}
MutexAutoLock lock(mMutex);
for (uint32_t i = 0; i < mPlugins.Length(); ++i) {
nsCOMPtr<nsIFile> pluginpath = mPlugins[i]->GetDirectory();
bool equals;

View File

@ -69,8 +69,8 @@ private:
bool mAdd;
};
Mutex mMutex; // Protects mGMPThread and mShuttingDown and mPlugins
nsTArray<nsRefPtr<GMPParent>> mPlugins;
Mutex mMutex; // Protects mGMPThread and mShuttingDown
nsCOMPtr<nsIThread> mGMPThread;
bool mShuttingDown;
bool mShuttingDownOnGMPThread;

View File

@ -21,7 +21,7 @@ class GMPVideoHost;
[ptr] native MessageLoop(MessageLoop);
[ptr] native TagArray(nsTArray<nsCString>);
[scriptable, uuid(7cef50ca-7a0f-41f2-9560-47abf709f0d7)]
[scriptable, uuid(a9b826da-725a-4b81-814f-b715445188f2)]
interface mozIGeckoMediaPluginService : nsISupports
{
/**
@ -29,6 +29,15 @@ interface mozIGeckoMediaPluginService : nsISupports
*/
readonly attribute nsIThread thread;
/**
* Get a plugin that supports the specified tags.
* Callable on any thread
*/
[noscript]
boolean hasPluginForAPI([optional] in AString origin,
in ACString api,
in TagArray tags);
/**
* Get a video decoder that supports the specified tags.
* The array of tags should at least contain a codec tag, and optionally

View File

@ -30,8 +30,8 @@ if CONFIG['MOZ_GSTREAMER']:
if CONFIG['MOZ_DIRECTSHOW']:
PARALLEL_DIRS += ['directshow']
if CONFIG['MOZ_MEDIA_PLUGINS']:
PARALLEL_DIRS += ['plugins']
if CONFIG['MOZ_ANDROID_OMX']:
PARALLEL_DIRS += ['android']
if CONFIG['MOZ_WMF']:
PARALLEL_DIRS += ['wmf']
@ -50,7 +50,8 @@ if CONFIG['MOZ_OMX_DECODER']:
PARALLEL_DIRS += ['webspeech']
PARALLEL_DIRS += ['eme']
if CONFIG['MOZ_EME']:
PARALLEL_DIRS += ['eme']
TEST_DIRS += [
'test',

View File

@ -0,0 +1,229 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "I420ColorConverterHelper.h"
#include <dlfcn.h>
#include "prlog.h"
#ifdef PR_LOGGING
PRLogModuleInfo *gI420ColorConverterHelperLog;
#define LOG(msg...) PR_LOG(gI420ColorConverterHelperLog, PR_LOG_WARNING, (msg))
#else
#define LOG(x...)
#endif
namespace android {
I420ColorConverterHelper::I420ColorConverterHelper()
: mHandle(nullptr)
, mConverter({nullptr, nullptr, nullptr, nullptr, nullptr})
{
#ifdef PR_LOGGING
if (!gI420ColorConverterHelperLog) {
gI420ColorConverterHelperLog = PR_NewLogModule("I420ColorConverterHelper");
}
#endif
}
I420ColorConverterHelper::~I420ColorConverterHelper()
{
RWLock::AutoWLock awl(mLock);
unloadLocked();
}
// Prerequisite: a writer-lock should be held
bool
I420ColorConverterHelper::loadLocked()
{
if (loadedLocked()) {
return true;
}
unloadLocked();
// Open the shared library
mHandle = dlopen("libI420colorconvert.so", RTLD_NOW);
if (mHandle == nullptr) {
LOG("libI420colorconvert.so not found");
return false;
}
// Find the entry point
// Pointer to function with signature
// void getI420ColorConverter(II420ColorConverter *converter)
typedef int (* getConverterFn)(II420ColorConverter *converter);
getConverterFn getI420ColorConverter =
(getConverterFn) dlsym(mHandle, "getI420ColorConverter");
if (getI420ColorConverter == nullptr) {
LOG("Cannot load getI420ColorConverter from libI420colorconvert.so");
unloadLocked();
return false;
}
// Fill the function pointers.
getI420ColorConverter(&mConverter);
if (mConverter.getDecoderOutputFormat == nullptr ||
mConverter.convertDecoderOutputToI420 == nullptr ||
mConverter.getEncoderInputFormat == nullptr ||
mConverter.convertI420ToEncoderInput == nullptr ||
mConverter.getEncoderInputBufferInfo == nullptr) {
LOG("Failed to initialize I420 color converter");
unloadLocked();
return false;
}
return true;
}
// Prerequisite: a reader-lock or a writer-lock should be held
bool
I420ColorConverterHelper::loadedLocked() const
{
if (mHandle == nullptr ||
mConverter.getDecoderOutputFormat == nullptr ||
mConverter.convertDecoderOutputToI420 == nullptr ||
mConverter.getEncoderInputFormat == nullptr ||
mConverter.convertI420ToEncoderInput == nullptr ||
mConverter.getEncoderInputBufferInfo == nullptr) {
return false;
}
return true;
}
// Prerequisite: a writer-lock should be held
void
I420ColorConverterHelper::unloadLocked()
{
if (mHandle != nullptr) {
dlclose(mHandle);
}
mHandle = nullptr;
mConverter.getDecoderOutputFormat = nullptr;
mConverter.convertDecoderOutputToI420 = nullptr;
mConverter.getEncoderInputFormat = nullptr;
mConverter.convertI420ToEncoderInput = nullptr;
mConverter.getEncoderInputBufferInfo = nullptr;
}
bool
I420ColorConverterHelper::ensureLoaded()
{
{
RWLock::AutoRLock arl(mLock);
// Check whether the library has been loaded or not.
if (loadedLocked()) {
return true;
}
}
{
RWLock::AutoWLock awl(mLock);
// Check whether the library has been loaded or not on other threads.
if (loadedLocked()) {
return true;
}
// Reload the library
unloadLocked();
if (loadLocked()) {
return true;
}
// Reset the library
unloadLocked();
}
return false;
}
int
I420ColorConverterHelper::getDecoderOutputFormat()
{
if (!ensureLoaded()) {
return -1;
}
RWLock::AutoRLock arl(mLock);
if (mConverter.getDecoderOutputFormat != nullptr) {
return mConverter.getDecoderOutputFormat();
}
return -1;
}
int
I420ColorConverterHelper::convertDecoderOutputToI420(
void* decoderBits, int decoderWidth, int decoderHeight,
ARect decoderRect, void* dstBits)
{
if (!ensureLoaded()) {
return -1;
}
RWLock::AutoRLock arl(mLock);
if (mConverter.convertDecoderOutputToI420 != nullptr) {
return mConverter.convertDecoderOutputToI420(decoderBits,
decoderWidth, decoderHeight, decoderRect, dstBits);
}
return -1;
}
int
I420ColorConverterHelper::getEncoderInputFormat()
{
if (!ensureLoaded()) {
return -1;
}
RWLock::AutoRLock arl(mLock);
if (mConverter.getEncoderInputFormat != nullptr) {
return mConverter.getEncoderInputFormat();
}
return -1;
}
int
I420ColorConverterHelper::convertI420ToEncoderInput(void* aSrcBits,
int aSrcWidth,
int aSrcHeight,
int aEncoderWidth,
int aEncoderHeight,
ARect aEncoderRect,
void* aEncoderBits)
{
if (!ensureLoaded()) {
return -1;
}
RWLock::AutoRLock arl(mLock);
if (mConverter.convertI420ToEncoderInput != nullptr) {
return mConverter.convertI420ToEncoderInput(aSrcBits, aSrcWidth, aSrcHeight,
aEncoderWidth, aEncoderHeight, aEncoderRect, aEncoderBits);
}
return -1;
}
int
I420ColorConverterHelper::getEncoderInputBufferInfo(int aSrcWidth,
int aSrcHeight,
int* aEncoderWidth,
int* aEncoderHeight,
ARect* aEncoderRect,
int* aEncoderBufferSize)
{
if (!ensureLoaded()) {
return -1;
}
RWLock::AutoRLock arl(mLock);
if (mConverter.getEncoderInputBufferInfo != nullptr) {
return mConverter.getEncoderInputBufferInfo(aSrcWidth, aSrcHeight,
aEncoderWidth, aEncoderHeight, aEncoderRect, aEncoderBufferSize);
}
return -1;
}
} // namespace android

View File

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef I420_COLOR_CONVERTER_HELPER_H
#define I420_COLOR_CONVERTER_HELPER_H
#include <utils/RWLock.h>
#include <media/editor/II420ColorConverter.h>
#include <mozilla/Attributes.h>
namespace android {
class I420ColorConverterHelper {
public:
I420ColorConverterHelper();
~I420ColorConverterHelper();
int getDecoderOutputFormat();
int convertDecoderOutputToI420(void* aDecoderBits,
int aDecoderWidth,
int aDecoderHeight,
ARect aDecoderRect,
void* aDstBits);
int getEncoderInputFormat();
int convertI420ToEncoderInput(void* aSrcBits,
int aSrcWidth,
int aSrcHeight,
int aEncoderWidth,
int aEncoderHeight,
ARect aEncoderRect,
void* aEncoderBits);
int getEncoderInputBufferInfo(int aSrcWidth,
int aSrcHeight,
int* aEncoderWidth,
int* aEncoderHeight,
ARect* aEncoderRect,
int* aEncoderBufferSize);
private:
mutable RWLock mLock;
void *mHandle;
II420ColorConverter mConverter;
bool loadLocked();
bool loadedLocked() const;
void unloadLocked();
bool ensureLoaded();
I420ColorConverterHelper(const I420ColorConverterHelper &) MOZ_DELETE;
const I420ColorConverterHelper &operator=(const I420ColorConverterHelper &) MOZ_DELETE;
};
} // namespace android
#endif // I420_COLOR_CONVERTER_HELPER_H

Some files were not shown because too many files have changed in this diff Show More