зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound. CLOSED TREE
This commit is contained in:
Коммит
6151e79a07
|
@ -4,269 +4,12 @@ dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|||
|
||||
AC_DEFUN([MOZ_ARCH_OPTS],
|
||||
[
|
||||
|
||||
dnl ========================================================
|
||||
dnl = ARM toolchain tweaks
|
||||
dnl ========================================================
|
||||
|
||||
MOZ_THUMB=toolchain-default
|
||||
MOZ_THUMB_INTERWORK=toolchain-default
|
||||
MOZ_FPU=toolchain-default
|
||||
MOZ_FLOAT_ABI=toolchain-default
|
||||
MOZ_SOFT_FLOAT=toolchain-default
|
||||
MOZ_ALIGN=toolchain-default
|
||||
|
||||
MOZ_ARG_WITH_STRING(arch,
|
||||
[ --with-arch=[[type|toolchain-default]]
|
||||
Use specific CPU features (-march=type). Resets
|
||||
thumb, fpu, float-abi, etc. defaults when set],
|
||||
if test -z "$GNU_CC"; then
|
||||
AC_MSG_ERROR([--with-arch is not supported on non-GNU toolchains])
|
||||
fi
|
||||
MOZ_ARCH=$withval)
|
||||
|
||||
if test -z "$MOZ_ARCH"; then
|
||||
dnl Defaults
|
||||
case "${CPU_ARCH}-${OS_TARGET}" in
|
||||
arm-Android)
|
||||
MOZ_THUMB=yes
|
||||
MOZ_ARCH=armv7-a
|
||||
MOZ_FPU=neon
|
||||
MOZ_FLOAT_ABI=softfp
|
||||
MOZ_ALIGN=no
|
||||
;;
|
||||
arm-Darwin)
|
||||
MOZ_ARCH=toolchain-default
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if test "$MOZ_ARCH" = "armv6" -a "$OS_TARGET" = "Android"; then
|
||||
AC_MSG_ERROR([Android/armv6 is not supported])
|
||||
fi
|
||||
|
||||
MOZ_ARG_WITH_STRING(thumb,
|
||||
[ --with-thumb[[=yes|no|toolchain-default]]]
|
||||
[ Use Thumb instruction set (-mthumb)],
|
||||
if test -z "$GNU_CC"; then
|
||||
AC_MSG_ERROR([--with-thumb is not supported on non-GNU toolchains])
|
||||
fi
|
||||
MOZ_THUMB=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(thumb-interwork,
|
||||
[ --with-thumb-interwork[[=yes|no|toolchain-default]]
|
||||
Use Thumb/ARM instuctions interwork (-mthumb-interwork)],
|
||||
if test -z "$GNU_CC"; then
|
||||
AC_MSG_ERROR([--with-thumb-interwork is not supported on non-GNU toolchains])
|
||||
fi
|
||||
MOZ_THUMB_INTERWORK=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(fpu,
|
||||
[ --with-fpu=[[type|toolchain-default]]
|
||||
Use specific FPU type (-mfpu=type)],
|
||||
if test -z "$GNU_CC"; then
|
||||
AC_MSG_ERROR([--with-fpu is not supported on non-GNU toolchains])
|
||||
fi
|
||||
MOZ_FPU=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(float-abi,
|
||||
[ --with-float-abi=[[type|toolchain-default]]
|
||||
Use specific arm float ABI (-mfloat-abi=type)],
|
||||
if test -z "$GNU_CC"; then
|
||||
AC_MSG_ERROR([--with-float-abi is not supported on non-GNU toolchains])
|
||||
fi
|
||||
MOZ_FLOAT_ABI=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(soft-float,
|
||||
[ --with-soft-float[[=yes|no|toolchain-default]]
|
||||
Use soft float library (-msoft-float)],
|
||||
if test -z "$GNU_CC"; then
|
||||
AC_MSG_ERROR([--with-soft-float is not supported on non-GNU toolchains])
|
||||
fi
|
||||
MOZ_SOFT_FLOAT=$withval)
|
||||
|
||||
case "$MOZ_ARCH" in
|
||||
toolchain-default|"")
|
||||
arch_flag=""
|
||||
;;
|
||||
*)
|
||||
arch_flag="-march=$MOZ_ARCH"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$MOZ_THUMB" in
|
||||
yes)
|
||||
MOZ_THUMB2=1
|
||||
thumb_flag="-mthumb"
|
||||
;;
|
||||
no)
|
||||
MOZ_THUMB2=
|
||||
thumb_flag="-marm"
|
||||
;;
|
||||
*)
|
||||
_SAVE_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$arch_flag"
|
||||
AC_TRY_COMPILE([],[return sizeof(__thumb2__);],
|
||||
MOZ_THUMB2=1,
|
||||
MOZ_THUMB2=)
|
||||
CFLAGS="$_SAVE_CFLAGS"
|
||||
thumb_flag=""
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$MOZ_THUMB2" = 1; then
|
||||
AC_DEFINE(MOZ_THUMB2)
|
||||
fi
|
||||
|
||||
case "$MOZ_THUMB_INTERWORK" in
|
||||
yes)
|
||||
thumb_interwork_flag="-mthumb-interwork"
|
||||
;;
|
||||
no)
|
||||
thumb_interwork_flag="-mno-thumb-interwork"
|
||||
;;
|
||||
*) # toolchain-default
|
||||
thumb_interwork_flag=""
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$MOZ_FPU" in
|
||||
toolchain-default|"")
|
||||
fpu_flag=""
|
||||
;;
|
||||
*)
|
||||
fpu_flag="-mfpu=$MOZ_FPU"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$MOZ_FLOAT_ABI" in
|
||||
toolchain-default|"")
|
||||
float_abi_flag=""
|
||||
;;
|
||||
*)
|
||||
float_abi_flag="-mfloat-abi=$MOZ_FLOAT_ABI"
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$MOZ_SOFT_FLOAT" in
|
||||
yes)
|
||||
soft_float_flag="-msoft-float"
|
||||
;;
|
||||
no)
|
||||
soft_float_flag="-mno-soft-float"
|
||||
;;
|
||||
*) # toolchain-default
|
||||
soft_float_flag=""
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$MOZ_ALIGN" in
|
||||
no)
|
||||
align_flag="-mno-unaligned-access"
|
||||
;;
|
||||
yes)
|
||||
align_flag="-munaligned-access"
|
||||
;;
|
||||
*)
|
||||
align_flag=""
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -n "$align_flag"; then
|
||||
_SAVE_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $align_flag"
|
||||
AC_MSG_CHECKING(whether alignment flag ($align_flag) is supported)
|
||||
AC_TRY_COMPILE([],[],,align_flag="")
|
||||
CFLAGS="$_SAVE_CFLAGS"
|
||||
fi
|
||||
|
||||
dnl Use echo to avoid accumulating space characters
|
||||
all_flags=`echo $arch_flag $thumb_flag $thumb_interwork_flag $fpu_flag $float_abi_flag $soft_float_flag $align_flag`
|
||||
if test -n "$all_flags"; then
|
||||
_SAVE_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$all_flags"
|
||||
AC_MSG_CHECKING(whether the chosen combination of compiler flags ($all_flags) works)
|
||||
AC_TRY_COMPILE([],[return 0;],
|
||||
AC_MSG_RESULT([yes]),
|
||||
AC_MSG_ERROR([no]))
|
||||
|
||||
CFLAGS="$_SAVE_CFLAGS $all_flags"
|
||||
CXXFLAGS="$CXXFLAGS $all_flags"
|
||||
ASFLAGS="$ASFLAGS $all_flags"
|
||||
if test -n "$thumb_flag"; then
|
||||
LDFLAGS="$LDFLAGS $thumb_flag"
|
||||
if test -n "$_ARM_FLAGS"; then
|
||||
CFLAGS="$CFLAGS $_ARM_FLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $_ARM_FLAGS"
|
||||
ASFLAGS="$ASFLAGS $_ARM_FLAGS"
|
||||
if test -n "$_THUMB_FLAGS"; then
|
||||
LDFLAGS="$LDFLAGS $_THUMB_FLAGS"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_THUMB2)
|
||||
|
||||
if test "$CPU_ARCH" = "arm"; then
|
||||
NEON_FLAGS="-mfpu=neon"
|
||||
AC_MSG_CHECKING(for ARM SIMD support in compiler)
|
||||
# We try to link so that this also fails when
|
||||
# building with LTO.
|
||||
AC_TRY_LINK([],
|
||||
[asm("uqadd8 r1, r1, r2");],
|
||||
result="yes", result="no")
|
||||
AC_MSG_RESULT("$result")
|
||||
if test "$result" = "yes"; then
|
||||
AC_DEFINE(HAVE_ARM_SIMD)
|
||||
HAVE_ARM_SIMD=1
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(ARM version support in compiler)
|
||||
dnl Determine the target ARM architecture (5 for ARMv5, v5T, v5E, etc.; 6 for ARMv6, v6K, etc.)
|
||||
ARM_ARCH=`${CC-cc} ${CFLAGS} -dM -E - < /dev/null | sed -n 's/.*__ARM_ARCH_\([[0-9]][[0-9]]*\).*/\1/p' | head -n 1`
|
||||
AC_MSG_RESULT("$ARM_ARCH")
|
||||
|
||||
AC_MSG_CHECKING(for ARM NEON support in compiler)
|
||||
# We try to link so that this also fails when
|
||||
# building with LTO.
|
||||
AC_TRY_LINK([],
|
||||
[asm(".fpu neon\n vadd.i8 d0, d0, d0");],
|
||||
result="yes", result="no")
|
||||
AC_MSG_RESULT("$result")
|
||||
if test "$result" = "yes"; then
|
||||
AC_DEFINE(HAVE_ARM_NEON)
|
||||
HAVE_ARM_NEON=1
|
||||
|
||||
dnl We don't need to build NEON support if we're targetting a non-NEON device.
|
||||
dnl This matches media/webrtc/trunk/webrtc/build/common.gypi.
|
||||
if test -n "$ARM_ARCH"; then
|
||||
if test "$ARM_ARCH" -lt 7; then
|
||||
BUILD_ARM_NEON=
|
||||
else
|
||||
AC_DEFINE(BUILD_ARM_NEON)
|
||||
BUILD_ARM_NEON=1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl Building with -mfpu=neon requires either the "softfp" or the
|
||||
dnl "hardfp" ABI. Depending on the compiler's default target, and the
|
||||
dnl CFLAGS, the default ABI might be neither, in which case it is the
|
||||
dnl "softfloat" ABI.
|
||||
dnl The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
|
||||
dnl we can safely mix code built with both ABIs. So, if we detect
|
||||
dnl that compiling uses the "softfloat" ABI, force the use of the
|
||||
dnl "softfp" ABI instead.
|
||||
dnl Confusingly, the __SOFTFP__ preprocessor variable indicates the
|
||||
dnl "softfloat" ABI, not the "softfp" ABI.
|
||||
dnl Note: VPX_ASFLAGS is also used in CFLAGS.
|
||||
AC_TRY_COMPILE([],
|
||||
[#ifndef __SOFTFP__
|
||||
#error "compiler target supports -mfpu=neon, so we don't have to add extra flags"
|
||||
#endif],
|
||||
NEON_FLAGS="$NEON_FLAGS -mfloat-abi=softfp"
|
||||
)
|
||||
|
||||
fi # CPU_ARCH = arm
|
||||
|
||||
AC_SUBST(HAVE_ARM_SIMD)
|
||||
AC_SUBST(HAVE_ARM_NEON)
|
||||
AC_SUBST(BUILD_ARM_NEON)
|
||||
AC_SUBST(ARM_ARCH)
|
||||
AC_SUBST_LIST(NEON_FLAGS)
|
||||
AC_SUBST(MOZ_FPU)
|
||||
|
||||
])
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
# -*- Mode: python; 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/.
|
||||
|
||||
@depends(target.os, '--help')
|
||||
def arm_option_defaults(os, _):
|
||||
if os == 'Android':
|
||||
arch = 'armv7-a'
|
||||
thumb = 'yes'
|
||||
fpu = 'neon'
|
||||
float_abi = 'softfp'
|
||||
else:
|
||||
arch = thumb = fpu = float_abi = 'toolchain-default'
|
||||
return namespace(
|
||||
arch=arch,
|
||||
thumb=thumb,
|
||||
fpu=fpu,
|
||||
float_abi=float_abi,
|
||||
)
|
||||
|
||||
|
||||
# Note: '{...|}' in the help of all options with a non-constant default to
|
||||
# make the lint happy. The first arm is always going to be used, because a
|
||||
# default is always returned. The lint is fooled by this file being
|
||||
# conditional. If it weren't conditional, the lint wouldn't ask for '{|}' to
|
||||
# be there.
|
||||
js_option('--with-arch', nargs=1,
|
||||
default=arm_option_defaults.arch,
|
||||
help='{Use specific CPU features (-march=type). Resets thumb, fpu, '
|
||||
'float-abi, etc. defaults when set|}')
|
||||
|
||||
|
||||
@depends('--with-arch')
|
||||
def arch_option(value):
|
||||
if value:
|
||||
if value[0] != 'toolchain-default':
|
||||
return ['-march={}'.format(value[0])]
|
||||
return []
|
||||
|
||||
|
||||
js_option('--with-thumb', choices=('yes', 'no', 'toolchain-default'),
|
||||
default=arm_option_defaults.thumb,
|
||||
nargs='?', help='{Use Thumb instruction set (-mthumb)|}')
|
||||
|
||||
|
||||
def normalize_arm_option(value):
|
||||
if value:
|
||||
if len(value):
|
||||
if value[0] == 'yes':
|
||||
return True
|
||||
elif value[0] == 'no':
|
||||
return False
|
||||
else:
|
||||
return value[0]
|
||||
return True
|
||||
return False
|
||||
|
||||
@depends('--with-thumb')
|
||||
def thumb_option(value):
|
||||
value = normalize_arm_option(value)
|
||||
if value is True:
|
||||
return ['-mthumb']
|
||||
if value is False:
|
||||
return ['-marm']
|
||||
return []
|
||||
|
||||
|
||||
js_option('--with-thumb-interwork', choices=('yes', 'no', 'toolchain-default'),
|
||||
default='toolchain-default',
|
||||
nargs='?', help='Use Thumb/ARM instuctions interwork (-mthumb-interwork)')
|
||||
|
||||
|
||||
@depends('--with-thumb-interwork')
|
||||
def thumb_interwork_option(value):
|
||||
value = normalize_arm_option(value)
|
||||
if value is True:
|
||||
return ['-mthumb-interwork']
|
||||
if value is False:
|
||||
return ['-mno-thumb-interwork']
|
||||
return []
|
||||
|
||||
|
||||
js_option('--with-fpu', nargs=1,
|
||||
default=arm_option_defaults.fpu,
|
||||
help='{Use specific FPU type (-mfpu=type)|}')
|
||||
|
||||
|
||||
@depends('--with-fpu')
|
||||
def fpu_option(value):
|
||||
if value:
|
||||
if value[0] != 'toolchain-default':
|
||||
return ['-mfpu={}'.format(value[0])]
|
||||
return []
|
||||
|
||||
|
||||
js_option('--with-float-abi', nargs=1,
|
||||
default=arm_option_defaults.float_abi,
|
||||
help='{Use specific arm float ABI (-mfloat-abi=type)|}')
|
||||
|
||||
|
||||
@depends('--with-float-abi')
|
||||
def float_abi_option(value):
|
||||
if value:
|
||||
if value[0] != 'toolchain-default':
|
||||
return ['-mfloat-abi={}'.format(value[0])]
|
||||
return []
|
||||
|
||||
|
||||
js_option('--with-soft-float', choices=('yes', 'no', 'toolchain-default'),
|
||||
default='toolchain-default',
|
||||
nargs='?', help='Use soft float library (-msoft-float)')
|
||||
|
||||
|
||||
@depends('--with-soft-float')
|
||||
def soft_float_option(value):
|
||||
value = normalize_arm_option(value)
|
||||
if value is True:
|
||||
return ['-msoft-float']
|
||||
if value is False:
|
||||
return ['-mno-soft-float']
|
||||
return []
|
||||
|
||||
|
||||
check_and_add_gcc_flag('-mno-unaligned-access',
|
||||
when=depends(target.os)(lambda os: os == 'Android'))
|
||||
|
||||
|
||||
@depends(arch_option, thumb_option, thumb_interwork_option, fpu_option,
|
||||
float_abi_option, soft_float_option)
|
||||
def all_flags(arch, thumb, interwork, fpu, float_abi, soft_float):
|
||||
return arch + thumb + interwork + fpu + float_abi + soft_float
|
||||
|
||||
|
||||
add_old_configure_assignment('_ARM_FLAGS', all_flags)
|
||||
add_old_configure_assignment('_THUMB_FLAGS', thumb_option)
|
||||
|
||||
|
||||
@depends(c_compiler, all_flags)
|
||||
@checking('ARM version support in compiler', lambda x: x.arm_arch)
|
||||
@imports(_from='textwrap', _import='dedent')
|
||||
def arm_target(compiler, all_flags):
|
||||
# We're going to preprocess the following source to figure out some details
|
||||
# about the arm target options we have enabled.
|
||||
source = dedent('''\
|
||||
%ARM_ARCH __ARM_ARCH
|
||||
#if __thumb2__
|
||||
%THUMB2 yes
|
||||
#else
|
||||
%THUMB2 no
|
||||
#endif
|
||||
// Confusingly, the __SOFTFP__ preprocessor variable indicates the
|
||||
// "softfloat" ABI, not the "softfp" ABI.
|
||||
#if __SOFTFP__
|
||||
%FLOAT_ABI soft
|
||||
#elif __ARM_PCS_VFP
|
||||
%FLOAT_ABI hard
|
||||
#else
|
||||
%FLOAT_ABI softfp
|
||||
#endif
|
||||
// There is more subtlety to it than this preprocessor test, but MOZ_FPU doesn't
|
||||
// need to be too fine-grained.
|
||||
#if __ARM_NEON
|
||||
%FPU neon
|
||||
#elif __ARM_VFPV2__
|
||||
%FPU vfpv2
|
||||
#elif __ARM_VFPV3__
|
||||
%FPU vfpv3
|
||||
#elif __ARM_VFPV4__
|
||||
%FPU vfpv4
|
||||
#elif __ARM_FPV5__
|
||||
%FPU fp-armv8
|
||||
#endif
|
||||
''')
|
||||
result = try_invoke_compiler(
|
||||
compiler.wrapper + [compiler.compiler] + compiler.flags,
|
||||
compiler.language,
|
||||
source,
|
||||
['-E'] + all_flags,
|
||||
)
|
||||
# Metadata emitted by preprocessors such as GCC with LANG=ja_JP.utf-8 may
|
||||
# have non-ASCII characters. Treat the output as bytearray.
|
||||
data = {}
|
||||
for line in result.splitlines():
|
||||
if line.startswith(b'%'):
|
||||
k, _, v = line.partition(' ')
|
||||
k = k.lstrip('%').lower()
|
||||
if k == 'arm_arch':
|
||||
data[k] = int(v)
|
||||
else:
|
||||
data[k] = {
|
||||
'yes': True,
|
||||
'no': False,
|
||||
}.get(v, v)
|
||||
log.debug('%s = %s', k, data[k])
|
||||
|
||||
return namespace(**data)
|
||||
|
||||
|
||||
@depends(arm_target.arm_arch, when=depends(target.os)(lambda os: os == 'Android'))
|
||||
def armv7(arch):
|
||||
if arch < 7:
|
||||
die('Android/armv6 and earlier are not supported')
|
||||
|
||||
|
||||
set_config('MOZ_THUMB2', True, when=arm_target.thumb2)
|
||||
set_define('MOZ_THUMB2', True, when=arm_target.thumb2)
|
||||
add_old_configure_assignment('MOZ_THUMB2', True, when=arm_target.thumb2)
|
||||
|
||||
|
||||
have_arm_simd = c_compiler.try_compile(body='asm("uqadd8 r1, r1, r2");',
|
||||
check_msg='for ARM SIMD support in compiler')
|
||||
|
||||
set_config('HAVE_ARM_SIMD', have_arm_simd)
|
||||
set_define('HAVE_ARM_SIMD', have_arm_simd)
|
||||
|
||||
have_arm_neon = c_compiler.try_compile(body='asm(".fpu neon\\n vadd.i8 d0, d0, d0");',
|
||||
check_msg='for ARM NEON support in compiler')
|
||||
|
||||
set_config('HAVE_ARM_NEON', have_arm_neon)
|
||||
set_define('HAVE_ARM_NEON', have_arm_neon)
|
||||
|
||||
|
||||
# We don't need to build NEON support if we're targetting a non-NEON device.
|
||||
# This matches media/webrtc/trunk/webrtc/build/common.gypi.
|
||||
@depends(arm_target.arm_arch, when=have_arm_neon)
|
||||
def build_arm_neon(arm_arch):
|
||||
return arm_arch >= 7
|
||||
|
||||
|
||||
set_config('BUILD_ARM_NEON', build_arm_neon)
|
||||
set_define('BUILD_ARM_NEON', build_arm_neon)
|
||||
|
||||
|
||||
set_config('ARM_ARCH', depends(arm_target.arm_arch)(lambda x: str(x)))
|
||||
add_old_configure_assignment('ARM_ARCH', depends(arm_target.arm_arch)(lambda x: str(x)))
|
||||
set_config('MOZ_FPU', arm_target.fpu)
|
||||
|
||||
|
||||
@depends(arm_target.float_abi)
|
||||
def neon_flags(float_abi):
|
||||
# Building with -mfpu=neon requires either the "softfp" or the
|
||||
# "hardfp" ABI. Depending on the compiler's default target, and the
|
||||
# CFLAGS, the default ABI might be neither, in which case it is the
|
||||
# "softfloat" ABI.
|
||||
# The "softfloat" ABI is binary-compatible with the "softfp" ABI, so
|
||||
# we can safely mix code built with both ABIs. So, if we detect
|
||||
# that compiling uses the "softfloat" ABI, force the use of the
|
||||
# "softfp" ABI instead.
|
||||
flags = ['-mfpu=neon']
|
||||
if float_abi == 'soft':
|
||||
flags.append('-mfloat-abi=softfp')
|
||||
return tuple(flags)
|
||||
|
||||
|
||||
set_config('NEON_FLAGS', neon_flags)
|
|
@ -231,7 +231,6 @@ def old_configure_options(*options):
|
|||
'--with-android-min-sdk',
|
||||
'--with-app-basename',
|
||||
'--with-app-name',
|
||||
'--with-arch',
|
||||
'--with-branding',
|
||||
'--with-cross-lib',
|
||||
'--with-debug-label',
|
||||
|
@ -239,8 +238,6 @@ def old_configure_options(*options):
|
|||
'--with-doc-include-dirs',
|
||||
'--with-doc-input-dirs',
|
||||
'--with-doc-output-dir',
|
||||
'--with-float-abi',
|
||||
'--with-fpu',
|
||||
'--with-intl-api',
|
||||
'--with-ios-sdk',
|
||||
'--with-jitreport-granularity',
|
||||
|
@ -253,7 +250,6 @@ def old_configure_options(*options):
|
|||
'--with-nss-prefix',
|
||||
'--with-qemu-exe',
|
||||
'--with-sixgill',
|
||||
'--with-soft-float',
|
||||
'--with-system-bz2',
|
||||
'--with-system-icu',
|
||||
'--with-system-libevent',
|
||||
|
@ -261,8 +257,6 @@ def old_configure_options(*options):
|
|||
'--with-system-nss',
|
||||
'--with-system-png',
|
||||
'--with-system-zlib',
|
||||
'--with-thumb',
|
||||
'--with-thumb-interwork',
|
||||
'--with-unify-dist',
|
||||
'--with-user-appdir',
|
||||
'--x-includes',
|
||||
|
|
|
@ -1183,6 +1183,7 @@ def msvs_version(info):
|
|||
set_config('MSVS_VERSION', msvs_version)
|
||||
|
||||
include('compile-checks.configure')
|
||||
include('arm.configure', when=depends(target.cpu)(lambda cpu: cpu == 'arm'))
|
||||
|
||||
|
||||
@depends(have_64_bit,
|
||||
|
|
|
@ -2810,7 +2810,7 @@ html[dir="rtl"] .editor-mount {
|
|||
}
|
||||
|
||||
.debug-expression,
|
||||
.new-debug-line .column-breakpoint {
|
||||
.debug-expression ~ .CodeMirror-widget {
|
||||
background-color: var(--debug-expression-background);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,21 +3,20 @@
|
|||
* file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
|
||||
|
||||
// @flow
|
||||
|
||||
import { setBreakpointPositions } from "./breakpointPositions";
|
||||
import {
|
||||
breakpointExists,
|
||||
assertBreakpoint,
|
||||
createBreakpoint,
|
||||
getASTLocation,
|
||||
makeBreakpointId,
|
||||
makeBreakpointLocation,
|
||||
findPosition
|
||||
makeBreakpointLocation
|
||||
} from "../../utils/breakpoint";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import {
|
||||
getSymbols,
|
||||
getFirstBreakpointPosition,
|
||||
getBreakpointPositionsForSource,
|
||||
getBreakpointPositionsForLocation,
|
||||
getSourceFromId
|
||||
} from "../../selectors";
|
||||
|
||||
|
@ -101,15 +100,14 @@ export function addBreakpoint(
|
|||
) {
|
||||
return async ({ dispatch, getState, sourceMaps, client }: ThunkArgs) => {
|
||||
recordEvent("add_breakpoint");
|
||||
let position;
|
||||
|
||||
const { sourceId, column } = location;
|
||||
|
||||
if (column === undefined) {
|
||||
position = getFirstBreakpointPosition(getState(), location);
|
||||
} else {
|
||||
const positions = getBreakpointPositionsForSource(getState(), sourceId);
|
||||
position = findPosition(positions, location);
|
||||
}
|
||||
await dispatch(setBreakpointPositions(sourceId));
|
||||
|
||||
const position = column
|
||||
? getBreakpointPositionsForLocation(getState(), location)
|
||||
: getFirstBreakpointPosition(getState(), location);
|
||||
|
||||
if (!position) {
|
||||
return;
|
||||
|
|
|
@ -123,6 +123,9 @@ export function setBreakpointPositions(sourceId: string) {
|
|||
(async () => {
|
||||
try {
|
||||
await _setBreakpointPositions(sourceId, thunkArgs);
|
||||
} catch (e) {
|
||||
// TODO: Address exceptions originating from 1536618
|
||||
// `Debugger.Source belongs to a different Debugger`
|
||||
} finally {
|
||||
requests.delete(sourceId);
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ async function loadSourceTextPromise(
|
|||
|
||||
if (!newSource.isWasm && isLoaded(newSource)) {
|
||||
parser.setSource(newSource);
|
||||
await dispatch(setBreakpointPositions(newSource.id));
|
||||
dispatch(setBreakpointPositions(newSource.id));
|
||||
}
|
||||
|
||||
return newSource;
|
||||
|
@ -105,6 +105,7 @@ export function loadSourceText(inputSource: ?Source) {
|
|||
if (!inputSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This ensures that the falsy check above is preserved into the IIFE
|
||||
// below in a way that Flow is happy with.
|
||||
const source = inputSource;
|
||||
|
|
|
@ -114,7 +114,7 @@ html[dir="rtl"] .editor-mount {
|
|||
}
|
||||
|
||||
.debug-expression,
|
||||
.new-debug-line .column-breakpoint {
|
||||
.debug-expression ~ .CodeMirror-widget {
|
||||
background-color: var(--debug-expression-background);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
* @module reducers/breakpoints
|
||||
*/
|
||||
|
||||
import { isGeneratedId, isOriginalId } from "devtools-source-map";
|
||||
import { isGeneratedId } from "devtools-source-map";
|
||||
import { isEqual } from "lodash";
|
||||
|
||||
import { makeBreakpointId } from "../utils/breakpoint";
|
||||
import { makeBreakpointId, findPosition } from "../utils/breakpoint";
|
||||
import { findEmptyLines } from "../utils/empty-lines";
|
||||
|
||||
// eslint-disable-next-line max-len
|
||||
|
@ -22,6 +22,7 @@ import type {
|
|||
XHRBreakpoint,
|
||||
Breakpoint,
|
||||
BreakpointId,
|
||||
MappedLocation,
|
||||
SourceLocation,
|
||||
BreakpointPositions
|
||||
} from "../types";
|
||||
|
@ -380,19 +381,13 @@ export function hasBreakpointPositions(
|
|||
return !!getBreakpointPositionsForSource(state, sourceId);
|
||||
}
|
||||
|
||||
export function getBreakpointPositionsForLine(
|
||||
export function getBreakpointPositionsForLocation(
|
||||
state: OuterState,
|
||||
sourceId: string,
|
||||
line: number
|
||||
): ?BreakpointPositions {
|
||||
location: SourceLocation
|
||||
): ?MappedLocation {
|
||||
const { sourceId } = location;
|
||||
const positions = getBreakpointPositionsForSource(state, sourceId);
|
||||
if (!positions) {
|
||||
return null;
|
||||
}
|
||||
return positions.filter(({ location, generatedLocation }) => {
|
||||
const loc = isOriginalId(sourceId) ? location : generatedLocation;
|
||||
return loc.line == line;
|
||||
});
|
||||
return findPosition(positions, location);
|
||||
}
|
||||
|
||||
export function isEmptyLineInSource(
|
||||
|
|
|
@ -32,6 +32,10 @@
|
|||
"waitForClipboard": false,
|
||||
"waitForExplicitFinish": false,
|
||||
"waitForFocus": false,
|
||||
"selectSource": false,
|
||||
"prettyPrint": false,
|
||||
"closeTab": false,
|
||||
"assertEditorBreakpoint": false,
|
||||
|
||||
// Globals introduced in debugger-specific head.js
|
||||
"promise": false,
|
||||
|
@ -42,8 +46,12 @@
|
|||
"waitForThreadEvents": false,
|
||||
"waitForState": false,
|
||||
"waitForElement": false,
|
||||
"waitForElementWithSelector": false,
|
||||
"waitForPaused": false,
|
||||
"waitForSources": false,
|
||||
"waitForSource": false,
|
||||
"waitForLoadedSource": false,
|
||||
"waitForSelectedSource": false,
|
||||
"isPaused": false,
|
||||
"assertPausedLocation": false,
|
||||
"assertHighlightLocation": false,
|
||||
|
@ -68,6 +76,7 @@
|
|||
"toggleScopes": false,
|
||||
"isVisibleWithin": false,
|
||||
"clickElement": false,
|
||||
"clickElementWithSelector": false,
|
||||
"rightClickElement": false,
|
||||
"selectMenuItem": false,
|
||||
"togglePauseOnExceptions": false,
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.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/>. */
|
||||
|
||||
// Tests pending breakpoints when reloading
|
||||
requestLongerTimeout(3);
|
||||
|
@ -20,16 +21,13 @@ function addBreakpoint(dbg, line) {
|
|||
}
|
||||
|
||||
function assertEditorBreakpoint(dbg, line) {
|
||||
const exists = !!getLineEl(dbg, line).querySelector(".new-breakpoint");
|
||||
const lineEl = getLineEl(dbg, line);
|
||||
const exists = lineEl.classList.contains("new-breakpoint");
|
||||
ok(exists, `Breakpoint exists on line ${line}`);
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-scripts.html", "simple1.js");
|
||||
const {
|
||||
selectors: { getBreakpoints, getBreakpoint },
|
||||
getState
|
||||
} = dbg;
|
||||
const source = findSource(dbg, "simple1.js");
|
||||
|
||||
await selectSource(dbg, source.url);
|
||||
|
|
|
@ -10,6 +10,10 @@ add_task(async function() {
|
|||
clickElementWithSelector(dbg, ".watch-expressions-pane ._header");
|
||||
|
||||
info(">> Click + to add the new expression");
|
||||
await waitForElementWithSelector(
|
||||
dbg,
|
||||
".watch-expressions-pane ._header .plus"
|
||||
);
|
||||
clickElementWithSelector(dbg, ".watch-expressions-pane ._header .plus");
|
||||
|
||||
info(">> Ensure element gets focused");
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-pretty.html", "pretty.js");
|
||||
|
||||
await selectSource(dbg, "pretty.js")
|
||||
await selectSource(dbg, "pretty.js");
|
||||
await prettyPrint(dbg);
|
||||
|
||||
await addBreakpoint(dbg, "pretty.js:formatted", 5);
|
||||
|
|
|
@ -58,6 +58,7 @@ add_task(async function() {
|
|||
|
||||
const selectedSource = dbg.selectors.getSelectedSource(dbg.getState());
|
||||
ok(selectedSource.url.includes("switching-01"));
|
||||
await waitForLoadedSource(dbg, "switching-01");
|
||||
});
|
||||
|
||||
add_task(async function() {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.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/>. */
|
||||
|
||||
/*
|
||||
* Test reloading:
|
||||
|
@ -21,19 +22,23 @@ function getBreakpoints(dbg) {
|
|||
return dbg.selectors.getBreakpointsList(dbg.getState());
|
||||
}
|
||||
|
||||
function getBreakpointCount(dbg) {
|
||||
return dbg.selectors.getBreakpointCount(dbg.getState());
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
const dbg = await initDebugger("doc-minified.html");
|
||||
|
||||
await navigate(dbg, "sourcemaps-reload/doc-sourcemaps-reload.html", "v1.js");
|
||||
|
||||
info('Add initial breakpoint');
|
||||
info("Add initial breakpoint");
|
||||
await selectSource(dbg, "v1.js");
|
||||
await addBreakpoint(dbg, "v1.js", 6);
|
||||
|
||||
let breakpoint = getBreakpoints(dbg)[0];
|
||||
is(breakpoint.location.line, 6);
|
||||
|
||||
info('Reload with a new version of the file');
|
||||
info("Reload with a new version of the file");
|
||||
let syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT");
|
||||
await navigate(dbg, "doc-sourcemaps-reload2.html", "v1.js");
|
||||
|
||||
|
@ -43,18 +48,17 @@ add_task(async function() {
|
|||
is(breakpoint.location.line, 9);
|
||||
is(breakpoint.generatedLocation.line, 79);
|
||||
|
||||
info('Add a second breakpoint');
|
||||
info("Add a second breakpoint");
|
||||
await addBreakpoint(dbg, "v1.js", 13);
|
||||
is(dbg.selectors.getBreakpointCount(dbg.getState()), 2, "No breakpoints");
|
||||
|
||||
is(getBreakpointCount(dbg), 2, "No breakpoints");
|
||||
|
||||
// NOTE: When we reload, the `foo` function and the
|
||||
// module is no longer 13 lines long
|
||||
info('Reload and observe no breakpoints')
|
||||
info("Reload and observe no breakpoints");
|
||||
syncBp = waitForDispatch(dbg, "SYNC_BREAKPOINT", 2);
|
||||
await navigate(dbg, "doc-sourcemaps-reload3.html", "v1.js");
|
||||
await waitForSource(dbg, "v1");
|
||||
await syncBp;
|
||||
|
||||
is(getBreakpoints(dbg).length, 0, "No breakpoints");
|
||||
is(getBreakpointCount(dbg), 0, "No breakpoints");
|
||||
});
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable no-unused-vars */
|
||||
/* 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/>. */
|
||||
|
@ -41,40 +42,17 @@ async function waitFor(condition) {
|
|||
}
|
||||
|
||||
// Wait until an action of `type` is dispatched. This is different
|
||||
// then `_afterDispatchDone` because it doesn't wait for async actions
|
||||
// then `waitForDispatch` because it doesn't wait for async actions
|
||||
// to be done/errored. Use this if you want to listen for the "start"
|
||||
// action of an async operation (somewhat rare).
|
||||
function waitForNextDispatch(store, type) {
|
||||
function waitForNextDispatch(store, actionType) {
|
||||
return new Promise(resolve => {
|
||||
store.dispatch({
|
||||
// Normally we would use `services.WAIT_UNTIL`, but use the
|
||||
// internal name here so tests aren't forced to always pass it
|
||||
// in
|
||||
type: "@@service/waitUntil",
|
||||
predicate: action => action.type === type,
|
||||
run: (dispatch, getState, action) => {
|
||||
resolve(action);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Wait until an action of `type` is dispatched. If it's part of an
|
||||
// async operation, wait until the `status` field is "done" or "error"
|
||||
function _afterDispatchDone(store, type) {
|
||||
return new Promise(resolve => {
|
||||
store.dispatch({
|
||||
// Normally we would use `services.WAIT_UNTIL`, but use the
|
||||
// internal name here so tests aren't forced to always pass it
|
||||
// in
|
||||
type: "@@service/waitUntil",
|
||||
predicate: action => {
|
||||
if (action.type === type) {
|
||||
return action.status
|
||||
? action.status === "done" || action.status === "error"
|
||||
: true;
|
||||
}
|
||||
},
|
||||
predicate: action => action.type === actionType,
|
||||
run: (dispatch, getState, action) => {
|
||||
resolve(action);
|
||||
}
|
||||
|
@ -93,16 +71,28 @@ function _afterDispatchDone(store, type) {
|
|||
* @return {Promise}
|
||||
* @static
|
||||
*/
|
||||
function waitForDispatch(dbg, type, eventRepeat = 1) {
|
||||
function waitForDispatch(dbg, actionType, eventRepeat = 1) {
|
||||
let count = 0;
|
||||
return new Promise(resolve => {
|
||||
dbg.store.dispatch({
|
||||
// Normally we would use `services.WAIT_UNTIL`, but use the
|
||||
// internal name here so tests aren't forced to always pass it
|
||||
// in
|
||||
type: "@@service/waitUntil",
|
||||
predicate: action => {
|
||||
const isDone =
|
||||
!action.status ||
|
||||
action.status === "done" ||
|
||||
action.status === "error";
|
||||
|
||||
return Task.spawn(function*() {
|
||||
info(`Waiting for ${type} to dispatch ${eventRepeat} time(s)`);
|
||||
while (count < eventRepeat) {
|
||||
yield _afterDispatchDone(dbg.store, type);
|
||||
count++;
|
||||
info(`${type} dispatched ${count} time(s)`);
|
||||
}
|
||||
if (action.type === actionType && isDone && ++count == eventRepeat) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
run: (dispatch, getState, action) => {
|
||||
resolve(action);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -737,10 +727,13 @@ async function navigate(dbg, url, ...sources) {
|
|||
return waitForSources(dbg, ...sources);
|
||||
}
|
||||
|
||||
function getFirstBreakpointColumn(dbg, {line, sourceId}) {
|
||||
const {getSource, getFirstBreakpointPosition} = dbg.selectors;
|
||||
const source = getSource(dbg.getState(), sourceId)
|
||||
const position = getFirstBreakpointPosition(dbg.getState(), { line, sourceId });
|
||||
function getFirstBreakpointColumn(dbg, { line, sourceId }) {
|
||||
const { getSource, getFirstBreakpointPosition } = dbg.selectors;
|
||||
const source = getSource(dbg.getState(), sourceId);
|
||||
const position = getFirstBreakpointPosition(dbg.getState(), {
|
||||
line,
|
||||
sourceId
|
||||
});
|
||||
|
||||
return getSelectedLocation(position, source).column;
|
||||
}
|
||||
|
@ -759,15 +752,19 @@ function getFirstBreakpointColumn(dbg, {line, sourceId}) {
|
|||
async function addBreakpoint(dbg, source, line, column, options) {
|
||||
source = findSource(dbg, source);
|
||||
const sourceId = source.id;
|
||||
column = column || getFirstBreakpointColumn(dbg, {line, sourceId: source.id});
|
||||
const bpCount = dbg.selectors.getBreakpointCount(dbg.getState());
|
||||
dbg.actions.addBreakpoint({ sourceId, line, column }, options);
|
||||
await waitForDispatch(dbg, "ADD_BREAKPOINT");
|
||||
is(dbg.selectors.getBreakpointCount(dbg.getState()), bpCount + 1, "a new breakpoint was created");
|
||||
is(
|
||||
dbg.selectors.getBreakpointCount(dbg.getState()),
|
||||
bpCount + 1,
|
||||
"a new breakpoint was created"
|
||||
);
|
||||
}
|
||||
|
||||
function disableBreakpoint(dbg, source, line, column) {
|
||||
column = column || getFirstBreakpointColumn(dbg, {line, sourceId: source.id});
|
||||
column =
|
||||
column || getFirstBreakpointColumn(dbg, { line, sourceId: source.id });
|
||||
const location = { sourceId: source.id, sourceUrl: source.url, line, column };
|
||||
const bp = dbg.selectors.getBreakpointForLocation(dbg.getState(), location);
|
||||
dbg.actions.disableBreakpoint(bp);
|
||||
|
@ -1255,10 +1252,7 @@ async function clickElement(dbg, elementName, ...args) {
|
|||
}
|
||||
|
||||
function clickElementWithSelector(dbg, selector) {
|
||||
clickDOMElement(
|
||||
dbg,
|
||||
findElementWithSelector(dbg, selector)
|
||||
);
|
||||
clickDOMElement(dbg, findElementWithSelector(dbg, selector));
|
||||
}
|
||||
|
||||
function clickDOMElement(dbg, element) {
|
||||
|
|
|
@ -103,6 +103,11 @@ class ViewportDimension extends PureComponent {
|
|||
const { target } = event;
|
||||
target.value = parseInt(target.value, 10) + increment;
|
||||
this.onInputChange(event, this.onInputSubmit);
|
||||
|
||||
// Keep this event from having default processing. Since the field is a
|
||||
// number field, default processing would trigger additional manipulations
|
||||
// of the value, and we've already applied the desired amount.
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
onInputKeyUp({ target, keyCode }) {
|
||||
|
@ -162,6 +167,7 @@ class ViewportDimension extends PureComponent {
|
|||
className: "text-input viewport-dimension-input" +
|
||||
(this.state.isWidthValid ? "" : " invalid"),
|
||||
size: 4,
|
||||
type: "number",
|
||||
value: this.state.width,
|
||||
onBlur: this.onInputBlur,
|
||||
onChange: this.onInputChange,
|
||||
|
@ -179,6 +185,7 @@ class ViewportDimension extends PureComponent {
|
|||
className: "text-input viewport-dimension-input" +
|
||||
(this.state.isHeightValid ? "" : " invalid"),
|
||||
size: 4,
|
||||
type: "number",
|
||||
value: this.state.height,
|
||||
onBlur: this.onInputBlur,
|
||||
onChange: this.onInputChange,
|
||||
|
|
|
@ -362,6 +362,7 @@ body,
|
|||
.viewport-dimension-input {
|
||||
text-align: center;
|
||||
width: 3em;
|
||||
-moz-appearance: textfield;
|
||||
}
|
||||
|
||||
.viewport-dimension-separator {
|
||||
|
|
|
@ -319,7 +319,9 @@ class IdleDispatchRunnable final : public IdleRunnable,
|
|||
mCallback(&aCallback),
|
||||
mParent(aParent) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT.
|
||||
// See bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
|
||||
if (mCallback) {
|
||||
CancelTimer();
|
||||
|
||||
|
@ -329,12 +331,10 @@ class IdleDispatchRunnable final : public IdleRunnable,
|
|||
RefPtr<IdleDeadline> idleDeadline =
|
||||
new IdleDeadline(mParent, mTimedOut, deadline.ToMilliseconds());
|
||||
|
||||
mCallback->Call(*idleDeadline, rv, "ChromeUtils::IdleDispatch handler");
|
||||
mCallback = nullptr;
|
||||
RefPtr<IdleRequestCallback> callback(mCallback.forget());
|
||||
MOZ_ASSERT(!mCallback);
|
||||
callback->Call(*idleDeadline, "ChromeUtils::IdleDispatch handler");
|
||||
mParent = nullptr;
|
||||
|
||||
rv.SuppressException();
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -460,7 +460,8 @@ void DOMIntersectionObserver::Notify() {
|
|||
}
|
||||
}
|
||||
mQueuedEntries.Clear();
|
||||
mCallback->Call(this, entries, *this);
|
||||
RefPtr<dom::IntersectionCallback> callback(mCallback);
|
||||
callback->Call(this, entries, *this);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef DOMIntersectionObserver_h
|
||||
#define DOMIntersectionObserver_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/IntersectionObserverBinding.h"
|
||||
#include "nsStyleCoord.h"
|
||||
#include "nsTArray.h"
|
||||
|
@ -132,7 +133,7 @@ class DOMIntersectionObserver final : public nsISupports,
|
|||
bool SetRootMargin(const nsAString& aString);
|
||||
|
||||
void Update(Document* aDocument, DOMHighResTimeStamp time);
|
||||
void Notify();
|
||||
MOZ_CAN_RUN_SCRIPT void Notify();
|
||||
|
||||
protected:
|
||||
void Connect();
|
||||
|
|
|
@ -11830,7 +11830,7 @@ DocumentAutoplayPolicy Document::AutoplayPolicy() const {
|
|||
}
|
||||
|
||||
void Document::MaybeAllowStorageForOpenerAfterUserInteraction() {
|
||||
if (mCookieSettings->GetCookieBehavior() !=
|
||||
if (CookieSettings()->GetCookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
return;
|
||||
}
|
||||
|
@ -12352,7 +12352,7 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
|
|||
}
|
||||
|
||||
// Only enforce third-party checks when there is a reason to enforce them.
|
||||
if (mCookieSettings->GetCookieBehavior() !=
|
||||
if (CookieSettings()->GetCookieBehavior() !=
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER) {
|
||||
// Step 3. If the document's frame is the main frame, resolve.
|
||||
if (IsTopLevelContentDocument()) {
|
||||
|
@ -12405,7 +12405,7 @@ already_AddRefed<mozilla::dom::Promise> Document::RequestStorageAccess(
|
|||
return promise.forget();
|
||||
}
|
||||
|
||||
if (mCookieSettings->GetCookieBehavior() ==
|
||||
if (CookieSettings()->GetCookieBehavior() ==
|
||||
nsICookieService::BEHAVIOR_REJECT_TRACKER &&
|
||||
inner) {
|
||||
// Only do something special for third-party tracking content.
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsContentListDeclarations.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "mozilla/dom/BrowsingContext.h"
|
||||
#include "mozilla/dom/ContentBlockingLog.h"
|
||||
|
@ -3487,7 +3488,7 @@ class Document : public nsINode,
|
|||
|
||||
void UpdateIntersectionObservations();
|
||||
void ScheduleIntersectionObserverNotification();
|
||||
void NotifyIntersectionObservers();
|
||||
MOZ_CAN_RUN_SCRIPT void NotifyIntersectionObservers();
|
||||
|
||||
// Dispatch a runnable related to the document.
|
||||
nsresult Dispatch(TaskCategory aCategory,
|
||||
|
|
|
@ -51,19 +51,16 @@ uint32_t IdleRequest::GetTimeoutHandle() const {
|
|||
return mTimeoutHandle.value();
|
||||
}
|
||||
|
||||
nsresult IdleRequest::IdleRun(nsPIDOMWindowInner* aWindow,
|
||||
DOMHighResTimeStamp aDeadline, bool aDidTimeout) {
|
||||
void IdleRequest::IdleRun(nsPIDOMWindowInner* aWindow,
|
||||
DOMHighResTimeStamp aDeadline, bool aDidTimeout) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mCallback);
|
||||
|
||||
ErrorResult error;
|
||||
RefPtr<IdleDeadline> deadline =
|
||||
new IdleDeadline(aWindow, aDidTimeout, aDeadline);
|
||||
mCallback->Call(*deadline, error, "requestIdleCallback handler");
|
||||
|
||||
mCallback = nullptr;
|
||||
error.SuppressException();
|
||||
return error.StealNSResult();
|
||||
RefPtr<IdleRequestCallback> callback(mCallback.forget());
|
||||
MOZ_ASSERT(!mCallback);
|
||||
callback->Call(*deadline, "requestIdleCallback handler");
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -28,8 +28,9 @@ class IdleRequest final : public LinkedListElement<RefPtr<IdleRequest>> {
|
|||
public:
|
||||
IdleRequest(IdleRequestCallback* aCallback, uint32_t aHandle);
|
||||
|
||||
nsresult IdleRun(nsPIDOMWindowInner* aWindow, DOMHighResTimeStamp aDeadline,
|
||||
bool aDidTimeout);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void IdleRun(nsPIDOMWindowInner* aWindow, DOMHighResTimeStamp aDeadline,
|
||||
bool aDidTimeout);
|
||||
|
||||
void SetTimeoutHandle(int32_t aHandle);
|
||||
bool HasTimeout() const { return mTimeoutHandle.isSome(); }
|
||||
|
|
|
@ -91,20 +91,23 @@ class EncodingCompleteEvent : public CancelableRunnable {
|
|||
}
|
||||
}
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHOD Run() override {
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// We want to null out mEncodeCompleteCallback no matter what.
|
||||
RefPtr<EncodeCompleteCallback> callback(mEncodeCompleteCallback.forget());
|
||||
if (!mFailed) {
|
||||
// The correct parentObject has to be set by the mEncodeCompleteCallback.
|
||||
RefPtr<Blob> blob =
|
||||
Blob::CreateMemoryBlob(nullptr, mImgData, mImgSize, mType);
|
||||
MOZ_ASSERT(blob);
|
||||
|
||||
rv = mEncodeCompleteCallback->ReceiveBlob(blob.forget());
|
||||
rv = callback->ReceiveBlob(blob.forget());
|
||||
}
|
||||
|
||||
mEncodeCompleteCallback = nullptr;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ class EncodeCompleteCallback {
|
|||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EncodeCompleteCallback)
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual nsresult ReceiveBlob(already_AddRefed<Blob> aBlob) = 0;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -1240,8 +1240,8 @@ void Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
|
|||
return;
|
||||
}
|
||||
|
||||
MediaManager::GetUserMediaSuccessCallback onsuccess(&aOnSuccess);
|
||||
MediaManager::GetUserMediaErrorCallback onerror(&aOnError);
|
||||
RefPtr<NavigatorUserMediaSuccessCallback> onsuccess(&aOnSuccess);
|
||||
RefPtr<NavigatorUserMediaErrorCallback> onerror(&aOnError);
|
||||
|
||||
nsWeakPtr weakWindow = nsWeakPtr(do_GetWeakReference(mWindow));
|
||||
|
||||
|
@ -1250,23 +1250,23 @@ void Navigator::MozGetUserMedia(const MediaStreamConstraints& aConstraints,
|
|||
->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[weakWindow, onsuccess = std::move(onsuccess)](
|
||||
const RefPtr<DOMMediaStream>& aStream) {
|
||||
const RefPtr<DOMMediaStream>& aStream) MOZ_CAN_RUN_SCRIPT {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(weakWindow);
|
||||
if (!window || !window->GetOuterWindow() ||
|
||||
window->GetOuterWindow()->GetCurrentInnerWindow() != window) {
|
||||
return; // Leave Promise pending after navigation by design.
|
||||
}
|
||||
MediaManager::CallOnSuccess(&onsuccess, *aStream);
|
||||
MediaManager::CallOnSuccess(*onsuccess, *aStream);
|
||||
},
|
||||
[weakWindow,
|
||||
onerror = std::move(onerror)](const RefPtr<MediaMgrError>& aError) {
|
||||
[weakWindow, onerror = std::move(onerror)](
|
||||
const RefPtr<MediaMgrError>& aError) MOZ_CAN_RUN_SCRIPT {
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryReferent(weakWindow);
|
||||
if (!window || !window->GetOuterWindow() ||
|
||||
window->GetOuterWindow()->GetCurrentInnerWindow() != window) {
|
||||
return; // Leave Promise pending after navigation by design.
|
||||
}
|
||||
auto error = MakeRefPtr<MediaStreamError>(window, *aError);
|
||||
MediaManager::CallOnError(&onerror, *error);
|
||||
MediaManager::CallOnError(*onerror, *error);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1281,9 +1281,10 @@ void Navigator::MozGetUserMediaDevices(
|
|||
return;
|
||||
}
|
||||
|
||||
MediaManager* manager = MediaManager::Get();
|
||||
RefPtr<MediaManager> manager = MediaManager::Get();
|
||||
// XXXbz aOnError seems to be unused?
|
||||
aRv = manager->GetUserMediaDevices(mWindow, aConstraints, aOnSuccess,
|
||||
nsCOMPtr<nsPIDOMWindowInner> window(mWindow);
|
||||
aRv = manager->GetUserMediaDevices(window, aConstraints, aOnSuccess,
|
||||
aInnerWindowID, aCallID);
|
||||
}
|
||||
|
||||
|
|
|
@ -186,6 +186,7 @@ class Navigator final : public nsISupports, public nsWrapperCache {
|
|||
NavigatorUserMediaSuccessCallback& aOnSuccess,
|
||||
NavigatorUserMediaErrorCallback& aOnError,
|
||||
CallerType aCallerType, ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void MozGetUserMediaDevices(const MediaStreamConstraints& aConstraints,
|
||||
MozGetUserMediaDevicesSuccessCallback& aOnSuccess,
|
||||
NavigatorUserMediaErrorCallback& aOnError,
|
||||
|
|
|
@ -90,7 +90,7 @@ uint32_t GetFlagsForEvents(
|
|||
}
|
||||
|
||||
template <class TWrapped, class TUnwrapped>
|
||||
void CallListeners(
|
||||
MOZ_CAN_RUN_SCRIPT void CallListeners(
|
||||
uint32_t aEventFlags, FlaggedArray<TWrapped>& aListeners,
|
||||
const Sequence<OwningNonNull<PlacesEvent>>& aEvents,
|
||||
const std::function<TUnwrapped(TWrapped&)>& aUnwrapListener,
|
||||
|
@ -283,7 +283,12 @@ void PlacesObservers::NotifyListeners(
|
|||
|
||||
CallListeners<RefPtr<PlacesEventCallback>, RefPtr<PlacesEventCallback>>(
|
||||
flags, *JSListeners::GetListeners(), aEvents, [](auto& cb) { return cb; },
|
||||
[&](auto& cb, const auto& events) { cb->Call(aEvents); });
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY because on Windows this gets called from
|
||||
// some internals of the std::function implementation that we can't
|
||||
// annotate. We handle this by annotating CallListeners and making sure
|
||||
// it holds a strong ref to the callback.
|
||||
[&](auto& cb, const auto& events)
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY { cb->Call(aEvents); });
|
||||
|
||||
CallListeners<WeakPtr<places::INativePlacesEventCallback>,
|
||||
RefPtr<places::INativePlacesEventCallback>>(
|
||||
|
@ -297,7 +302,14 @@ void PlacesObservers::NotifyListeners(
|
|||
RefPtr<PlacesWeakCallbackWrapper>>(
|
||||
flags, *WeakJSListeners::GetListeners(), aEvents,
|
||||
[](auto& cb) { return cb.get(); },
|
||||
[&](auto& cb, const auto& events) { cb->mCallback->Call(aEvents); });
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY because on Windows this gets called from
|
||||
// some internals of the std::function implementation that we can't
|
||||
// annotate. We handle this by annotating CallListeners and making sure
|
||||
// it holds a strong ref to the callback.
|
||||
[&](auto& cb, const auto& events) MOZ_CAN_RUN_SCRIPT_BOUNDARY {
|
||||
RefPtr<PlacesEventCallback> callback(cb->mCallback);
|
||||
callback->Call(aEvents);
|
||||
});
|
||||
|
||||
auto& listenersToRemove = *JSListeners::GetListenersToRemove();
|
||||
if (listenersToRemove.Length() > 0) {
|
||||
|
|
|
@ -41,10 +41,12 @@ class PlacesObservers {
|
|||
static void RemoveListener(const nsTArray<PlacesEventType>& aEventTypes,
|
||||
places::INativePlacesEventCallback* aCallback);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void NotifyListeners(
|
||||
GlobalObject& aGlobal,
|
||||
const Sequence<OwningNonNull<PlacesEvent>>& aEvents, ErrorResult& rv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void NotifyListeners(
|
||||
const Sequence<OwningNonNull<PlacesEvent>>& aEvents);
|
||||
|
||||
|
|
|
@ -221,8 +221,9 @@ void TimeoutExecutor::Cancel() {
|
|||
mDeadline = TimeStamp();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
TimeoutExecutor::Run() {
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP TimeoutExecutor::Run() {
|
||||
// If the executor is canceled and then rescheduled its possible to get
|
||||
// spurious executions here. Ignore these unless our current mode matches.
|
||||
MOZ_LOG(gTimeoutLog, LogLevel::Debug,
|
||||
|
@ -233,7 +234,9 @@ TimeoutExecutor::Run() {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsITimerCallback::Notify is
|
||||
// MOZ_CAN_RUN_SCRIPT.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP
|
||||
TimeoutExecutor::Notify(nsITimer* aTimer) {
|
||||
// If the executor is canceled and then rescheduled its possible to get
|
||||
// spurious executions here. Ignore these unless our current mode matches.
|
||||
|
|
|
@ -66,7 +66,7 @@ class TimeoutExecutor final : public nsIRunnable,
|
|||
nsresult MaybeReschedule(const TimeStamp& aDeadline,
|
||||
const TimeDuration& aMinDelay);
|
||||
|
||||
void MaybeExecute();
|
||||
MOZ_CAN_RUN_SCRIPT void MaybeExecute();
|
||||
|
||||
public:
|
||||
TimeoutExecutor(TimeoutManager* aOwner, bool aIsIdleQueue,
|
||||
|
|
|
@ -14,7 +14,7 @@ TimeoutHandler::TimeoutHandler(JSContext* aCx) : TimeoutHandler() {
|
|||
nsJSUtils::GetCallingLocation(aCx, mFileName, &mLineNo, &mColumn);
|
||||
}
|
||||
|
||||
nsresult TimeoutHandler::Call() { return NS_OK; }
|
||||
void TimeoutHandler::Call() {}
|
||||
|
||||
void TimeoutHandler::GetLocation(const char** aFileName, uint32_t* aLineNo,
|
||||
uint32_t* aColumn) {
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsITimeoutHandler.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsString.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -26,7 +27,7 @@ class TimeoutHandler : public nsITimeoutHandler {
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(TimeoutHandler)
|
||||
|
||||
virtual nsresult Call() override;
|
||||
MOZ_CAN_RUN_SCRIPT virtual void Call() override;
|
||||
virtual void GetLocation(const char** aFileName, uint32_t* aLineNo,
|
||||
uint32_t* aColumn) override;
|
||||
virtual void MarkForCC() override {}
|
||||
|
|
|
@ -741,11 +741,10 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
|
|||
|
||||
// Make sure that the window and the script context don't go away as
|
||||
// a result of running timeouts
|
||||
nsCOMPtr<nsIScriptGlobalObject> windowKungFuDeathGrip(&mWindow);
|
||||
// Silence the static analysis error about windowKungFuDeathGrip. Accessing
|
||||
// members of mWindow here is safe, because the lifetime of TimeoutManager is
|
||||
// the same as the lifetime of the containing nsGlobalWindow.
|
||||
Unused << windowKungFuDeathGrip;
|
||||
RefPtr<nsGlobalWindowInner> window(&mWindow);
|
||||
// Accessing members of mWindow here is safe, because the lifetime of
|
||||
// TimeoutManager is the same as the lifetime of the containing
|
||||
// nsGlobalWindow.
|
||||
|
||||
// A native timer has gone off. See which of our timeouts need
|
||||
// servicing
|
||||
|
@ -976,8 +975,9 @@ void TimeoutManager::RunTimeout(const TimeStamp& aNow,
|
|||
MOZ_ASSERT(timeout->mFiringIndex > mLastFiringIndex);
|
||||
mLastFiringIndex = timeout->mFiringIndex;
|
||||
#endif
|
||||
// This timeout is good to run
|
||||
bool timeout_was_cleared = mWindow.RunTimeoutHandler(timeout, scx);
|
||||
// This timeout is good to run.
|
||||
bool timeout_was_cleared =
|
||||
window->RunTimeoutHandler(timeout, scx);
|
||||
#if MOZ_GECKO_PROFILER
|
||||
if (profiler_is_active()) {
|
||||
TimeDuration elapsed = now - timeout->SubmitTime();
|
||||
|
|
|
@ -52,6 +52,7 @@ class TimeoutManager final {
|
|||
bool aIsIdle);
|
||||
|
||||
// The timeout implementation functions.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadline,
|
||||
bool aProcessIdle);
|
||||
|
||||
|
|
|
@ -536,6 +536,7 @@ void nsDOMMutationObserver::ScheduleForRun() {
|
|||
|
||||
class MutationObserverMicroTask final : public MicroTaskRunnable {
|
||||
public:
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void Run(AutoSlowOperation& aAso) override {
|
||||
nsDOMMutationObserver::HandleMutations(aAso);
|
||||
}
|
||||
|
@ -804,7 +805,8 @@ void nsDOMMutationObserver::HandleMutation() {
|
|||
}
|
||||
ClearPendingRecords();
|
||||
|
||||
mCallback->Call(this, mutations, *this);
|
||||
RefPtr<dom::MutationCallback> callback(mCallback);
|
||||
callback->Call(this, mutations, *this);
|
||||
}
|
||||
|
||||
void nsDOMMutationObserver::HandleMutationsInternal(AutoSlowOperation& aAso) {
|
||||
|
|
|
@ -467,7 +467,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
|
|||
|
||||
void TakeRecords(nsTArray<RefPtr<nsDOMMutationRecord>>& aRetVal);
|
||||
|
||||
void HandleMutation();
|
||||
MOZ_CAN_RUN_SCRIPT void HandleMutation();
|
||||
|
||||
void GetObservingInfo(
|
||||
nsTArray<mozilla::dom::Nullable<MutationObservingInfo>>& aResult,
|
||||
|
@ -514,6 +514,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
|
|||
// static methods
|
||||
static void QueueMutationObserverMicroTask();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void HandleMutations(mozilla::AutoSlowOperation& aAso);
|
||||
|
||||
static bool AllScheduledMutationObserversAreSuppressed() {
|
||||
|
@ -561,6 +562,7 @@ class nsDOMMutationObserver final : public nsISupports, public nsWrapperCache {
|
|||
return mOwner && nsGlobalWindowInner::Cast(mOwner)->IsInSyncOperation();
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void HandleMutationsInternal(mozilla::AutoSlowOperation& aAso);
|
||||
|
||||
static void AddCurrentlyHandlingObserver(nsDOMMutationObserver* aObserver,
|
||||
|
|
|
@ -420,7 +420,7 @@ class IdleRequestExecutorTimeoutHandler final : public TimeoutHandler {
|
|||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IdleRequestExecutorTimeoutHandler,
|
||||
TimeoutHandler)
|
||||
|
||||
nsresult Call() override;
|
||||
void Call() override;
|
||||
|
||||
private:
|
||||
~IdleRequestExecutorTimeoutHandler() override {}
|
||||
|
@ -530,13 +530,15 @@ IdleRequestExecutor::GetName(nsACString& aName) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
IdleRequestExecutor::Run() {
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until nsIRunnable::Run is MOZ_CAN_RUN_SCRIPT.
|
||||
// See bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMP IdleRequestExecutor::Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mDispatched = false;
|
||||
if (mWindow) {
|
||||
return mWindow->ExecuteIdleRequest(mDeadline);
|
||||
RefPtr<nsGlobalWindowInner> window(mWindow);
|
||||
window->ExecuteIdleRequest(mDeadline);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -617,11 +619,10 @@ void IdleRequestExecutor::DelayedDispatch(uint32_t aDelay) {
|
|||
mDelayedExecutorHandle = Some(handle);
|
||||
}
|
||||
|
||||
nsresult IdleRequestExecutorTimeoutHandler::Call() {
|
||||
void IdleRequestExecutorTimeoutHandler::Call() {
|
||||
if (!mExecutor->IsCancelled()) {
|
||||
mExecutor->ScheduleDispatch();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsGlobalWindowInner::ScheduleIdleRequestDispatch() {
|
||||
|
@ -659,23 +660,25 @@ void nsGlobalWindowInner::RemoveIdleCallback(
|
|||
aRequest->removeFrom(mIdleRequestCallbacks);
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
|
||||
DOMHighResTimeStamp aDeadline,
|
||||
bool aDidTimeout) {
|
||||
void nsGlobalWindowInner::RunIdleRequest(IdleRequest* aRequest,
|
||||
DOMHighResTimeStamp aDeadline,
|
||||
bool aDidTimeout) {
|
||||
AssertIsOnMainThread();
|
||||
// XXXbz Do we still need this RefPtr? MOZ_CAN_RUN_SCRIPT should
|
||||
// guarantee that caller is holding a strong ref on the stack.
|
||||
RefPtr<IdleRequest> request(aRequest);
|
||||
RemoveIdleCallback(request);
|
||||
return request->IdleRun(this, aDeadline, aDidTimeout);
|
||||
request->IdleRun(this, aDeadline, aDidTimeout);
|
||||
}
|
||||
|
||||
nsresult nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
|
||||
void nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
|
||||
AssertIsOnMainThread();
|
||||
RefPtr<IdleRequest> request = mIdleRequestCallbacks.getFirst();
|
||||
|
||||
if (!request) {
|
||||
// There are no more idle requests, so stop scheduling idle
|
||||
// request callbacks.
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the request that we're trying to execute has been queued
|
||||
|
@ -683,7 +686,7 @@ nsresult nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
|
|||
// of the idle period.
|
||||
if (mIdleRequestExecutor->IneligibleForCurrentIdlePeriod(request)) {
|
||||
mIdleRequestExecutor->MaybeDispatch(aDeadline);
|
||||
return NS_OK;
|
||||
return;
|
||||
}
|
||||
|
||||
DOMHighResTimeStamp deadline = 0.0;
|
||||
|
@ -693,14 +696,13 @@ nsresult nsGlobalWindowInner::ExecuteIdleRequest(TimeStamp aDeadline) {
|
|||
}
|
||||
|
||||
mIdleRequestExecutor->MaybeUpdateIdlePeriodLimit();
|
||||
nsresult result = RunIdleRequest(request, deadline, false);
|
||||
RunIdleRequest(request, deadline, false);
|
||||
|
||||
// Running the idle callback could've suspended the window, in which
|
||||
// case mIdleRequestExecutor will be null.
|
||||
if (mIdleRequestExecutor) {
|
||||
mIdleRequestExecutor->MaybeDispatch();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
class IdleRequestTimeoutHandler final : public TimeoutHandler {
|
||||
|
@ -713,9 +715,10 @@ class IdleRequestTimeoutHandler final : public TimeoutHandler {
|
|||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IdleRequestTimeoutHandler,
|
||||
TimeoutHandler)
|
||||
|
||||
nsresult Call() override {
|
||||
return nsGlobalWindowInner::Cast(mWindow)->RunIdleRequest(mIdleRequest, 0.0,
|
||||
true);
|
||||
MOZ_CAN_RUN_SCRIPT void Call() override {
|
||||
RefPtr<nsGlobalWindowInner> window(nsGlobalWindowInner::Cast(mWindow));
|
||||
RefPtr<IdleRequest> request(mIdleRequest);
|
||||
window->RunIdleRequest(request, 0.0, true);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -5559,6 +5562,8 @@ bool nsGlobalWindowInner::RunTimeoutHandler(Timeout* aTimeout,
|
|||
nsIScriptContext* aScx) {
|
||||
// Hold on to the timeout in case mExpr or mFunObj releases its
|
||||
// doc.
|
||||
// XXXbz Our caller guarantees it'll hold on to the timeout (because
|
||||
// we're MOZ_CAN_RUN_SCRIPT), so we can probably stop doing that...
|
||||
RefPtr<Timeout> timeout = aTimeout;
|
||||
Timeout* last_running_timeout = mTimeoutManager->BeginRunningTimeout(timeout);
|
||||
timeout->mRunning = true;
|
||||
|
@ -7012,7 +7017,7 @@ void nsPIDOMWindowInner::BroadcastReport(Report* aReport) {
|
|||
|
||||
void nsPIDOMWindowInner::NotifyReportingObservers() {
|
||||
nsTArray<RefPtr<ReportingObserver>> reportingObservers(mReportingObservers);
|
||||
for (ReportingObserver* observer : reportingObservers) {
|
||||
for (RefPtr<ReportingObserver>& observer : reportingObservers) {
|
||||
observer->MaybeNotify();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1053,6 +1053,7 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
mozilla::ErrorResult& aError);
|
||||
|
||||
// Return true if |aTimeout| was cleared while its handler ran.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
bool RunTimeoutHandler(mozilla::dom::Timeout* aTimeout,
|
||||
nsIScriptContext* aScx);
|
||||
|
||||
|
@ -1196,9 +1197,11 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
|
|||
uint32_t LastIdleRequestHandle() const {
|
||||
return mIdleRequestCallbackCounter - 1;
|
||||
}
|
||||
nsresult RunIdleRequest(mozilla::dom::IdleRequest* aRequest,
|
||||
DOMHighResTimeStamp aDeadline, bool aDidTimeout);
|
||||
nsresult ExecuteIdleRequest(TimeStamp aDeadline);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void RunIdleRequest(mozilla::dom::IdleRequest* aRequest,
|
||||
DOMHighResTimeStamp aDeadline, bool aDidTimeout);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ExecuteIdleRequest(TimeStamp aDeadline);
|
||||
void ScheduleIdleRequestDispatch();
|
||||
void SuspendIdleRequests();
|
||||
void ResumeIdleRequests();
|
||||
|
|
|
@ -1638,6 +1638,7 @@ class nsINode : public mozilla::dom::EventTarget {
|
|||
|
||||
void GenerateXPath(nsAString& aResult);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
already_AddRefed<mozilla::dom::Promise> Localize(
|
||||
JSContext* aCx, mozilla::dom::L10nCallback& aCallback,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define nsITimeoutHandler_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#define NS_ITIMEOUTHANDLER_IID \
|
||||
{ \
|
||||
|
@ -19,7 +20,7 @@ class nsITimeoutHandler : public nsISupports {
|
|||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ITIMEOUTHANDLER_IID)
|
||||
|
||||
virtual nsresult Call() = 0;
|
||||
MOZ_CAN_RUN_SCRIPT virtual void Call() = 0;
|
||||
|
||||
virtual void GetLocation(const char** aFileName, uint32_t* aLineNo,
|
||||
uint32_t* aColumn) = 0;
|
||||
|
|
|
@ -57,7 +57,7 @@ class nsJSScriptTimeoutHandler final : public nsIScriptTimeoutHandler {
|
|||
|
||||
virtual const nsTArray<JS::Value>& GetArgs() override { return mArgs; }
|
||||
|
||||
virtual nsresult Call() override { return NS_OK; }
|
||||
virtual void Call() override {}
|
||||
|
||||
virtual void GetLocation(const char** aFileName, uint32_t* aLineNo,
|
||||
uint32_t* aColumn) override {
|
||||
|
|
|
@ -555,7 +555,7 @@ class nsPIDOMWindowInner : public mozIDOMWindow {
|
|||
|
||||
void BroadcastReport(mozilla::dom::Report* aReport);
|
||||
|
||||
void NotifyReportingObservers();
|
||||
MOZ_CAN_RUN_SCRIPT void NotifyReportingObservers();
|
||||
|
||||
void SaveStorageAccessGranted(const nsACString& aPermissionKey);
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ class CallbackObject : public nsISupports {
|
|||
const char* aExecutionReason,
|
||||
ExceptionHandling aExceptionHandling, JS::Realm* aRealm = nullptr,
|
||||
bool aIsJSImplementedWebIDL = false);
|
||||
~CallSetup();
|
||||
MOZ_CAN_RUN_SCRIPT ~CallSetup();
|
||||
|
||||
JSContext* GetContext() const { return mCx; }
|
||||
|
||||
|
|
|
@ -31,16 +31,18 @@ void CanvasRenderingContextHelper::ToBlob(
|
|||
: mGlobal(aGlobal), mBlobCallback(aCallback) {}
|
||||
|
||||
// This is called on main thread.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult ReceiveBlob(already_AddRefed<Blob> aBlob) override {
|
||||
RefPtr<Blob> blob = aBlob;
|
||||
|
||||
RefPtr<Blob> newBlob = Blob::Create(mGlobal, blob->Impl());
|
||||
|
||||
RefPtr<BlobCallback> callback(mBlobCallback.forget());
|
||||
ErrorResult rv;
|
||||
mBlobCallback->Call(newBlob, rv);
|
||||
callback->Call(newBlob, rv);
|
||||
|
||||
mGlobal = nullptr;
|
||||
mBlobCallback = nullptr;
|
||||
MOZ_ASSERT(!mBlobCallback);
|
||||
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback PlacesEventCallback = void (sequence<PlacesEvent> events);
|
||||
|
||||
[ChromeOnly, Exposed=Window,
|
||||
|
|
|
@ -8,7 +8,6 @@ interface nsISupports;
|
|||
/**
|
||||
* A callback passed to SessionStoreUtils.forEachNonDynamicChildFrame().
|
||||
*/
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback SessionStoreUtilsFrameCallback = void (WindowProxy frame, unsigned long index);
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
interface URI;
|
||||
interface WindowProxy;
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback WebExtensionLocalizeCallback = DOMString (DOMString unlocalizedText);
|
||||
|
||||
/**
|
||||
|
|
|
@ -445,8 +445,7 @@ class ConsoleRunnable : public StructuredCloneHolderBase {
|
|||
return true;
|
||||
}
|
||||
|
||||
void ProcessProfileData(JSContext* aCx, Console* aConsole,
|
||||
Console::MethodName aMethodName,
|
||||
void ProcessProfileData(JSContext* aCx, Console::MethodName aMethodName,
|
||||
const nsAString& aAction) {
|
||||
AssertIsOnMainThread();
|
||||
|
||||
|
@ -485,7 +484,7 @@ class ConsoleRunnable : public StructuredCloneHolderBase {
|
|||
}
|
||||
}
|
||||
|
||||
aConsole->ProfileMethodInternal(aCx, aMethodName, aAction, arguments);
|
||||
Console::ProfileMethodMainthread(aCx, aAction, arguments);
|
||||
}
|
||||
|
||||
ConsoleStructuredCloneData mClonedData;
|
||||
|
@ -634,7 +633,7 @@ class ConsoleWorkerRunnable : public WorkerProxyToMainThreadRunnable,
|
|||
wp = wp->GetParent();
|
||||
}
|
||||
|
||||
nsPIDOMWindowInner* window = wp->GetWindow();
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = wp->GetWindow();
|
||||
if (!window) {
|
||||
RunWindowless(aWorkerPrivate);
|
||||
} else {
|
||||
|
@ -655,7 +654,7 @@ class ConsoleWorkerRunnable : public WorkerProxyToMainThreadRunnable,
|
|||
return;
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter* outerWindow = aWindow->GetOuterWindow();
|
||||
nsCOMPtr<nsPIDOMWindowOuter> outerWindow = aWindow->GetOuterWindow();
|
||||
if (NS_WARN_IF(!outerWindow)) {
|
||||
return;
|
||||
}
|
||||
|
@ -834,8 +833,7 @@ class ConsoleProfileWorkletRunnable final : public ConsoleWorkletRunnable {
|
|||
|
||||
// We don't need to set a parent object in mCallData bacause there are not
|
||||
// DOM objects exposed to worklet.
|
||||
|
||||
ProcessProfileData(cx, mConsole, mName, mAction);
|
||||
ProcessProfileData(cx, mName, mAction);
|
||||
}
|
||||
|
||||
virtual void ReleaseData() override {}
|
||||
|
@ -870,7 +868,7 @@ class ConsoleProfileWorkerRunnable final : public ConsoleWorkerRunnable {
|
|||
// Now we could have the correct window (if we are not window-less).
|
||||
mClonedData.mParent = aInnerWindow;
|
||||
|
||||
ProcessProfileData(aCx, mConsole, mName, mAction);
|
||||
ProcessProfileData(aCx, mName, mAction);
|
||||
|
||||
mClonedData.mParent = nullptr;
|
||||
}
|
||||
|
@ -1267,6 +1265,13 @@ void Console::ProfileMethodInternal(JSContext* aCx, MethodName aMethodName,
|
|||
return;
|
||||
}
|
||||
|
||||
ProfileMethodMainthread(aCx, aAction, aData);
|
||||
}
|
||||
|
||||
// static
|
||||
void Console::ProfileMethodMainthread(JSContext* aCx, const nsAString& aAction,
|
||||
const Sequence<JS::Value>& aData) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
ConsoleCommon::ClearException ce(aCx);
|
||||
|
||||
RootedDictionary<ConsoleProfileEvent> event(aCx);
|
||||
|
@ -2517,7 +2522,8 @@ void Console::NotifyHandler(JSContext* aCx,
|
|||
}
|
||||
|
||||
JS::Rooted<JS::Value> ignored(aCx);
|
||||
mConsoleEventNotifier->Call(value, &ignored);
|
||||
RefPtr<AnyCallback> notifier(mConsoleEventNotifier);
|
||||
notifier->Call(value, &ignored);
|
||||
}
|
||||
|
||||
void Console::RetrieveConsoleEvents(JSContext* aCx,
|
||||
|
@ -2850,7 +2856,8 @@ void Console::MaybeExecuteDumpFunctionForTime(JSContext* aCx,
|
|||
|
||||
void Console::ExecuteDumpFunction(const nsAString& aMessage) {
|
||||
if (mDumpFunction) {
|
||||
mDumpFunction->Call(aMessage);
|
||||
RefPtr<ConsoleInstanceDumpCallback> dumpFunction(mDumpFunction);
|
||||
dumpFunction->Call(aMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,67 +49,90 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
|
|||
uint64_t aInnerWindowID,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Log(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Info(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Warn(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Error(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Exception(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Debug(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Table(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Trace(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Dir(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Dirxml(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Group(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void GroupCollapsed(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void GroupEnd(const GlobalObject& aGlobal);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Time(const GlobalObject& aGlobal, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void TimeLog(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void TimeStamp(const GlobalObject& aGlobal,
|
||||
const JS::Handle<JS::Value> aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Profile(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void ProfileEnd(const GlobalObject& aGlobal,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Assert(const GlobalObject& aGlobal, bool aCondition,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Count(const GlobalObject& aGlobal, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void CountReset(const GlobalObject& aGlobal, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Clear(const GlobalObject& aGlobal);
|
||||
|
||||
static already_AddRefed<ConsoleInstance> CreateInstance(
|
||||
|
@ -162,27 +185,38 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
|
|||
static already_AddRefed<Console> GetConsoleInternal(
|
||||
const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void ProfileMethod(const GlobalObject& aGlobal, MethodName aName,
|
||||
const nsAString& aAction,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ProfileMethodInternal(JSContext* aCx, MethodName aName,
|
||||
const nsAString& aAction,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
// Implementation of the mainthread-only parts of ProfileMethod.
|
||||
// This is indepedent of console instance state.
|
||||
static void ProfileMethodMainthread(JSContext* aCx, const nsAString& aAction,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void Method(const GlobalObject& aGlobal, MethodName aName,
|
||||
const nsAString& aString,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void MethodInternal(JSContext* aCx, MethodName aName,
|
||||
const nsAString& aString,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData,
|
||||
MethodName aMethodName,
|
||||
const nsAString& aMethodString);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData,
|
||||
MethodName aMethodName,
|
||||
|
@ -200,6 +234,7 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
|
|||
void ReleaseCallData(ConsoleCallData* aCallData);
|
||||
|
||||
// aCx and aArguments must be in the same JS compartment.
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void NotifyHandler(JSContext* aCx, const Sequence<JS::Value>& aArguments,
|
||||
ConsoleCallData* aData);
|
||||
|
||||
|
@ -370,15 +405,18 @@ class Console final : public nsIObserver, public nsSupportsWeakReference {
|
|||
const Sequence<JS::Value>& aData,
|
||||
DOMHighResTimeStamp* aTimeStamp);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void MaybeExecuteDumpFunction(JSContext* aCx, const nsAString& aMethodName,
|
||||
const Sequence<JS::Value>& aData,
|
||||
nsIStackFrame* aStack);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void MaybeExecuteDumpFunctionForTime(JSContext* aCx, MethodName aMethodName,
|
||||
const nsAString& aMethodString,
|
||||
uint64_t aMonotonicTimer,
|
||||
const JS::Value& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ExecuteDumpFunction(const nsAString& aMessage);
|
||||
|
||||
bool IsEnabled(JSContext* aCx) const;
|
||||
|
|
|
@ -109,8 +109,9 @@ JSObject* ConsoleInstance::WrapObject(JSContext* aCx,
|
|||
#define METHOD(name, string) \
|
||||
void ConsoleInstance::name(JSContext* aCx, \
|
||||
const Sequence<JS::Value>& aData) { \
|
||||
mConsole->MethodInternal(aCx, Console::Method##name, \
|
||||
NS_LITERAL_STRING(string), aData); \
|
||||
RefPtr<Console> console(mConsole); \
|
||||
console->MethodInternal(aCx, Console::Method##name, \
|
||||
NS_LITERAL_STRING(string), aData); \
|
||||
}
|
||||
|
||||
METHOD(Log, "log")
|
||||
|
@ -130,26 +131,29 @@ METHOD(GroupCollapsed, "groupCollapsed")
|
|||
|
||||
void ConsoleInstance::GroupEnd(JSContext* aCx) {
|
||||
const Sequence<JS::Value> data;
|
||||
mConsole->MethodInternal(aCx, Console::MethodGroupEnd,
|
||||
NS_LITERAL_STRING("groupEnd"), data);
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->MethodInternal(aCx, Console::MethodGroupEnd,
|
||||
NS_LITERAL_STRING("groupEnd"), data);
|
||||
}
|
||||
|
||||
void ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel) {
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodTime,
|
||||
NS_LITERAL_STRING("time"));
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodTime, NS_LITERAL_STRING("time"));
|
||||
}
|
||||
|
||||
void ConsoleInstance::TimeLog(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData) {
|
||||
mConsole->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog,
|
||||
NS_LITERAL_STRING("timeLog"));
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->StringMethodInternal(aCx, aLabel, aData, Console::MethodTimeLog,
|
||||
NS_LITERAL_STRING("timeLog"));
|
||||
}
|
||||
|
||||
void ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel) {
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodTimeEnd,
|
||||
NS_LITERAL_STRING("timeEnd"));
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodTimeEnd,
|
||||
NS_LITERAL_STRING("timeEnd"));
|
||||
}
|
||||
|
||||
void ConsoleInstance::TimeStamp(JSContext* aCx,
|
||||
|
@ -163,46 +167,53 @@ void ConsoleInstance::TimeStamp(JSContext* aCx,
|
|||
return;
|
||||
}
|
||||
|
||||
mConsole->MethodInternal(aCx, Console::MethodTimeStamp,
|
||||
NS_LITERAL_STRING("timeStamp"), data);
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->MethodInternal(aCx, Console::MethodTimeStamp,
|
||||
NS_LITERAL_STRING("timeStamp"), data);
|
||||
}
|
||||
|
||||
void ConsoleInstance::Profile(JSContext* aCx,
|
||||
const Sequence<JS::Value>& aData) {
|
||||
mConsole->ProfileMethodInternal(aCx, Console::MethodProfile,
|
||||
NS_LITERAL_STRING("profile"), aData);
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->ProfileMethodInternal(aCx, Console::MethodProfile,
|
||||
NS_LITERAL_STRING("profile"), aData);
|
||||
}
|
||||
|
||||
void ConsoleInstance::ProfileEnd(JSContext* aCx,
|
||||
const Sequence<JS::Value>& aData) {
|
||||
mConsole->ProfileMethodInternal(aCx, Console::MethodProfileEnd,
|
||||
NS_LITERAL_STRING("profileEnd"), aData);
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->ProfileMethodInternal(aCx, Console::MethodProfileEnd,
|
||||
NS_LITERAL_STRING("profileEnd"), aData);
|
||||
}
|
||||
|
||||
void ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
|
||||
const Sequence<JS::Value>& aData) {
|
||||
if (!aCondition) {
|
||||
mConsole->MethodInternal(aCx, Console::MethodAssert,
|
||||
NS_LITERAL_STRING("assert"), aData);
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->MethodInternal(aCx, Console::MethodAssert,
|
||||
NS_LITERAL_STRING("assert"), aData);
|
||||
}
|
||||
}
|
||||
|
||||
void ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel) {
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodCount,
|
||||
NS_LITERAL_STRING("count"));
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodCount,
|
||||
NS_LITERAL_STRING("count"));
|
||||
}
|
||||
|
||||
void ConsoleInstance::CountReset(JSContext* aCx, const nsAString& aLabel) {
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodCountReset,
|
||||
NS_LITERAL_STRING("countReset"));
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->StringMethodInternal(aCx, aLabel, Sequence<JS::Value>(),
|
||||
Console::MethodCountReset,
|
||||
NS_LITERAL_STRING("countReset"));
|
||||
}
|
||||
|
||||
void ConsoleInstance::Clear(JSContext* aCx) {
|
||||
const Sequence<JS::Value> data;
|
||||
mConsole->MethodInternal(aCx, Console::MethodClear,
|
||||
NS_LITERAL_STRING("clear"), data);
|
||||
RefPtr<Console> console(mConsole);
|
||||
console->MethodInternal(aCx, Console::MethodClear, NS_LITERAL_STRING("clear"),
|
||||
data);
|
||||
}
|
||||
|
||||
void ConsoleInstance::ReportForServiceWorkerScope(const nsAString& aScope,
|
||||
|
|
|
@ -26,52 +26,75 @@ class ConsoleInstance final : public nsISupports, public nsWrapperCache {
|
|||
|
||||
nsPIDOMWindowInner* GetParentObject() const { return nullptr; }
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Log(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Info(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Warn(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Error(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Exception(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Debug(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Table(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Trace(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Dir(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Dirxml(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Group(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void GroupCollapsed(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void GroupEnd(JSContext* aCx);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Time(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void TimeLog(JSContext* aCx, const nsAString& aLabel,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void TimeEnd(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Assert(JSContext* aCx, bool aCondition,
|
||||
const Sequence<JS::Value>& aData);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Count(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void CountReset(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Clear(JSContext* aCx);
|
||||
|
||||
// For testing only.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "DataTransferItem.h"
|
||||
#include "DataTransferItemList.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ContentEvents.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
#include "mozilla/dom/DataTransferItemBinding.h"
|
||||
|
@ -430,15 +431,19 @@ void DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
|
|||
mCallback(aCallback),
|
||||
mStringData(aStringData) {}
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until runnables are opted into
|
||||
// MOZ_CAN_RUN_SCRIPT. See bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHOD Run() override {
|
||||
ErrorResult rv;
|
||||
mCallback->Call(mStringData, rv);
|
||||
// mCallback is const, so we never null it out until our destructor.
|
||||
MOZ_KnownLive(mCallback)->Call(mStringData, rv);
|
||||
NS_WARNING_ASSERTION(!rv.Failed(), "callback failed");
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<FunctionStringCallback> mCallback;
|
||||
const RefPtr<FunctionStringCallback> mCallback;
|
||||
nsString mStringData;
|
||||
};
|
||||
|
||||
|
|
|
@ -154,8 +154,8 @@ nsresult JSEventHandler::HandleEvent(Event* aEvent) {
|
|||
mTypedHandler.OnErrorEventHandler();
|
||||
ErrorResult rv;
|
||||
JS::Rooted<JS::Value> retval(RootingCx());
|
||||
handler->Call(mTarget, msgOrEvent, fileName, lineNumber, columnNumber,
|
||||
error, &retval, rv);
|
||||
handler->Call(target, msgOrEvent, fileName, lineNumber, columnNumber, error,
|
||||
&retval, rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ nsresult JSEventHandler::HandleEvent(Event* aEvent) {
|
|||
mTypedHandler.OnBeforeUnloadEventHandler();
|
||||
ErrorResult rv;
|
||||
nsString retval;
|
||||
handler->Call(mTarget, *aEvent, retval, rv);
|
||||
handler->Call(target, *aEvent, retval, rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ nsresult JSEventHandler::HandleEvent(Event* aEvent) {
|
|||
ErrorResult rv;
|
||||
RefPtr<EventHandlerNonNull> handler = mTypedHandler.NormalEventHandler();
|
||||
JS::Rooted<JS::Value> retval(RootingCx());
|
||||
handler->Call(mTarget, *aEvent, &retval, rv);
|
||||
handler->Call(target, *aEvent, &retval, rv);
|
||||
if (rv.Failed()) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
|
|
@ -33,7 +33,9 @@ EntryCallbackRunnable::EntryCallbackRunnable(FileSystemEntryCallback* aCallback,
|
|||
|
||||
NS_IMETHODIMP
|
||||
EntryCallbackRunnable::Run() {
|
||||
mCallback->Call(*mEntry);
|
||||
// Both of our strongly held members never change (they're const), so we can
|
||||
// use MOZ_KnownLive on them.
|
||||
MOZ_KnownLive(mCallback)->Call(MOZ_KnownLive(*mEntry));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -52,7 +54,8 @@ ErrorCallbackRunnable::ErrorCallbackRunnable(nsIGlobalObject* aGlobalObject,
|
|||
NS_IMETHODIMP
|
||||
ErrorCallbackRunnable::Run() {
|
||||
RefPtr<DOMException> exception = DOMException::Create(mError);
|
||||
mCallback->Call(*exception);
|
||||
// mCallback never changes (it's const) so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mCallback)->Call(*exception);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -65,7 +68,8 @@ EmptyEntriesCallbackRunnable::EmptyEntriesCallbackRunnable(
|
|||
NS_IMETHODIMP
|
||||
EmptyEntriesCallbackRunnable::Run() {
|
||||
Sequence<OwningNonNull<FileSystemEntry>> sequence;
|
||||
mCallback->Call(sequence);
|
||||
// mCallback never changes (it's const), so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mCallback)->Call(sequence);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -188,7 +192,8 @@ void GetEntryHelper::CompleteOperation(JSObject* aObj) {
|
|||
|
||||
RefPtr<FileSystemFileEntry> entry = new FileSystemFileEntry(
|
||||
mParentEntry->GetParentObject(), file, mParentEntry, mFileSystem);
|
||||
mSuccessCallback->Call(*entry);
|
||||
// mSuccessCallback never changes (it's const), so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mSuccessCallback)->Call(*entry);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -202,7 +207,8 @@ void GetEntryHelper::CompleteOperation(JSObject* aObj) {
|
|||
|
||||
RefPtr<FileSystemDirectoryEntry> entry = new FileSystemDirectoryEntry(
|
||||
mParentEntry->GetParentObject(), directory, mParentEntry, mFileSystem);
|
||||
mSuccessCallback->Call(*entry);
|
||||
// mSuccessCallback never changes (it's const), so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mSuccessCallback)->Call(*entry);
|
||||
}
|
||||
|
||||
void GetEntryHelper::ContinueRunning(JSObject* aObj) {
|
||||
|
|
|
@ -23,12 +23,13 @@ class EntryCallbackRunnable final : public Runnable {
|
|||
EntryCallbackRunnable(FileSystemEntryCallback* aCallback,
|
||||
FileSystemEntry* aEntry);
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override;
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override;
|
||||
|
||||
private:
|
||||
RefPtr<FileSystemEntryCallback> mCallback;
|
||||
RefPtr<FileSystemEntry> mEntry;
|
||||
const RefPtr<FileSystemEntryCallback> mCallback;
|
||||
const RefPtr<FileSystemEntry> mEntry;
|
||||
};
|
||||
|
||||
class ErrorCallbackRunnable final : public Runnable {
|
||||
|
@ -36,12 +37,13 @@ class ErrorCallbackRunnable final : public Runnable {
|
|||
ErrorCallbackRunnable(nsIGlobalObject* aGlobalObject,
|
||||
ErrorCallback* aCallback, nsresult aError);
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override;
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIGlobalObject> mGlobal;
|
||||
RefPtr<ErrorCallback> mCallback;
|
||||
const RefPtr<ErrorCallback> mCallback;
|
||||
nsresult mError;
|
||||
};
|
||||
|
||||
|
@ -49,11 +51,12 @@ class EmptyEntriesCallbackRunnable final : public Runnable {
|
|||
public:
|
||||
explicit EmptyEntriesCallbackRunnable(FileSystemEntriesCallback* aCallback);
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override;
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override;
|
||||
|
||||
private:
|
||||
RefPtr<FileSystemEntriesCallback> mCallback;
|
||||
const RefPtr<FileSystemEntriesCallback> mCallback;
|
||||
};
|
||||
|
||||
class GetEntryHelper final : public PromiseNativeHandler {
|
||||
|
@ -68,6 +71,7 @@ class GetEntryHelper final : public PromiseNativeHandler {
|
|||
|
||||
void Run();
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void ResolvedCallback(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) override;
|
||||
|
||||
|
@ -81,14 +85,14 @@ class GetEntryHelper final : public PromiseNativeHandler {
|
|||
|
||||
void ContinueRunning(JSObject* aObj);
|
||||
|
||||
void CompleteOperation(JSObject* aObj);
|
||||
MOZ_CAN_RUN_SCRIPT void CompleteOperation(JSObject* aObj);
|
||||
|
||||
RefPtr<FileSystemDirectoryEntry> mParentEntry;
|
||||
RefPtr<Directory> mDirectory;
|
||||
nsTArray<nsString> mParts;
|
||||
RefPtr<FileSystem> mFileSystem;
|
||||
|
||||
RefPtr<FileSystemEntryCallback> mSuccessCallback;
|
||||
const RefPtr<FileSystemEntryCallback> mSuccessCallback;
|
||||
RefPtr<ErrorCallback> mErrorCallback;
|
||||
|
||||
FileSystemDirectoryEntry::GetInternalType mType;
|
||||
|
|
|
@ -36,6 +36,7 @@ class PromiseHandler final : public PromiseNativeHandler {
|
|||
MOZ_ASSERT(aSuccessCallback);
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void ResolvedCallback(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) override {
|
||||
if (NS_WARN_IF(!aValue.isObject())) {
|
||||
|
@ -86,7 +87,8 @@ class PromiseHandler final : public PromiseNativeHandler {
|
|||
sequence[i] = entry;
|
||||
}
|
||||
|
||||
mSuccessCallback->Call(sequence);
|
||||
// mSuccessCallback never changes (it's const), so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mSuccessCallback)->Call(sequence);
|
||||
}
|
||||
|
||||
virtual void RejectedCallback(JSContext* aCx,
|
||||
|
@ -106,7 +108,7 @@ class PromiseHandler final : public PromiseNativeHandler {
|
|||
|
||||
RefPtr<FileSystemDirectoryEntry> mParentEntry;
|
||||
RefPtr<FileSystem> mFileSystem;
|
||||
RefPtr<FileSystemEntriesCallback> mSuccessCallback;
|
||||
const RefPtr<FileSystemEntriesCallback> mSuccessCallback;
|
||||
RefPtr<ErrorCallback> mErrorCallback;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,19 +24,21 @@ class FileCallbackRunnable final : public Runnable {
|
|||
MOZ_ASSERT(aFile);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override {
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
|
||||
// Here we clone the File object.
|
||||
|
||||
RefPtr<File> file = File::Create(mFile->GetParentObject(), mFile->Impl());
|
||||
MOZ_ASSERT(file);
|
||||
|
||||
mCallback->Call(*file);
|
||||
// mCallback never changes (it's const) so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mCallback)->Call(*file);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<FileCallback> mCallback;
|
||||
const RefPtr<FileCallback> mCallback;
|
||||
RefPtr<File> mFile;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,8 +24,9 @@ class EntriesCallbackRunnable final : public Runnable {
|
|||
MOZ_ASSERT(aCallback);
|
||||
}
|
||||
|
||||
NS_IMETHOD
|
||||
Run() override {
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHOD Run() override {
|
||||
Sequence<OwningNonNull<FileSystemEntry>> entries;
|
||||
for (uint32_t i = 0; i < mEntries.Length(); ++i) {
|
||||
if (!entries.AppendElement(mEntries[i].forget(), fallible)) {
|
||||
|
@ -33,12 +34,13 @@ class EntriesCallbackRunnable final : public Runnable {
|
|||
}
|
||||
}
|
||||
|
||||
mCallback->Call(entries);
|
||||
// mCallback never changes (it's const), so MOZ_KnownLive is ok.
|
||||
MOZ_KnownLive(mCallback)->Call(entries);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<FileSystemEntriesCallback> mCallback;
|
||||
const RefPtr<FileSystemEntriesCallback> mCallback;
|
||||
Sequence<RefPtr<FileSystemEntry>> mEntries;
|
||||
};
|
||||
|
||||
|
|
|
@ -492,9 +492,11 @@ nsresult HTMLCanvasElement::DispatchPrintCallback(nsITimerCallback* aCallback) {
|
|||
return OwnerDoc()->Dispatch(TaskCategory::Other, renderEvent.forget());
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void HTMLCanvasElement::CallPrintCallback() {
|
||||
ErrorResult rv;
|
||||
GetMozPrintCallback()->Call(*mPrintState, rv);
|
||||
RefPtr<PrintCallback> callback = GetMozPrintCallback();
|
||||
RefPtr<HTMLCanvasPrintState> state = mPrintState;
|
||||
callback->Call(*state);
|
||||
}
|
||||
|
||||
void HTMLCanvasElement::ResetPrintCallback() {
|
||||
|
|
|
@ -3009,7 +3009,7 @@ ContentParent::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
// We know prefs are ASCII here.
|
||||
NS_LossyConvertUTF16toASCII strData(aData);
|
||||
|
||||
Pref pref(strData, /* isLocked */ false, null_t(), null_t());
|
||||
Pref pref(strData, /* isLocked */ false, Nothing(), Nothing());
|
||||
Preferences::GetPreference(&pref);
|
||||
if (IsAlive()) {
|
||||
MOZ_ASSERT(mQueuedPrefs.IsEmpty());
|
||||
|
|
|
@ -112,12 +112,6 @@ struct WebProgressData
|
|||
uint64_t DOMWindowID;
|
||||
};
|
||||
|
||||
union OptionalWebProgressData
|
||||
{
|
||||
void_t;
|
||||
WebProgressData;
|
||||
};
|
||||
|
||||
struct RequestData
|
||||
{
|
||||
nsIURI requestURI;
|
||||
|
@ -125,12 +119,6 @@ struct RequestData
|
|||
nsCString matchedList;
|
||||
};
|
||||
|
||||
union OptionalShmem
|
||||
{
|
||||
void_t;
|
||||
Shmem;
|
||||
};
|
||||
|
||||
nested(upto inside_cpow) sync protocol PBrowser
|
||||
{
|
||||
manager PContent;
|
||||
|
@ -550,7 +538,7 @@ parent:
|
|||
async RegisterProtocolHandler(nsString scheme, nsIURI handlerURI, nsString title,
|
||||
nsIURI documentURI);
|
||||
|
||||
async OnContentBlockingEvent(OptionalWebProgressData aWebProgressData,
|
||||
async OnContentBlockingEvent(WebProgressData? aWebProgressData,
|
||||
RequestData aRequestData, uint32_t aEvent);
|
||||
|
||||
child:
|
||||
|
@ -594,7 +582,7 @@ parent:
|
|||
nested(inside_sync) sync DispatchKeyboardEvent(WidgetKeyboardEvent event);
|
||||
|
||||
async InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action,
|
||||
OptionalShmem visualData,
|
||||
Shmem? visualData,
|
||||
uint32_t stride, SurfaceFormat format,
|
||||
LayoutDeviceIntRect dragRect,
|
||||
Principal principal);
|
||||
|
|
|
@ -14,11 +14,6 @@ union PrefValue {
|
|||
bool;
|
||||
};
|
||||
|
||||
union MaybePrefValue {
|
||||
PrefValue;
|
||||
null_t;
|
||||
};
|
||||
|
||||
// This serialization form mirrors that used in mozilla::Pref in
|
||||
// Preferences.cpp. The two should be kept in sync, e.g. if something is added
|
||||
// to one it should also be added to the other.
|
||||
|
@ -28,8 +23,8 @@ union MaybePrefValue {
|
|||
struct Pref {
|
||||
nsCString name;
|
||||
bool isLocked;
|
||||
MaybePrefValue defaultValue;
|
||||
MaybePrefValue userValue;
|
||||
PrefValue? defaultValue;
|
||||
PrefValue? userValue;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -3311,11 +3311,13 @@ NS_IMETHODIMP TabChild::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
|
|||
nsresult rv = PrepareProgressListenerData(aWebProgress, aRequest,
|
||||
webProgressData, requestData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
Maybe<WebProgressData> maybeWebProgressData;
|
||||
if (aWebProgress) {
|
||||
Unused << SendOnContentBlockingEvent(webProgressData, requestData, aEvent);
|
||||
} else {
|
||||
Unused << SendOnContentBlockingEvent(void_t(), requestData, aEvent);
|
||||
maybeWebProgressData.emplace(webProgressData);
|
||||
}
|
||||
Unused << SendOnContentBlockingEvent(maybeWebProgressData, requestData,
|
||||
aEvent);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -2210,26 +2210,24 @@ mozilla::ipc::IPCResult TabParent::RecvRegisterProtocolHandler(
|
|||
}
|
||||
|
||||
mozilla::ipc::IPCResult TabParent::RecvOnContentBlockingEvent(
|
||||
const OptionalWebProgressData& aWebProgressData,
|
||||
const Maybe<WebProgressData>& aWebProgressData,
|
||||
const RequestData& aRequestData, const uint32_t& aEvent) {
|
||||
nsCOMPtr<nsIBrowser> browser =
|
||||
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
|
||||
if (browser) {
|
||||
MOZ_ASSERT(aWebProgressData.type() != OptionalWebProgressData::T__None);
|
||||
|
||||
if (aWebProgressData.type() == OptionalWebProgressData::Tvoid_t) {
|
||||
if (aWebProgressData.isNothing()) {
|
||||
Unused << browser->CallWebProgressContentBlockingEventListeners(
|
||||
false, false, false, 0, 0, aRequestData.requestURI(),
|
||||
aRequestData.originalRequestURI(), aRequestData.matchedList(),
|
||||
aEvent);
|
||||
} else {
|
||||
Unused << browser->CallWebProgressContentBlockingEventListeners(
|
||||
true, aWebProgressData.get_WebProgressData().isTopLevel(),
|
||||
aWebProgressData.get_WebProgressData().isLoadingDocument(),
|
||||
aWebProgressData.get_WebProgressData().loadType(),
|
||||
aWebProgressData.get_WebProgressData().DOMWindowID(),
|
||||
aRequestData.requestURI(), aRequestData.originalRequestURI(),
|
||||
aRequestData.matchedList(), aEvent);
|
||||
true, aWebProgressData.ref().isTopLevel(),
|
||||
aWebProgressData.ref().isLoadingDocument(),
|
||||
aWebProgressData.ref().loadType(),
|
||||
aWebProgressData.ref().DOMWindowID(), aRequestData.requestURI(),
|
||||
aRequestData.originalRequestURI(), aRequestData.matchedList(),
|
||||
aEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3301,7 +3299,7 @@ mozilla::ipc::IPCResult TabParent::RecvAsyncAuthPrompt(
|
|||
|
||||
mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
|
||||
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction,
|
||||
const OptionalShmem& aVisualDnDData, const uint32_t& aStride,
|
||||
Maybe<Shmem>&& aVisualDnDData, const uint32_t& aStride,
|
||||
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
|
||||
const IPC::Principal& aPrincipal) {
|
||||
mInitialDataTransferItems.Clear();
|
||||
|
@ -3326,14 +3324,13 @@ mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
|
|||
dragService->MaybeAddChildProcess(Manager());
|
||||
}
|
||||
|
||||
if (aVisualDnDData.type() == OptionalShmem::Tvoid_t ||
|
||||
!aVisualDnDData.get_Shmem().IsReadable() ||
|
||||
aVisualDnDData.get_Shmem().Size<char>() < aDragRect.height * aStride) {
|
||||
if (aVisualDnDData.isNothing() || !aVisualDnDData.ref().IsReadable() ||
|
||||
aVisualDnDData.ref().Size<char>() < aDragRect.height * aStride) {
|
||||
mDnDVisualization = nullptr;
|
||||
} else {
|
||||
mDnDVisualization = gfx::CreateDataSourceSurfaceFromData(
|
||||
gfx::IntSize(aDragRect.width, aDragRect.height), aFormat,
|
||||
aVisualDnDData.get_Shmem().get<uint8_t>(), aStride);
|
||||
aVisualDnDData.ref().get<uint8_t>(), aStride);
|
||||
}
|
||||
|
||||
mDragValid = true;
|
||||
|
@ -3342,8 +3339,8 @@ mozilla::ipc::IPCResult TabParent::RecvInvokeDragSession(
|
|||
|
||||
esm->BeginTrackingRemoteDragGesture(mFrameElement);
|
||||
|
||||
if (aVisualDnDData.type() == OptionalShmem::TShmem) {
|
||||
Unused << DeallocShmem(aVisualDnDData);
|
||||
if (aVisualDnDData.isSome()) {
|
||||
Unused << DeallocShmem(aVisualDnDData.ref());
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
|
|
|
@ -166,7 +166,7 @@ class TabParent final : public PBrowserParent,
|
|||
nsIURI* aDocURI);
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnContentBlockingEvent(
|
||||
const OptionalWebProgressData& aWebProgressData,
|
||||
const Maybe<WebProgressData>& aWebProgressData,
|
||||
const RequestData& aRequestData, const uint32_t& aEvent);
|
||||
|
||||
mozilla::ipc::IPCResult RecvBrowserFrameOpenWindow(
|
||||
|
@ -572,7 +572,7 @@ class TabParent final : public PBrowserParent,
|
|||
|
||||
mozilla::ipc::IPCResult RecvInvokeDragSession(
|
||||
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction,
|
||||
const OptionalShmem& aVisualDnDData, const uint32_t& aStride,
|
||||
Maybe<Shmem>&& aVisualDnDData, const uint32_t& aStride,
|
||||
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
|
||||
const IPC::Principal& aPrincipal);
|
||||
|
||||
|
|
|
@ -121,115 +121,6 @@ std::map<MediaDecoderOwnerID, GPUProcessCrashTelemetryLogger::GPUCrashData>
|
|||
GPUProcessCrashTelemetryLogger::sGPUCrashDataMap;
|
||||
StaticMutex GPUProcessCrashTelemetryLogger::sGPUCrashMapMutex;
|
||||
|
||||
/**
|
||||
* This class addresses the concern of bug 1339310 comment 4 where the Widevine
|
||||
* CDM doesn't support running multiple instances of a video decoder at once per
|
||||
* CDM instance by sequencing the order of decoder creation and shutdown. Note
|
||||
* this class addresses a different concern from that of GlobalAllocPolicy which
|
||||
* controls a system-wide number of decoders while this class control a per-MFR
|
||||
* number (which is one per CDM requirement).
|
||||
*/
|
||||
class LocalAllocPolicy {
|
||||
using TrackType = TrackInfo::TrackType;
|
||||
using Promise = GlobalAllocPolicy::Promise;
|
||||
using Token = GlobalAllocPolicy::Token;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(LocalAllocPolicy)
|
||||
|
||||
public:
|
||||
LocalAllocPolicy(TrackType aTrack, TaskQueue* aOwnerThread)
|
||||
: mTrack(aTrack), mOwnerThread(aOwnerThread) {}
|
||||
|
||||
// Acquire a token for decoder creation. Note the resolved token will
|
||||
// aggregate a GlobalAllocPolicy token to comply to its policy. Note
|
||||
// this function shouldn't be called again until the returned promise
|
||||
// is resolved or rejected.
|
||||
RefPtr<Promise> Alloc();
|
||||
|
||||
// Cancel the request to GlobalAllocPolicy and reject the current token
|
||||
// request. Note this must happen before mOwnerThread->BeginShutdown().
|
||||
void Cancel();
|
||||
|
||||
private:
|
||||
/*
|
||||
* An RAII class to manage LocalAllocPolicy::mDecoderLimit.
|
||||
*/
|
||||
class AutoDeallocToken : public Token {
|
||||
public:
|
||||
explicit AutoDeallocToken(LocalAllocPolicy* aOwner) : mOwner(aOwner) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mOwner->mDecoderLimit > 0);
|
||||
--mOwner->mDecoderLimit;
|
||||
}
|
||||
// Aggregate a GlobalAllocPolicy token to present a single instance of
|
||||
// Token to the client so the client doesn't have to deal with
|
||||
// GlobalAllocPolicy and LocalAllocPolicy separately.
|
||||
void Append(Token* aToken) { mToken = aToken; }
|
||||
|
||||
private:
|
||||
// Release tokens allocated from GlobalAllocPolicy and LocalAllocPolicy
|
||||
// and process next token request if any.
|
||||
~AutoDeallocToken() {
|
||||
mToken = nullptr; // Dealloc the global token.
|
||||
++mOwner->mDecoderLimit; // Dealloc the local token.
|
||||
mOwner->ProcessRequest(); // Process next pending request.
|
||||
}
|
||||
RefPtr<LocalAllocPolicy> mOwner;
|
||||
RefPtr<Token> mToken;
|
||||
};
|
||||
|
||||
~LocalAllocPolicy() {}
|
||||
void ProcessRequest();
|
||||
|
||||
int mDecoderLimit = 1;
|
||||
const TrackType mTrack;
|
||||
RefPtr<TaskQueue> mOwnerThread;
|
||||
MozPromiseHolder<Promise> mPendingPromise;
|
||||
MozPromiseRequestHolder<Promise> mTokenRequest;
|
||||
};
|
||||
|
||||
RefPtr<LocalAllocPolicy::Promise> LocalAllocPolicy::Alloc() {
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mPendingPromise.IsEmpty());
|
||||
RefPtr<Promise> p = mPendingPromise.Ensure(__func__);
|
||||
if (mDecoderLimit > 0) {
|
||||
ProcessRequest();
|
||||
}
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void LocalAllocPolicy::ProcessRequest() {
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
MOZ_DIAGNOSTIC_ASSERT(mDecoderLimit > 0);
|
||||
|
||||
// No pending request.
|
||||
if (mPendingPromise.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<AutoDeallocToken> token = new AutoDeallocToken(this);
|
||||
RefPtr<LocalAllocPolicy> self = this;
|
||||
|
||||
GlobalAllocPolicy::Instance(mTrack)
|
||||
.Alloc()
|
||||
->Then(mOwnerThread, __func__,
|
||||
[self, token](RefPtr<Token> aToken) {
|
||||
self->mTokenRequest.Complete();
|
||||
token->Append(aToken);
|
||||
self->mPendingPromise.Resolve(token, __func__);
|
||||
},
|
||||
[self, token]() {
|
||||
self->mTokenRequest.Complete();
|
||||
self->mPendingPromise.Reject(true, __func__);
|
||||
})
|
||||
->Track(mTokenRequest);
|
||||
}
|
||||
|
||||
void LocalAllocPolicy::Cancel() {
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
mPendingPromise.RejectIfExists(true, __func__);
|
||||
mTokenRequest.DisconnectIfExists();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class tracks shutdown promises to ensure all decoders are shut down
|
||||
* completely before MFR continues the rest of the shutdown procedure.
|
||||
|
@ -371,8 +262,8 @@ void MediaFormatReader::DecoderData::Flush() {
|
|||
|
||||
class MediaFormatReader::DecoderFactory {
|
||||
using InitPromise = MediaDataDecoder::InitPromise;
|
||||
using TokenPromise = GlobalAllocPolicy::Promise;
|
||||
using Token = GlobalAllocPolicy::Token;
|
||||
using TokenPromise = AllocPolicy::Promise;
|
||||
using Token = AllocPolicy::Token;
|
||||
|
||||
public:
|
||||
explicit DecoderFactory(MediaFormatReader* aOwner)
|
||||
|
@ -415,10 +306,10 @@ class MediaFormatReader::DecoderFactory {
|
|||
Data(DecoderData& aOwnerData, TrackType aTrack, TaskQueue* aThread)
|
||||
: mOwnerData(aOwnerData),
|
||||
mTrack(aTrack),
|
||||
mPolicy(new LocalAllocPolicy(aTrack, aThread)) {}
|
||||
mPolicy(new SingleAllocPolicy(aTrack, aThread)) {}
|
||||
DecoderData& mOwnerData;
|
||||
const TrackType mTrack;
|
||||
RefPtr<LocalAllocPolicy> mPolicy;
|
||||
RefPtr<SingleAllocPolicy> mPolicy;
|
||||
Stage mStage = Stage::None;
|
||||
RefPtr<Token> mToken;
|
||||
RefPtr<MediaDataDecoder> mDecoder;
|
||||
|
|
|
@ -301,26 +301,14 @@ static uint16_t FromCaptureState(CaptureState aState) {
|
|||
return static_cast<uint16_t>(aState);
|
||||
}
|
||||
|
||||
void MediaManager::CallOnError(
|
||||
const MediaManager::GetUserMediaErrorCallback* aCallback,
|
||||
MediaStreamError& aError) {
|
||||
MOZ_ASSERT(aCallback);
|
||||
if (aCallback->HasWebIDLCallback()) {
|
||||
aCallback->GetWebIDLCallback()->Call(aError);
|
||||
} else {
|
||||
aCallback->GetXPCOMCallback()->OnError(&aError);
|
||||
}
|
||||
void MediaManager::CallOnError(GetUserMediaErrorCallback& aCallback,
|
||||
MediaStreamError& aError) {
|
||||
aCallback.Call(aError);
|
||||
}
|
||||
|
||||
void MediaManager::CallOnSuccess(
|
||||
const MediaManager::GetUserMediaSuccessCallback* aCallback,
|
||||
DOMMediaStream& aStream) {
|
||||
MOZ_ASSERT(aCallback);
|
||||
if (aCallback->HasWebIDLCallback()) {
|
||||
aCallback->GetWebIDLCallback()->Call(aStream);
|
||||
} else {
|
||||
aCallback->GetXPCOMCallback()->OnSuccess(&aStream);
|
||||
}
|
||||
void MediaManager::CallOnSuccess(GetUserMediaSuccessCallback& aCallback,
|
||||
DOMMediaStream& aStream) {
|
||||
aCallback.Call(aStream);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -199,16 +199,14 @@ class MediaManager final : public nsIMediaManagerService,
|
|||
void RemoveFromWindowList(uint64_t aWindowID,
|
||||
GetUserMediaWindowListener* aListener);
|
||||
|
||||
typedef dom::CallbackObjectHolder<dom::NavigatorUserMediaSuccessCallback,
|
||||
nsIDOMGetUserMediaSuccessCallback>
|
||||
GetUserMediaSuccessCallback;
|
||||
typedef dom::CallbackObjectHolder<dom::NavigatorUserMediaErrorCallback,
|
||||
nsIDOMGetUserMediaErrorCallback>
|
||||
GetUserMediaErrorCallback;
|
||||
typedef dom::NavigatorUserMediaSuccessCallback GetUserMediaSuccessCallback;
|
||||
typedef dom::NavigatorUserMediaErrorCallback GetUserMediaErrorCallback;
|
||||
|
||||
static void CallOnError(const GetUserMediaErrorCallback* aCallback,
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void CallOnError(GetUserMediaErrorCallback& aCallback,
|
||||
dom::MediaStreamError& aError);
|
||||
static void CallOnSuccess(const GetUserMediaSuccessCallback* aCallback,
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static void CallOnSuccess(GetUserMediaSuccessCallback& aCallback,
|
||||
DOMMediaStream& aStream);
|
||||
|
||||
typedef nsTArray<RefPtr<MediaDevice>> MediaDeviceSet;
|
||||
|
@ -227,6 +225,7 @@ class MediaManager final : public nsIMediaManagerService,
|
|||
const dom::MediaStreamConstraints& aConstraints,
|
||||
dom::CallerType aCallerType);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
nsresult GetUserMediaDevices(
|
||||
nsPIDOMWindowInner* aWindow,
|
||||
const dom::MediaStreamConstraints& aConstraints,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "MediaRecorder.h"
|
||||
#include "PDMFactory.h"
|
||||
#include "VPXDecoder.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "mozilla/TaskQueue.h"
|
||||
|
@ -243,81 +244,98 @@ already_AddRefed<Promise> MediaCapabilities::DecodingInfo(
|
|||
*config, taskQueue, compositor,
|
||||
CreateDecoderParams::VideoFrameRate(frameRate),
|
||||
TrackInfo::kVideoTrack};
|
||||
return AllocationWrapper::CreateDecoder(params)->Then(
|
||||
taskQueue, __func__,
|
||||
[taskQueue, frameRate, config = std::move(config)](
|
||||
AllocationWrapper::AllocateDecoderPromise::
|
||||
ResolveOrRejectValue&& aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
return CapabilitiesPromise::CreateAndReject(
|
||||
std::move(aValue.RejectValue()), __func__);
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder =
|
||||
std::move(aValue.ResolveValue());
|
||||
// We now query the decoder to determine if it's power
|
||||
// efficient.
|
||||
RefPtr<CapabilitiesPromise> p = decoder->Init()->Then(
|
||||
taskQueue, __func__,
|
||||
[taskQueue, decoder, frameRate, config = std::move(config)](
|
||||
MediaDataDecoder::InitPromise::ResolveOrRejectValue&&
|
||||
aValue) mutable {
|
||||
RefPtr<CapabilitiesPromise> p;
|
||||
if (aValue.IsReject()) {
|
||||
p = CapabilitiesPromise::CreateAndReject(
|
||||
std::move(aValue.RejectValue()), __func__);
|
||||
} else {
|
||||
MOZ_ASSERT(config->IsVideo());
|
||||
nsAutoCString reason;
|
||||
bool powerEfficient = true;
|
||||
bool smooth = true;
|
||||
if (config->GetAsVideoInfo()->mImage.height > 480) {
|
||||
// Assume that we can do stuff at 480p or less in a
|
||||
// power efficient manner and smoothly. If greater
|
||||
// than 480p we assume that if the video decoding is
|
||||
// hardware accelerated it will be smooth and power
|
||||
// efficient, otherwise we use the benchmark to
|
||||
// estimate
|
||||
powerEfficient =
|
||||
decoder->IsHardwareAccelerated(reason);
|
||||
if (!powerEfficient &&
|
||||
VPXDecoder::IsVP9(config->mMimeType)) {
|
||||
smooth = VP9Benchmark::IsVP9DecodeFast(
|
||||
true /* default */);
|
||||
uint32_t fps = VP9Benchmark::MediaBenchmarkVp9Fps();
|
||||
if (!smooth && fps > 0) {
|
||||
// The VP9 estimizer decode a 1280x720 video.
|
||||
// Let's adjust the result for the resolution and
|
||||
// frame rate of what we actually want. If the
|
||||
// result is twice that we need we assume it will
|
||||
// be smooth.
|
||||
const auto& videoConfig =
|
||||
*config->GetAsVideoInfo();
|
||||
double needed = ((1280.0 * 720.0) /
|
||||
(videoConfig.mImage.width *
|
||||
videoConfig.mImage.height) *
|
||||
fps) /
|
||||
frameRate;
|
||||
smooth = needed > 2;
|
||||
// We want to ensure that all decoder's queries are occurring only
|
||||
// once at a time as it can quickly exhaust the system resources
|
||||
// otherwise.
|
||||
static RefPtr<AllocPolicy> sVideoAllocPolicy = [&taskQueue]() {
|
||||
SystemGroup::Dispatch(
|
||||
TaskCategory::Other,
|
||||
NS_NewRunnableFunction(
|
||||
"MediaCapabilities::AllocPolicy:Video", []() {
|
||||
ClearOnShutdown(&sVideoAllocPolicy,
|
||||
ShutdownPhase::ShutdownThreads);
|
||||
}));
|
||||
return new SingleAllocPolicy(TrackInfo::TrackType::kVideoTrack,
|
||||
taskQueue);
|
||||
}();
|
||||
return AllocationWrapper::CreateDecoder(params, sVideoAllocPolicy)
|
||||
->Then(
|
||||
taskQueue, __func__,
|
||||
[taskQueue, frameRate, config = std::move(config)](
|
||||
AllocationWrapper::AllocateDecoderPromise::
|
||||
ResolveOrRejectValue&& aValue) mutable {
|
||||
if (aValue.IsReject()) {
|
||||
return CapabilitiesPromise::CreateAndReject(
|
||||
std::move(aValue.RejectValue()), __func__);
|
||||
}
|
||||
RefPtr<MediaDataDecoder> decoder =
|
||||
std::move(aValue.ResolveValue());
|
||||
// We now query the decoder to determine if it's power
|
||||
// efficient.
|
||||
RefPtr<CapabilitiesPromise> p = decoder->Init()->Then(
|
||||
taskQueue, __func__,
|
||||
[taskQueue, decoder, frameRate,
|
||||
config = std::move(config)](
|
||||
MediaDataDecoder::InitPromise::
|
||||
ResolveOrRejectValue&& aValue) mutable {
|
||||
RefPtr<CapabilitiesPromise> p;
|
||||
if (aValue.IsReject()) {
|
||||
p = CapabilitiesPromise::CreateAndReject(
|
||||
std::move(aValue.RejectValue()), __func__);
|
||||
} else {
|
||||
MOZ_ASSERT(config->IsVideo());
|
||||
nsAutoCString reason;
|
||||
bool powerEfficient = true;
|
||||
bool smooth = true;
|
||||
if (config->GetAsVideoInfo()->mImage.height > 480) {
|
||||
// Assume that we can do stuff at 480p or less in
|
||||
// a power efficient manner and smoothly. If
|
||||
// greater than 480p we assume that if the video
|
||||
// decoding is hardware accelerated it will be
|
||||
// smooth and power efficient, otherwise we use
|
||||
// the benchmark to estimate
|
||||
powerEfficient =
|
||||
decoder->IsHardwareAccelerated(reason);
|
||||
if (!powerEfficient &&
|
||||
VPXDecoder::IsVP9(config->mMimeType)) {
|
||||
smooth = VP9Benchmark::IsVP9DecodeFast(
|
||||
true /* default */);
|
||||
uint32_t fps =
|
||||
VP9Benchmark::MediaBenchmarkVp9Fps();
|
||||
if (!smooth && fps > 0) {
|
||||
// The VP9 estimizer decode a 1280x720 video.
|
||||
// Let's adjust the result for the resolution
|
||||
// and frame rate of what we actually want. If
|
||||
// the result is twice that we need we assume
|
||||
// it will be smooth.
|
||||
const auto& videoConfig =
|
||||
*config->GetAsVideoInfo();
|
||||
double needed = ((1280.0 * 720.0) /
|
||||
(videoConfig.mImage.width *
|
||||
videoConfig.mImage.height) *
|
||||
fps) /
|
||||
frameRate;
|
||||
smooth = needed > 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
p = CapabilitiesPromise::CreateAndResolve(
|
||||
MediaCapabilitiesInfo(true /* supported */,
|
||||
smooth, powerEfficient),
|
||||
__func__);
|
||||
}
|
||||
}
|
||||
p = CapabilitiesPromise::CreateAndResolve(
|
||||
MediaCapabilitiesInfo(true /* supported */, smooth,
|
||||
powerEfficient),
|
||||
__func__);
|
||||
}
|
||||
MOZ_ASSERT(p.get(), "the promise has been created");
|
||||
// Let's keep alive the decoder and the config object
|
||||
// until the decoder has shutdown.
|
||||
decoder->Shutdown()->Then(
|
||||
taskQueue, __func__,
|
||||
[taskQueue, decoder, config = std::move(config)](
|
||||
const ShutdownPromise::ResolveOrRejectValue&
|
||||
aValue) {});
|
||||
return p;
|
||||
});
|
||||
return p;
|
||||
});
|
||||
MOZ_ASSERT(p.get(), "the promise has been created");
|
||||
// Let's keep alive the decoder and the config object
|
||||
// until the decoder has shutdown.
|
||||
decoder->Shutdown()->Then(
|
||||
taskQueue, __func__,
|
||||
[taskQueue, decoder, config = std::move(config)](
|
||||
const ShutdownPromise::ResolveOrRejectValue&
|
||||
aValue) {});
|
||||
return p;
|
||||
});
|
||||
return p;
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,10 @@
|
|||
|
||||
#include "VideoSink.h"
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
# include "ProfileJSONWriter.h"
|
||||
# include "ProfilerMarkerPayload.h"
|
||||
#endif
|
||||
#include "MediaQueue.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
|
@ -31,6 +34,42 @@ extern LazyLogModule gMediaDecoderLog;
|
|||
#define VSINK_LOG_V(x, ...) \
|
||||
MOZ_LOG(gMediaDecoderLog, LogLevel::Verbose, (FMT(x, ##__VA_ARGS__)))
|
||||
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
# define VSINK_ADD_PROFILER_MARKER(tag, markerTime, aTime, vTime) \
|
||||
do { \
|
||||
if (profiler_thread_is_being_profiled()) { \
|
||||
profiler_add_marker( \
|
||||
tag, JS::ProfilingCategoryPair::GRAPHICS, \
|
||||
MakeUnique<VideoFrameMarkerPayload>(markerTime, aTime, vTime)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
class VideoFrameMarkerPayload : public ProfilerMarkerPayload {
|
||||
public:
|
||||
explicit VideoFrameMarkerPayload(mozilla::TimeStamp aMarkerTime,
|
||||
int64_t aAudioPositionUs,
|
||||
int64_t aVideoFrameTimeUs)
|
||||
: ProfilerMarkerPayload(aMarkerTime, aMarkerTime),
|
||||
mAudioPositionUs(aAudioPositionUs),
|
||||
mVideoFrameTimeUs(aVideoFrameTimeUs) {}
|
||||
|
||||
void StreamPayload(SpliceableJSONWriter& aWriter,
|
||||
const TimeStamp& aProcessStartTime,
|
||||
UniqueStacks& aUniqueStacks) {
|
||||
StreamCommonProps("UpdateRenderVideoFrames", aWriter, aProcessStartTime,
|
||||
aUniqueStacks);
|
||||
aWriter.IntProperty("audio", mAudioPositionUs);
|
||||
aWriter.IntProperty("video", mVideoFrameTimeUs);
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t mAudioPositionUs;
|
||||
int64_t mVideoFrameTimeUs;
|
||||
};
|
||||
#else
|
||||
# define VSINK_ADD_PROFILER_MARKER(tag, markerTime, aTime, vTime)
|
||||
#endif
|
||||
|
||||
using namespace mozilla::layers;
|
||||
|
||||
// Minimum update frequency is 1/120th of a second, i.e. half the
|
||||
|
@ -411,7 +450,7 @@ void VideoSink::RenderVideoFrames(int32_t aMaxFrames, int64_t aClockTime,
|
|||
MediaSink::PlaybackParams params = mAudioSink->GetPlaybackParams();
|
||||
for (uint32_t i = 0; i < frames.Length(); ++i) {
|
||||
VideoData* frame = frames[i];
|
||||
|
||||
bool wasSent = frame->IsSentToCompositor();
|
||||
frame->MarkSentToCompositor();
|
||||
|
||||
if (!frame->mImage || !frame->mImage->IsValid() ||
|
||||
|
@ -452,6 +491,10 @@ void VideoSink::RenderVideoFrames(int32_t aMaxFrames, int64_t aClockTime,
|
|||
VSINK_LOG_V("playing video frame %" PRId64 " (id=%x) (vq-queued=%zu)",
|
||||
frame->mTime.ToMicroseconds(), frame->mFrameID,
|
||||
VideoQueue().GetSize());
|
||||
if (!wasSent) {
|
||||
VSINK_ADD_PROFILER_MARKER("VideoSink: play", aClockTimeStamp, aClockTime,
|
||||
frame->mTime.ToMicroseconds());
|
||||
}
|
||||
}
|
||||
|
||||
if (images.Length() > 0) {
|
||||
|
@ -488,13 +531,12 @@ void VideoSink::UpdateRenderedVideoFrames() {
|
|||
VSINK_LOG_V("discarding video frame mTime=%" PRId64
|
||||
" clock_time=%" PRId64,
|
||||
frame->mTime.ToMicroseconds(), clockTime.ToMicroseconds());
|
||||
VSINK_ADD_PROFILER_MARKER("VideoSink: discard", nowTime,
|
||||
clockTime.ToMicroseconds(),
|
||||
frame->mTime.ToMicroseconds());
|
||||
}
|
||||
}
|
||||
|
||||
if (droppedCount > 0) {
|
||||
PROFILER_ADD_MARKER("DroppedUncompositedVideoFrames", GRAPHICS);
|
||||
}
|
||||
|
||||
if (droppedCount || sentToCompositorCount) {
|
||||
uint32_t totalCompositorDroppedCount = mContainer->GetDroppedImageCount();
|
||||
uint32_t compositorDroppedCount =
|
||||
|
|
|
@ -16,25 +16,3 @@ interface nsIMediaDevice : nsISupports
|
|||
readonly attribute AString groupId;
|
||||
readonly attribute boolean scary;
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(24544878-d35e-4962-8c5f-fb84e97bdfee)]
|
||||
interface nsIGetUserMediaDevicesSuccessCallback : nsISupports
|
||||
{
|
||||
void onSuccess(in nsIVariant devices);
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(f2a144fc-3534-4761-8c5d-989ae720f89a)]
|
||||
interface nsIDOMGetUserMediaSuccessCallback : nsISupports
|
||||
{
|
||||
/*
|
||||
* value must be a Blob if picture is true and a
|
||||
* DOMMediaStream if either audio or video are true.
|
||||
*/
|
||||
void onSuccess(in nsISupports value);
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(39e96c61-2636-4f0e-918e-9bb64276492a)]
|
||||
interface nsIDOMGetUserMediaErrorCallback : nsISupports
|
||||
{
|
||||
void onError(in nsISupports error);
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#include "AllocationPolicy.h"
|
||||
|
||||
#include "PDMFactory.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "PDMFactory.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/SystemGroup.h"
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
@ -18,18 +18,62 @@ namespace mozilla {
|
|||
|
||||
using TrackType = TrackInfo::TrackType;
|
||||
|
||||
StaticMutex GlobalAllocPolicy::sMutex;
|
||||
|
||||
class GlobalAllocPolicy::AutoDeallocToken : public Token {
|
||||
class AllocPolicyImpl::AutoDeallocToken : public Token {
|
||||
public:
|
||||
explicit AutoDeallocToken(GlobalAllocPolicy& aPolicy) : mPolicy(aPolicy) {}
|
||||
explicit AutoDeallocToken(const RefPtr<AllocPolicyImpl>& aPolicy)
|
||||
: mPolicy(aPolicy) {}
|
||||
|
||||
private:
|
||||
~AutoDeallocToken() { mPolicy.Dealloc(); }
|
||||
~AutoDeallocToken() { mPolicy->Dealloc(); }
|
||||
|
||||
GlobalAllocPolicy& mPolicy; // reference to a singleton object.
|
||||
RefPtr<AllocPolicyImpl> mPolicy;
|
||||
};
|
||||
|
||||
AllocPolicyImpl::AllocPolicyImpl(int aDecoderLimit)
|
||||
: mMaxDecoderLimit(aDecoderLimit),
|
||||
mMonitor("AllocPolicyImpl"),
|
||||
mDecoderLimit(aDecoderLimit) {}
|
||||
AllocPolicyImpl::~AllocPolicyImpl() { RejectAll(); }
|
||||
|
||||
auto AllocPolicyImpl::Alloc() -> RefPtr<Promise> {
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
// No decoder limit set.
|
||||
if (mDecoderLimit < 0) {
|
||||
return Promise::CreateAndResolve(new Token(), __func__);
|
||||
}
|
||||
|
||||
RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
|
||||
mPromises.push(p);
|
||||
ResolvePromise(mon);
|
||||
return p.forget();
|
||||
}
|
||||
|
||||
void AllocPolicyImpl::Dealloc() {
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
++mDecoderLimit;
|
||||
ResolvePromise(mon);
|
||||
}
|
||||
|
||||
void AllocPolicyImpl::ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock) {
|
||||
MOZ_ASSERT(mDecoderLimit >= 0);
|
||||
|
||||
if (mDecoderLimit > 0 && !mPromises.empty()) {
|
||||
--mDecoderLimit;
|
||||
RefPtr<PromisePrivate> p = mPromises.front().forget();
|
||||
mPromises.pop();
|
||||
p->Resolve(new AutoDeallocToken(this), __func__);
|
||||
}
|
||||
}
|
||||
|
||||
void AllocPolicyImpl::RejectAll() {
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
while (!mPromises.empty()) {
|
||||
RefPtr<PromisePrivate> p = mPromises.front().forget();
|
||||
mPromises.pop();
|
||||
p->Reject(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t MediaDecoderLimitDefault() {
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (jni::GetAPIVersion() < 18) {
|
||||
|
@ -42,68 +86,90 @@ static int32_t MediaDecoderLimitDefault() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
GlobalAllocPolicy::GlobalAllocPolicy()
|
||||
: mMonitor("DecoderAllocPolicy::mMonitor"),
|
||||
mDecoderLimit(MediaDecoderLimitDefault()) {
|
||||
SystemGroup::Dispatch(
|
||||
TaskCategory::Other,
|
||||
NS_NewRunnableFunction("GlobalAllocPolicy::GlobalAllocPolicy", [this]() {
|
||||
ClearOnShutdown(this, ShutdownPhase::ShutdownThreads);
|
||||
}));
|
||||
}
|
||||
StaticMutex GlobalAllocPolicy::sMutex;
|
||||
|
||||
GlobalAllocPolicy::~GlobalAllocPolicy() {
|
||||
while (!mPromises.empty()) {
|
||||
RefPtr<PromisePrivate> p = mPromises.front().forget();
|
||||
mPromises.pop();
|
||||
p->Reject(true, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
GlobalAllocPolicy& GlobalAllocPolicy::Instance(TrackType aTrack) {
|
||||
NotNull<AllocPolicy*> GlobalAllocPolicy::Instance(TrackType aTrack) {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (aTrack == TrackType::kAudioTrack) {
|
||||
static auto sAudioPolicy = new GlobalAllocPolicy();
|
||||
return *sAudioPolicy;
|
||||
} else {
|
||||
static auto sVideoPolicy = new GlobalAllocPolicy();
|
||||
return *sVideoPolicy;
|
||||
static RefPtr<AllocPolicyImpl> sAudioPolicy = []() {
|
||||
SystemGroup::Dispatch(
|
||||
TaskCategory::Other,
|
||||
NS_NewRunnableFunction(
|
||||
"GlobalAllocPolicy::GlobalAllocPolicy:Audio", []() {
|
||||
ClearOnShutdown(&sAudioPolicy, ShutdownPhase::ShutdownThreads);
|
||||
}));
|
||||
return new AllocPolicyImpl(MediaDecoderLimitDefault());
|
||||
}();
|
||||
return WrapNotNull(sAudioPolicy.get());
|
||||
}
|
||||
static RefPtr<AllocPolicyImpl> sVideoPolicy = []() {
|
||||
SystemGroup::Dispatch(
|
||||
TaskCategory::Other,
|
||||
NS_NewRunnableFunction(
|
||||
"GlobalAllocPolicy::GlobalAllocPolicy:Audio", []() {
|
||||
ClearOnShutdown(&sVideoPolicy, ShutdownPhase::ShutdownThreads);
|
||||
}));
|
||||
return new AllocPolicyImpl(MediaDecoderLimitDefault());
|
||||
}();
|
||||
return WrapNotNull(sVideoPolicy.get());
|
||||
}
|
||||
|
||||
auto GlobalAllocPolicy::Alloc() -> RefPtr<Promise> {
|
||||
// No decoder limit set.
|
||||
if (mDecoderLimit < 0) {
|
||||
return Promise::CreateAndResolve(new Token(), __func__);
|
||||
}
|
||||
class SingleAllocPolicy::AutoDeallocCombinedToken : public Token {
|
||||
public:
|
||||
AutoDeallocCombinedToken(already_AddRefed<Token> aSingleAllocPolicyToken,
|
||||
already_AddRefed<Token> aGlobalAllocPolicyToken)
|
||||
: mSingleToken(aSingleAllocPolicyToken),
|
||||
mGlobalToken(aGlobalAllocPolicyToken) {}
|
||||
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
RefPtr<PromisePrivate> p = new PromisePrivate(__func__);
|
||||
mPromises.push(p);
|
||||
ResolvePromise(mon);
|
||||
return p.forget();
|
||||
private:
|
||||
// Release tokens allocated from GlobalAllocPolicy and LocalAllocPolicy
|
||||
// and process next token request if any.
|
||||
~AutoDeallocCombinedToken() = default;
|
||||
const RefPtr<Token> mSingleToken;
|
||||
const RefPtr<Token> mGlobalToken;
|
||||
};
|
||||
|
||||
auto SingleAllocPolicy::Alloc() -> RefPtr<Promise> {
|
||||
MOZ_DIAGNOSTIC_ASSERT(MaxDecoderLimit() == 1,
|
||||
"We can only handle at most one token out at a time.");
|
||||
RefPtr<SingleAllocPolicy> self = this;
|
||||
return AllocPolicyImpl::Alloc()->Then(
|
||||
mOwnerThread, __func__,
|
||||
[self](RefPtr<Token> aToken) {
|
||||
RefPtr<Token> localToken = aToken.forget();
|
||||
RefPtr<Promise> p = self->mPendingPromise.Ensure(__func__);
|
||||
GlobalAllocPolicy::Instance(self->mTrack)
|
||||
->Alloc()
|
||||
->Then(self->mOwnerThread, __func__,
|
||||
[self, localToken = std::move(localToken)](
|
||||
RefPtr<Token> aToken) mutable {
|
||||
self->mTokenRequest.Complete();
|
||||
RefPtr<Token> combinedToken = new AutoDeallocCombinedToken(
|
||||
localToken.forget(), aToken.forget());
|
||||
self->mPendingPromise.Resolve(combinedToken, __func__);
|
||||
},
|
||||
[self]() {
|
||||
self->mTokenRequest.Complete();
|
||||
self->mPendingPromise.Reject(true, __func__);
|
||||
})
|
||||
->Track(self->mTokenRequest);
|
||||
return p;
|
||||
},
|
||||
[]() { return Promise::CreateAndReject(true, __func__); });
|
||||
}
|
||||
|
||||
void GlobalAllocPolicy::Dealloc() {
|
||||
ReentrantMonitorAutoEnter mon(mMonitor);
|
||||
++mDecoderLimit;
|
||||
ResolvePromise(mon);
|
||||
SingleAllocPolicy::~SingleAllocPolicy() {
|
||||
mPendingPromise.RejectIfExists(true, __func__);
|
||||
mTokenRequest.DisconnectIfExists();
|
||||
}
|
||||
|
||||
void GlobalAllocPolicy::ResolvePromise(
|
||||
ReentrantMonitorAutoEnter& aProofOfLock) {
|
||||
MOZ_ASSERT(mDecoderLimit >= 0);
|
||||
|
||||
if (mDecoderLimit > 0 && !mPromises.empty()) {
|
||||
--mDecoderLimit;
|
||||
RefPtr<PromisePrivate> p = mPromises.front().forget();
|
||||
mPromises.pop();
|
||||
p->Resolve(new AutoDeallocToken(*this), __func__);
|
||||
}
|
||||
void SingleAllocPolicy::Cancel() {
|
||||
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
||||
mPendingPromise.RejectIfExists(true, __func__);
|
||||
mTokenRequest.DisconnectIfExists();
|
||||
RejectAll();
|
||||
}
|
||||
|
||||
void GlobalAllocPolicy::operator=(std::nullptr_t) { delete this; }
|
||||
|
||||
AllocationWrapper::AllocationWrapper(
|
||||
already_AddRefed<MediaDataDecoder> aDecoder, already_AddRefed<Token> aToken)
|
||||
: mDecoder(aDecoder), mToken(aToken) {
|
||||
|
@ -125,7 +191,8 @@ RefPtr<ShutdownPromise> AllocationWrapper::Shutdown() {
|
|||
[token]() { return ShutdownPromise::CreateAndResolve(true, __func__); });
|
||||
}
|
||||
/* static */ RefPtr<AllocationWrapper::AllocateDecoderPromise>
|
||||
AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams) {
|
||||
AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams,
|
||||
AllocPolicy* aPolicy) {
|
||||
// aParams.mConfig is guaranteed to stay alive during the lifetime of the
|
||||
// MediaDataDecoder, so keeping a pointer to the object is safe.
|
||||
const TrackInfo* config = &aParams.mConfig;
|
||||
|
@ -143,8 +210,8 @@ AllocationWrapper::CreateDecoder(const CreateDecoderParams& aParams) {
|
|||
CreateDecoderParams::VideoFrameRate rate = aParams.mRate;
|
||||
|
||||
RefPtr<AllocateDecoderPromise> p =
|
||||
GlobalAllocPolicy::Instance(aParams.mType)
|
||||
.Alloc()
|
||||
(aPolicy ? aPolicy : GlobalAllocPolicy::Instance(aParams.mType))
|
||||
->Alloc()
|
||||
->Then(AbstractThread::GetCurrent(), __func__,
|
||||
[=](RefPtr<Token> aToken) {
|
||||
// result may not always be updated by
|
||||
|
|
|
@ -7,56 +7,84 @@
|
|||
#ifndef AllocationPolicy_h_
|
||||
#define AllocationPolicy_h_
|
||||
|
||||
#include <queue>
|
||||
#include "MediaInfo.h"
|
||||
#include "PlatformDecoderModule.h"
|
||||
#include "TimeUnits.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/ReentrantMonitor.h"
|
||||
#include <queue>
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/**
|
||||
* This is a singleton which controls the number of decoders that can be
|
||||
* created concurrently. Before calling PDMFactory::CreateDecoder(), Alloc()
|
||||
* must be called to get a token object as a permission to create a decoder.
|
||||
* The token should stay alive until Shutdown() is called on the decoder.
|
||||
* The destructor of the token will restore the decoder count so it is available
|
||||
* Before calling PDMFactory::CreateDecoder(), Alloc() must be called on the
|
||||
* policy to get a token object as a permission to create a decoder. The
|
||||
* token should stay alive until Shutdown() is called on the decoder. The
|
||||
* destructor of the token will restore the decoder count so it is available
|
||||
* for next calls of Alloc().
|
||||
*/
|
||||
class GlobalAllocPolicy {
|
||||
class AllocPolicy {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AllocPolicy)
|
||||
|
||||
public:
|
||||
class Token {
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Token)
|
||||
protected:
|
||||
virtual ~Token() {}
|
||||
virtual ~Token() = default;
|
||||
};
|
||||
|
||||
using Promise = MozPromise<RefPtr<Token>, bool, true>;
|
||||
|
||||
// Acquire a token for decoder creation. Thread-safe.
|
||||
RefPtr<Promise> Alloc();
|
||||
virtual RefPtr<Promise> Alloc() = 0;
|
||||
|
||||
// Called by ClearOnShutdown() to delete the singleton.
|
||||
void operator=(decltype(nullptr));
|
||||
protected:
|
||||
virtual ~AllocPolicy() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* This is a singleton which controls the number of decoders that can be created
|
||||
* concurrently.
|
||||
* Instance() will return the TrackType global AllocPolicy.
|
||||
* Instance() will always return a non-null value.
|
||||
*/
|
||||
class GlobalAllocPolicy {
|
||||
public:
|
||||
// Get the singleton for the given track type. Thread-safe.
|
||||
static GlobalAllocPolicy& Instance(TrackInfo::TrackType aTrack);
|
||||
static NotNull<AllocPolicy*> Instance(TrackInfo::TrackType aTrack);
|
||||
|
||||
private:
|
||||
// Protect access to Instance().
|
||||
static StaticMutex sMutex;
|
||||
};
|
||||
|
||||
/** This the actual base implementation underneath all AllocPolicy objects and
|
||||
* control how many decoders can be created concurrently.
|
||||
* Alloc() must be called to get a token object as a permission to perform an
|
||||
* action. The token should stay alive until Shutdown() is called on the
|
||||
* decoder. The destructor of the token will restore the decoder count so it is
|
||||
* available for next calls of Alloc().
|
||||
**/
|
||||
class AllocPolicyImpl : public AllocPolicy {
|
||||
public:
|
||||
explicit AllocPolicyImpl(int aDecoderLimit);
|
||||
RefPtr<Promise> Alloc() override;
|
||||
|
||||
protected:
|
||||
virtual ~AllocPolicyImpl();
|
||||
void RejectAll();
|
||||
int MaxDecoderLimit() const { return mMaxDecoderLimit; }
|
||||
|
||||
private:
|
||||
class AutoDeallocToken;
|
||||
using PromisePrivate = Promise::Private;
|
||||
GlobalAllocPolicy();
|
||||
~GlobalAllocPolicy();
|
||||
// Called by the destructor of TokenImpl to restore the decoder limit.
|
||||
void Dealloc();
|
||||
// Decrement the decoder limit and resolve a promise if available.
|
||||
void ResolvePromise(ReentrantMonitorAutoEnter& aProofOfLock);
|
||||
|
||||
// Protect access to Instance().
|
||||
static StaticMutex sMutex;
|
||||
|
||||
const int mMaxDecoderLimit;
|
||||
ReentrantMonitor mMonitor;
|
||||
// The number of decoders available for creation.
|
||||
int mDecoderLimit;
|
||||
|
@ -64,8 +92,35 @@ class GlobalAllocPolicy {
|
|||
std::queue<RefPtr<PromisePrivate>> mPromises;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class allows to track and serialise a single decoder allocation at a
|
||||
* time
|
||||
*/
|
||||
class SingleAllocPolicy : public AllocPolicyImpl {
|
||||
using TrackType = TrackInfo::TrackType;
|
||||
|
||||
public:
|
||||
SingleAllocPolicy(TrackType aTrack, TaskQueue* aOwnerThread)
|
||||
: AllocPolicyImpl(1), mTrack(aTrack), mOwnerThread(aOwnerThread) {}
|
||||
|
||||
RefPtr<Promise> Alloc() override;
|
||||
|
||||
// Cancel the request to GlobalAllocPolicy and reject the current token
|
||||
// request. Note this must happen before mOwnerThread->BeginShutdown().
|
||||
void Cancel();
|
||||
|
||||
private:
|
||||
class AutoDeallocCombinedToken;
|
||||
virtual ~SingleAllocPolicy();
|
||||
|
||||
const TrackType mTrack;
|
||||
RefPtr<TaskQueue> mOwnerThread;
|
||||
MozPromiseHolder<Promise> mPendingPromise;
|
||||
MozPromiseRequestHolder<Promise> mTokenRequest;
|
||||
};
|
||||
|
||||
class AllocationWrapper : public MediaDataDecoder {
|
||||
using Token = GlobalAllocPolicy::Token;
|
||||
using Token = AllocPolicy::Token;
|
||||
|
||||
public:
|
||||
AllocationWrapper(already_AddRefed<MediaDataDecoder> aDecoder,
|
||||
|
@ -96,11 +151,11 @@ class AllocationWrapper : public MediaDataDecoder {
|
|||
/* IsExclusive = */ true>
|
||||
AllocateDecoderPromise;
|
||||
// Will create a decoder has soon as one can be created according to the
|
||||
// GlobalAllocPolicy.
|
||||
// AllocPolicy (or GlobalAllocPolicy if aPolicy is null)
|
||||
// Warning: all aParams members must be valid until the promise has been
|
||||
// resolved, as some contains raw pointers to objects.
|
||||
static RefPtr<AllocateDecoderPromise> CreateDecoder(
|
||||
const CreateDecoderParams& aParams);
|
||||
const CreateDecoderParams& aParams, AllocPolicy* aPolicy = nullptr);
|
||||
|
||||
private:
|
||||
RefPtr<MediaDataDecoder> mDecoder;
|
||||
|
|
|
@ -85,6 +85,9 @@ class MediaDecodeTask final : public Runnable {
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until Runnable::Run is MOZ_CAN_RUN_SCRIPT. See
|
||||
// bug 1535398.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHOD Run() override;
|
||||
bool CreateReader();
|
||||
MediaFormatReader* Reader() {
|
||||
|
@ -93,6 +96,7 @@ class MediaDecodeTask final : public Runnable {
|
|||
}
|
||||
|
||||
private:
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ReportFailureOnMainThread(WebAudioDecodeJob::ErrorCode aErrorCode) {
|
||||
if (NS_IsMainThread()) {
|
||||
Cleanup();
|
||||
|
@ -109,14 +113,14 @@ class MediaDecodeTask final : public Runnable {
|
|||
}
|
||||
|
||||
void Decode();
|
||||
void OnMetadataRead(MetadataHolder&& aMetadata);
|
||||
void OnMetadataNotRead(const MediaResult& aError);
|
||||
MOZ_CAN_RUN_SCRIPT void OnMetadataRead(MetadataHolder&& aMetadata);
|
||||
MOZ_CAN_RUN_SCRIPT void OnMetadataNotRead(const MediaResult& aError);
|
||||
void RequestSample();
|
||||
void SampleDecoded(RefPtr<AudioData> aData);
|
||||
void SampleNotDecoded(const MediaResult& aError);
|
||||
void FinishDecode();
|
||||
void AllocateBuffer();
|
||||
void CallbackTheResult();
|
||||
MOZ_CAN_RUN_SCRIPT void SampleNotDecoded(const MediaResult& aError);
|
||||
MOZ_CAN_RUN_SCRIPT void FinishDecode();
|
||||
MOZ_CAN_RUN_SCRIPT void AllocateBuffer();
|
||||
MOZ_CAN_RUN_SCRIPT void CallbackTheResult();
|
||||
|
||||
void Cleanup() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -486,14 +490,14 @@ void WebAudioDecodeJob::OnSuccess(ErrorCode aErrorCode) {
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aErrorCode == NoError);
|
||||
|
||||
RefPtr<AudioBuffer> output(mOutput);
|
||||
if (mSuccessCallback) {
|
||||
ErrorResult rv;
|
||||
mSuccessCallback->Call(*mOutput, rv);
|
||||
RefPtr<DecodeSuccessCallback> callback(mSuccessCallback);
|
||||
// Ignore errors in calling the callback, since there is not much that we
|
||||
// can do about it here.
|
||||
rv.SuppressException();
|
||||
callback->Call(*output);
|
||||
}
|
||||
mPromise->MaybeResolve(mOutput);
|
||||
mPromise->MaybeResolve(output);
|
||||
|
||||
mContext->RemoveFromDecodeQueue(this);
|
||||
}
|
||||
|
@ -537,7 +541,8 @@ void WebAudioDecodeJob::OnFailure(ErrorCode aErrorCode) {
|
|||
nsAutoCString errorString(errorMessage);
|
||||
RefPtr<DOMException> exception = DOMException::Create(
|
||||
NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR, errorString);
|
||||
mFailureCallback->Call(*exception);
|
||||
RefPtr<DecodeErrorCallback> callback(mFailureCallback);
|
||||
callback->Call(*exception);
|
||||
}
|
||||
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
||||
|
@ -45,8 +46,8 @@ struct WebAudioDecodeJob final {
|
|||
|
||||
typedef void (WebAudioDecodeJob::*ResultFn)(ErrorCode);
|
||||
|
||||
void OnSuccess(ErrorCode /* ignored */);
|
||||
void OnFailure(ErrorCode aErrorCode);
|
||||
MOZ_CAN_RUN_SCRIPT void OnSuccess(ErrorCode /* ignored */);
|
||||
MOZ_CAN_RUN_SCRIPT void OnFailure(ErrorCode aErrorCode);
|
||||
|
||||
bool AllocateBuffer();
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ already_AddRefed<Promise> RTCIdentityProviderRegistrar::GenerateAssertion(
|
|||
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
|
||||
return nullptr;
|
||||
}
|
||||
return mGenerateAssertionCallback->Call(aContents, aOrigin, aOptions, aRv);
|
||||
RefPtr<GenerateAssertionCallback> callback(mGenerateAssertionCallback);
|
||||
return callback->Call(aContents, aOrigin, aOptions, aRv);
|
||||
}
|
||||
already_AddRefed<Promise> RTCIdentityProviderRegistrar::ValidateAssertion(
|
||||
const nsAString& aAssertion, const nsAString& aOrigin, ErrorResult& aRv) {
|
||||
|
@ -63,7 +64,8 @@ already_AddRefed<Promise> RTCIdentityProviderRegistrar::ValidateAssertion(
|
|||
aRv.Throw(NS_ERROR_NOT_INITIALIZED);
|
||||
return nullptr;
|
||||
}
|
||||
return mValidateAssertionCallback->Call(aAssertion, aOrigin, aRv);
|
||||
RefPtr<ValidateAssertionCallback> callback(mValidateAssertionCallback);
|
||||
return callback->Call(aAssertion, aOrigin, aRv);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -38,9 +38,11 @@ class RTCIdentityProviderRegistrar final : public nsISupports,
|
|||
void Register(const RTCIdentityProvider& aIdp);
|
||||
bool HasIdp() const;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
already_AddRefed<Promise> GenerateAssertion(
|
||||
const nsAString& aContents, const nsAString& aOrigin,
|
||||
const RTCIdentityProviderOptions& aOptions, ErrorResult& aRv);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
already_AddRefed<Promise> ValidateAssertion(const nsAString& assertion,
|
||||
const nsAString& origin,
|
||||
ErrorResult& aRv);
|
||||
|
|
|
@ -231,7 +231,7 @@ class NotificationPermissionRequest : public ContentPermissionRequestBase,
|
|||
protected:
|
||||
~NotificationPermissionRequest() = default;
|
||||
|
||||
nsresult ResolvePromise();
|
||||
MOZ_CAN_RUN_SCRIPT nsresult ResolvePromise();
|
||||
nsresult DispatchResolvePromise();
|
||||
NotificationPermission mPermission;
|
||||
RefPtr<Promise> mPromise;
|
||||
|
@ -575,7 +575,8 @@ nsresult NotificationPermissionRequest::ResolvePromise() {
|
|||
}
|
||||
if (mCallback) {
|
||||
ErrorResult error;
|
||||
mCallback->Call(mPermission, error);
|
||||
RefPtr<NotificationPermissionCallback> callback(mCallback);
|
||||
callback->Call(mPermission, error);
|
||||
rv = error.StealNSResult();
|
||||
}
|
||||
mPromise->MaybeResolve(mPermission);
|
||||
|
|
|
@ -424,9 +424,13 @@ class NotifyObserversTask final : public CancelableRunnable {
|
|||
MOZ_ASSERT(mPerformance);
|
||||
}
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY for now until Runnable::Run is
|
||||
// MOZ_CAN_RUN_SCRIPT.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
NS_IMETHOD Run() override {
|
||||
MOZ_ASSERT(mPerformance);
|
||||
mPerformance->NotifyObservers();
|
||||
RefPtr<Performance> performance(mPerformance);
|
||||
performance->NotifyObservers();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ class Performance : public DOMEventTargetHelper {
|
|||
|
||||
void AddObserver(PerformanceObserver* aObserver);
|
||||
void RemoveObserver(PerformanceObserver* aObserver);
|
||||
void NotifyObservers();
|
||||
MOZ_CAN_RUN_SCRIPT void NotifyObservers();
|
||||
void CancelNotificationObservers();
|
||||
|
||||
virtual PerformanceTiming* Timing() = 0;
|
||||
|
|
|
@ -106,7 +106,8 @@ void PerformanceObserver::Notify() {
|
|||
mQueuedEntries.Clear();
|
||||
|
||||
ErrorResult rv;
|
||||
mCallback->Call(this, *list, *this, rv);
|
||||
RefPtr<PerformanceObserverCallback> callback(mCallback);
|
||||
callback->Call(this, *list, *this, rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ class PerformanceObserver final : public nsISupports, public nsWrapperCache {
|
|||
|
||||
void TakeRecords(nsTArray<RefPtr<PerformanceEntry>>& aRetval);
|
||||
|
||||
void Notify();
|
||||
MOZ_CAN_RUN_SCRIPT void Notify();
|
||||
void QueueEntry(PerformanceEntry* aEntry);
|
||||
|
||||
private:
|
||||
|
|
|
@ -55,11 +55,6 @@ union SurfaceDescriptor {
|
|||
null_t;
|
||||
};
|
||||
|
||||
union OptionalShmem {
|
||||
Shmem;
|
||||
null_t;
|
||||
};
|
||||
|
||||
intr protocol PPluginInstance
|
||||
{
|
||||
manager PPluginModule;
|
||||
|
|
|
@ -316,6 +316,7 @@ void Promise::MaybeReject(JSContext* aCx, JS::Handle<JS::Value> aValue) {
|
|||
|
||||
enum class NativeHandlerTask : int32_t { Resolve, Reject };
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
static bool NativeHandlerCallback(JSContext* aCx, unsigned aArgc,
|
||||
JS::Value* aVp) {
|
||||
JS::CallArgs args = CallArgsFromVp(aArgc, aVp);
|
||||
|
@ -334,10 +335,12 @@ static bool NativeHandlerCallback(JSContext* aCx, unsigned aArgc,
|
|||
NativeHandlerTask task = static_cast<NativeHandlerTask>(v.toInt32());
|
||||
|
||||
if (task == NativeHandlerTask::Resolve) {
|
||||
handler->ResolvedCallback(aCx, args.get(0));
|
||||
// handler is kept alive by "obj" on the stack.
|
||||
MOZ_KnownLive(handler)->ResolvedCallback(aCx, args.get(0));
|
||||
} else {
|
||||
MOZ_ASSERT(task == NativeHandlerTask::Reject);
|
||||
handler->RejectedCallback(aCx, args.get(0));
|
||||
// handler is kept alive by "obj" on the stack.
|
||||
MOZ_KnownLive(handler)->RejectedCallback(aCx, args.get(0));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -377,14 +380,18 @@ class PromiseNativeHandlerShim final : public PromiseNativeHandler {
|
|||
MOZ_ASSERT(mInner);
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
|
||||
mInner->ResolvedCallback(aCx, aValue);
|
||||
mInner = nullptr;
|
||||
RefPtr<PromiseNativeHandler> inner = mInner.forget();
|
||||
inner->ResolvedCallback(aCx, aValue);
|
||||
MOZ_ASSERT(!mInner);
|
||||
}
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override {
|
||||
mInner->RejectedCallback(aCx, aValue);
|
||||
mInner = nullptr;
|
||||
RefPtr<PromiseNativeHandler> inner = mInner.forget();
|
||||
inner->RejectedCallback(aCx, aValue);
|
||||
MOZ_ASSERT(!mInner);
|
||||
}
|
||||
|
||||
bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
|
||||
|
|
|
@ -23,9 +23,11 @@ class PromiseNativeHandler : public nsISupports {
|
|||
virtual ~PromiseNativeHandler() {}
|
||||
|
||||
public:
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void ResolvedCallback(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) = 0;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void RejectedCallback(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aValue) = 0;
|
||||
};
|
||||
|
|
|
@ -138,7 +138,11 @@ void ReportingObserver::MaybeReport(Report* aReport) {
|
|||
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
"ReportingObserver::MaybeReport",
|
||||
[window]() { window->NotifyReportingObservers(); });
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until at least we're able to have
|
||||
// Runnable::Run be MOZ_CAN_RUN_SCRIPT. But even then, having a boundary
|
||||
// here might make the most sense.
|
||||
[window]()
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY { window->NotifyReportingObservers(); });
|
||||
|
||||
NS_DispatchToCurrentThread(r);
|
||||
}
|
||||
|
@ -160,7 +164,8 @@ void ReportingObserver::MaybeNotify() {
|
|||
}
|
||||
|
||||
// We should report if this throws exception. But where?
|
||||
mCallback->Call(reports, *this);
|
||||
RefPtr<ReportingObserverCallback> callback(mCallback);
|
||||
callback->Call(reports, *this);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -54,7 +54,7 @@ class ReportingObserver final : public nsIObserver,
|
|||
|
||||
void MaybeReport(Report* aReport);
|
||||
|
||||
void MaybeNotify();
|
||||
MOZ_CAN_RUN_SCRIPT void MaybeNotify();
|
||||
|
||||
private:
|
||||
~ReportingObserver();
|
||||
|
|
|
@ -91,6 +91,7 @@ class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
|
|||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Register(const nsAString& aAppId,
|
||||
const Sequence<RegisterRequest>& aRegisterRequests,
|
||||
const Sequence<RegisteredKey>& aRegisteredKeys,
|
||||
|
@ -98,6 +99,7 @@ class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
|
|||
const Optional<Nullable<int32_t>>& opt_aTimeoutSeconds,
|
||||
ErrorResult& aRv);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void Sign(const nsAString& aAppId, const nsAString& aChallenge,
|
||||
const Sequence<RegisteredKey>& aRegisteredKeys,
|
||||
U2FSignCallback& aCallback,
|
||||
|
@ -106,31 +108,35 @@ class U2F final : public WebAuthnManagerBase, public nsWrapperCache {
|
|||
|
||||
// WebAuthnManagerBase
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void FinishMakeCredential(
|
||||
const uint64_t& aTransactionId,
|
||||
const WebAuthnMakeCredentialResult& aResult) override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void FinishGetAssertion(const uint64_t& aTransactionId,
|
||||
const WebAuthnGetAssertionResult& aResult) override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void RequestAborted(const uint64_t& aTransactionId,
|
||||
const nsresult& aError) override;
|
||||
|
||||
protected:
|
||||
// Cancels the current transaction (by sending a Cancel message to the
|
||||
// parent) and rejects it by calling RejectTransaction().
|
||||
void CancelTransaction(const nsresult& aError) override;
|
||||
MOZ_CAN_RUN_SCRIPT void CancelTransaction(const nsresult& aError) override;
|
||||
|
||||
private:
|
||||
~U2F();
|
||||
MOZ_CAN_RUN_SCRIPT ~U2F();
|
||||
|
||||
template <typename T, typename C>
|
||||
void ExecuteCallback(T& aResp, nsMainThreadPtrHandle<C>& aCb);
|
||||
MOZ_CAN_RUN_SCRIPT void ExecuteCallback(T& aResp,
|
||||
nsMainThreadPtrHandle<C>& aCb);
|
||||
|
||||
// Clears all information we have about the current transaction.
|
||||
void ClearTransaction();
|
||||
// Rejects the current transaction and clears it.
|
||||
void RejectTransaction(const nsresult& aError);
|
||||
MOZ_CAN_RUN_SCRIPT void RejectTransaction(const nsresult& aError);
|
||||
|
||||
nsString mOrigin;
|
||||
|
||||
|
|
|
@ -30,24 +30,27 @@ class WebAuthnManagerBase : public nsIDOMEventListener {
|
|||
|
||||
explicit WebAuthnManagerBase(nsPIDOMWindowInner* aParent);
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void FinishMakeCredential(
|
||||
const uint64_t& aTransactionId,
|
||||
const WebAuthnMakeCredentialResult& aResult) = 0;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void FinishGetAssertion(
|
||||
const uint64_t& aTransactionId,
|
||||
const WebAuthnGetAssertionResult& aResult) = 0;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
virtual void RequestAborted(const uint64_t& aTransactionId,
|
||||
const nsresult& aError) = 0;
|
||||
|
||||
void ActorDestroyed();
|
||||
|
||||
protected:
|
||||
virtual ~WebAuthnManagerBase();
|
||||
MOZ_CAN_RUN_SCRIPT virtual ~WebAuthnManagerBase();
|
||||
|
||||
// Needed by HandleEvent() to cancel transactions.
|
||||
virtual void CancelTransaction(const nsresult& aError) = 0;
|
||||
MOZ_CAN_RUN_SCRIPT virtual void CancelTransaction(const nsresult& aError) = 0;
|
||||
|
||||
// Visibility event handling.
|
||||
void ListenForVisibilityEvents();
|
||||
|
|
|
@ -25,14 +25,23 @@ class WebAuthnTransactionChild final : public PWebAuthnTransactionChild {
|
|||
NS_INLINE_DECL_REFCOUNTING(WebAuthnTransactionChild);
|
||||
explicit WebAuthnTransactionChild(WebAuthnManagerBase* aManager);
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until we can do MOZ_CAN_RUN_SCRIPT in
|
||||
// IPDL-generated things.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
mozilla::ipc::IPCResult RecvConfirmRegister(
|
||||
const uint64_t& aTransactionId,
|
||||
const WebAuthnMakeCredentialResult& aResult);
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until we can do MOZ_CAN_RUN_SCRIPT in
|
||||
// IPDL-generated things.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
mozilla::ipc::IPCResult RecvConfirmSign(
|
||||
const uint64_t& aTransactionId,
|
||||
const WebAuthnGetAssertionResult& aResult);
|
||||
|
||||
// MOZ_CAN_RUN_SCRIPT_BOUNDARY until we can do MOZ_CAN_RUN_SCRIPT in
|
||||
// IPDL-generated things.
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
mozilla::ipc::IPCResult RecvAbort(const uint64_t& aTransactionId,
|
||||
const nsresult& aError);
|
||||
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
* liability, trademark and document use rules apply.
|
||||
*/
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback DecodeSuccessCallback = void (AudioBuffer decodedData);
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback DecodeErrorCallback = void (DOMException error);
|
||||
|
||||
enum AudioContextState {
|
||||
|
|
|
@ -189,7 +189,6 @@ interface ConsoleInstance {
|
|||
void profileEnd(any... data);
|
||||
};
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback ConsoleInstanceDumpCallback = void (DOMString message);
|
||||
|
||||
enum ConsoleLogLevel {
|
||||
|
|
|
@ -17,7 +17,6 @@ interface DataTransferItem {
|
|||
File? getAsFile();
|
||||
};
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback FunctionStringCallback = void (DOMString data);
|
||||
|
||||
// https://wicg.github.io/entries-api/#idl-index
|
||||
|
|
|
@ -10,15 +10,15 @@
|
|||
* Opera Software ASA. You are granted a license to use, reproduce
|
||||
* and create derivative works of this document.
|
||||
*/
|
||||
[TreatNonObjectAsNull, MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
[TreatNonObjectAsNull]
|
||||
callback EventHandlerNonNull = any (Event event);
|
||||
typedef EventHandlerNonNull? EventHandler;
|
||||
|
||||
[TreatNonObjectAsNull, MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
[TreatNonObjectAsNull]
|
||||
callback OnBeforeUnloadEventHandlerNonNull = DOMString? (Event event);
|
||||
typedef OnBeforeUnloadEventHandlerNonNull? OnBeforeUnloadEventHandler;
|
||||
|
||||
[TreatNonObjectAsNull, MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
[TreatNonObjectAsNull]
|
||||
callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long column, optional any error);
|
||||
typedef OnErrorEventHandlerNonNull? OnErrorEventHandler;
|
||||
|
||||
|
|
|
@ -11,10 +11,8 @@ dictionary FileSystemFlags {
|
|||
boolean exclusive = false;
|
||||
};
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback FileSystemEntryCallback = void (FileSystemEntry entry);
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback ErrorCallback = void (DOMException err);
|
||||
|
||||
interface FileSystem {
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* https://wicg.github.io/entries-api/#idl-index
|
||||
*/
|
||||
|
||||
[MOZ_CAN_RUN_SCRIPT_BOUNDARY]
|
||||
callback FileSystemEntriesCallback = void (sequence<FileSystemEntry> entries);
|
||||
|
||||
interface FileSystemDirectoryReader {
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче