mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-27 21:00:50 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
db7359881e
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1193379 - Moving location of files under dom/bluetooth requires a clobber
|
||||
Bug 1201224 - stop unifying test package during mac universal builds needed a CLOBBER
|
||||
|
@ -23,7 +23,7 @@
|
||||
macanimationtype="document"
|
||||
fullscreenbutton="true"
|
||||
screenX="4" screenY="4"
|
||||
width="640" height="480"
|
||||
width="800" height="600"
|
||||
persist="screenX screenY width height sizemode">
|
||||
|
||||
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"></script>
|
||||
|
@ -142,6 +142,7 @@ ProjectList.prototype = {
|
||||
icon.setAttribute("src", opts.icon);
|
||||
opts.panel.appendChild(icon);
|
||||
opts.panel.appendChild(span);
|
||||
opts.panel.setAttribute("title", opts.name);
|
||||
} else {
|
||||
opts.panel.setAttribute("label", opts.name);
|
||||
opts.panel.setAttribute("image", opts.icon);
|
||||
|
@ -23,7 +23,7 @@ html, body {
|
||||
}
|
||||
|
||||
#custom-value-name {
|
||||
width: 70%;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
header {
|
||||
@ -38,13 +38,15 @@ header {
|
||||
}
|
||||
|
||||
#device-fields td {
|
||||
background-color: #f1f1f1;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-right: 1px solid #fff;
|
||||
background-color: #F9F9F9;
|
||||
border-bottom: 1px solid #CCC;
|
||||
border-right: 1px solid #FFF;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
#device-fields td:first-child {
|
||||
min-width: 400px;
|
||||
max-width: 250px;
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
#device-fields td.preference-name, #device-fields td.setting-name {
|
||||
@ -65,7 +67,7 @@ header {
|
||||
}
|
||||
|
||||
#device-fields .custom-input {
|
||||
width: 300px;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
#search {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
html {
|
||||
font: message-box;
|
||||
font-size: 15px;
|
||||
font-size: 0.9em;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
@ -28,7 +28,7 @@ body {
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
font-size: 2em;
|
||||
font-weight: lighter;
|
||||
line-height: 1.2;
|
||||
margin: 0;
|
||||
@ -60,7 +60,7 @@ th, td {
|
||||
}
|
||||
|
||||
th {
|
||||
min-width: 130px;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
th:first-of-type, td:first-of-type {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
html {
|
||||
font: message-box;
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@ -53,42 +53,59 @@ label,
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.panel-item span {
|
||||
display: block;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 75%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.panel-item {
|
||||
padding: 3%;
|
||||
display: block;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
border-top: 1px solid #ededed;
|
||||
border-left: 0;
|
||||
width: 94%;
|
||||
cursor: pointer;
|
||||
border-top: 1px solid transparent;
|
||||
border-left: 0;
|
||||
border-bottom: 1px solid #CCC;
|
||||
border-right: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
button.panel-item {
|
||||
background-position: 8px 8px;
|
||||
background-position: 5px 5px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 14px 14px;
|
||||
padding-left: 25px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
button.project-panel-item-refreshtabs {
|
||||
display: inline-block;
|
||||
float: right;
|
||||
padding: 3px;
|
||||
text-transform: none;
|
||||
width: auto;
|
||||
margin: 0 4px 5px 5px;
|
||||
}
|
||||
|
||||
.panel-item:disabled {
|
||||
background-color: #FFF;
|
||||
color: #5A5A5A;
|
||||
opacity: 0.5;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.panel-item:not(:disabled):hover {
|
||||
#refresh-tabs {
|
||||
background-color: #FFF;
|
||||
border-top: 1px solid #EDEDED;
|
||||
display: inline-block;
|
||||
float: right;
|
||||
padding: 3px;
|
||||
text-transform: none;
|
||||
border-right: 1px solid #CCC;
|
||||
width: auto;
|
||||
margin: 0 4px 5px 5px;
|
||||
}
|
||||
|
||||
.panel-item:not(:disabled):hover,
|
||||
button.panel-item:not(:disabled):hover,
|
||||
#refresh-tabs:hover {
|
||||
background-color: #CCF0FD;
|
||||
border-top: 1px solid #EDEDED;
|
||||
}
|
||||
|
||||
.configure-button {
|
||||
@ -101,7 +118,7 @@ button.project-panel-item-refreshtabs {
|
||||
background-repeat: no-repeat;
|
||||
background-size: 14px 14px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
top: -2px;
|
||||
right: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
@ -162,10 +162,14 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
||||
.panel-list {
|
||||
display: none;
|
||||
position: relative;
|
||||
max-width: 250px;
|
||||
max-width: 180px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#project-listing-panel.panel-list {
|
||||
max-width: 165px;
|
||||
}
|
||||
|
||||
.panel-list-wrapper {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
@ -1,81 +0,0 @@
|
||||
#!/usr/bin/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/.
|
||||
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
import json
|
||||
import re
|
||||
import errno
|
||||
from argparse import ArgumentParser
|
||||
|
||||
def getFileHashAndSize(filename):
|
||||
sha512Hash = 'UNKNOWN'
|
||||
size = 'UNKNOWN'
|
||||
|
||||
try:
|
||||
# open in binary mode to make sure we get consistent results
|
||||
# across all platforms
|
||||
f = open(filename, "rb")
|
||||
shaObj = hashlib.sha512(f.read())
|
||||
sha512Hash = shaObj.hexdigest()
|
||||
|
||||
size = os.path.getsize(filename)
|
||||
except:
|
||||
pass
|
||||
|
||||
return (sha512Hash, size)
|
||||
|
||||
def getMarProperties(filename, partial=False):
|
||||
if not os.path.exists(filename):
|
||||
return {}
|
||||
(mar_hash, mar_size) = getFileHashAndSize(filename)
|
||||
martype = 'partial' if partial else 'complete'
|
||||
return {
|
||||
'%sMarFilename' % martype: os.path.basename(filename),
|
||||
'%sMarSize' % martype: mar_size,
|
||||
'%sMarHash' % martype: mar_hash,
|
||||
}
|
||||
|
||||
def getPartialInfo(props):
|
||||
return [{
|
||||
"from_buildid": props.get("previous_buildid"),
|
||||
"size": props.get("partialMarSize"),
|
||||
"hash": props.get("partialMarHash"),
|
||||
"url": props.get("partialMarUrl"),
|
||||
}]
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Generate mach_build_properties.json for automation builds.')
|
||||
parser.add_argument("--complete-mar-file", required=True,
|
||||
action="store", dest="complete_mar_file",
|
||||
help="Path to the complete MAR file, relative to the objdir.")
|
||||
parser.add_argument("--partial-mar-file", required=False,
|
||||
action="store", dest="partial_mar_file",
|
||||
help="Path to the partial MAR file, relative to the objdir.")
|
||||
parser.add_argument("--upload-properties", required=False,
|
||||
action="store", dest="upload_properties",
|
||||
help="Path to the properties written by 'make upload'")
|
||||
args = parser.parse_args()
|
||||
|
||||
json_data = getMarProperties(args.complete_mar_file)
|
||||
if args.upload_properties:
|
||||
with open(args.upload_properties) as f:
|
||||
json_data.update(json.load(f))
|
||||
if args.partial_mar_file:
|
||||
json_data.update(getMarProperties(args.partial_mar_file, partial=True))
|
||||
|
||||
# Pull the previous buildid from the partial mar filename.
|
||||
res = re.match(r'.*\.([0-9]+)-[0-9]+.mar', args.partial_mar_file)
|
||||
if res:
|
||||
json_data['previous_buildid'] = res.group(1)
|
||||
|
||||
# Set partialInfo to be a collection of the partial mar properties
|
||||
# useful for balrog.
|
||||
json_data['partialInfo'] = getPartialInfo(json_data)
|
||||
|
||||
with open('mach_build_properties.json', 'w') as outfile:
|
||||
json.dump(json_data, outfile, indent=4)
|
@ -17,11 +17,6 @@ include $(topsrcdir)/toolkit/mozapps/installer/upload-files.mk
|
||||
# Clear out DIST_FILES if it was set by upload-files.mk (for Android builds)
|
||||
DIST_FILES =
|
||||
|
||||
ifeq (1,$(MOZ_AUTOMATION_UPLOAD))
|
||||
# Properties from 'make upload' that are file URLs.
|
||||
AUTOMATION_UPLOAD_PROPERTIES = --upload-properties $(DIST)/upload-properties.json
|
||||
endif
|
||||
|
||||
# Helper variables to convert from MOZ_AUTOMATION_* variables to the
|
||||
# corresponding the make target
|
||||
tier_MOZ_AUTOMATION_BUILD_SYMBOLS = buildsymbols
|
||||
@ -100,7 +95,7 @@ automation/l10n-check: automation/pretty-l10n-check
|
||||
automation/update-packaging: automation/pretty-update-packaging
|
||||
|
||||
automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
|
||||
$(PYTHON) $(topsrcdir)/build/gen_mach_buildprops.py --complete-mar-file $(DIST)/$(COMPLETE_MAR) $(addprefix --partial-mar-file ,$(wildcard $(DIST)/$(PARTIAL_MAR))) $(AUTOMATION_UPLOAD_PROPERTIES)
|
||||
@echo Automation steps completed.
|
||||
|
||||
# Note: We have to force -j1 here, at least until bug 1036563 is fixed.
|
||||
AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1
|
||||
|
@ -8,7 +8,12 @@
|
||||
# to be set:
|
||||
# UPLOAD_HOST : host to upload files to
|
||||
# UPLOAD_USER : username on that host
|
||||
# and one of the following:
|
||||
# UPLOAD_PATH : path on that host to put the files in
|
||||
# UPLOAD_TO_TEMP : upload files to a new temporary directory
|
||||
#
|
||||
# If UPLOAD_HOST and UPLOAD_USER are not set, this script will simply write out
|
||||
# the properties file.
|
||||
#
|
||||
# And will use the following optional environment variables if set:
|
||||
# UPLOAD_SSH_KEY : path to a ssh private key to use
|
||||
@ -25,18 +30,12 @@
|
||||
import sys, os
|
||||
import re
|
||||
import json
|
||||
import errno
|
||||
import hashlib
|
||||
from optparse import OptionParser
|
||||
from subprocess import check_call, check_output, STDOUT
|
||||
import redo
|
||||
|
||||
def RequireEnvironmentVariable(v):
|
||||
"""Return the value of the environment variable named v, or print
|
||||
an error and exit if it's unset (or empty)."""
|
||||
if not v in os.environ or os.environ[v] == "":
|
||||
print "Error: required environment variable %s not set" % v
|
||||
sys.exit(1)
|
||||
return os.environ[v]
|
||||
|
||||
def OptionalEnvironmentVariable(v):
|
||||
"""Return the value of the environment variable named v, or None
|
||||
if it's unset (or empty)."""
|
||||
@ -119,6 +118,33 @@ def GetRemotePath(path, local_file, base_path):
|
||||
dir = dir[len(base_path)+1:].replace('\\','/')
|
||||
return path + dir
|
||||
|
||||
def GetFileHashAndSize(filename):
|
||||
sha512Hash = 'UNKNOWN'
|
||||
size = 'UNKNOWN'
|
||||
|
||||
try:
|
||||
# open in binary mode to make sure we get consistent results
|
||||
# across all platforms
|
||||
with open(filename, "rb") as f:
|
||||
shaObj = hashlib.sha512(f.read())
|
||||
sha512Hash = shaObj.hexdigest()
|
||||
|
||||
size = os.path.getsize(filename)
|
||||
except:
|
||||
raise Exception("Unable to get filesize/hash from file: %s" % filename)
|
||||
|
||||
return (sha512Hash, size)
|
||||
|
||||
def GetMarProperties(filename):
|
||||
if not os.path.exists(filename):
|
||||
return {}
|
||||
(mar_hash, mar_size) = GetFileHashAndSize(filename)
|
||||
return {
|
||||
'completeMarFilename': os.path.basename(filename),
|
||||
'completeMarSize': mar_size,
|
||||
'completeMarHash': mar_hash,
|
||||
}
|
||||
|
||||
def GetUrlProperties(output, package):
|
||||
# let's create a switch case using name-spaces/dict
|
||||
# rather than a long if/else with duplicate code
|
||||
@ -156,7 +182,7 @@ def GetUrlProperties(output, package):
|
||||
properties = {prop: 'UNKNOWN' for prop, condition in property_conditions}
|
||||
return properties
|
||||
|
||||
def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None, properties_file=None, package=None):
|
||||
def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None, package=None):
|
||||
"""Upload each file in the list files to user@host:path. Optionally pass
|
||||
port and ssh_key to the ssh commands. If base_path is not None, upload
|
||||
files including their path relative to base_path. If upload_to_temp_dir is
|
||||
@ -167,6 +193,13 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None,
|
||||
after uploading all files, passing it the upload path, and the full paths to
|
||||
all files uploaded.
|
||||
If verbose is True, print status updates while working."""
|
||||
if not host or not user:
|
||||
return {}
|
||||
if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
|
||||
print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
|
||||
"defined."
|
||||
sys.exit(1)
|
||||
|
||||
if upload_to_temp_dir:
|
||||
path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
|
||||
if not path.endswith("/"):
|
||||
@ -174,6 +207,7 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None,
|
||||
if base_path is not None:
|
||||
base_path = os.path.abspath(base_path)
|
||||
remote_files = []
|
||||
properties = {}
|
||||
try:
|
||||
for file in files:
|
||||
file = os.path.abspath(file)
|
||||
@ -193,22 +227,28 @@ def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None,
|
||||
output = DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
|
||||
# We print since mozharness may parse URLs from the output stream.
|
||||
print output
|
||||
if properties_file:
|
||||
with open(properties_file, 'w') as outfile:
|
||||
properties = GetUrlProperties(output, package)
|
||||
properties['packageFilename'] = package
|
||||
properties['uploadFiles'] = [os.path.abspath(f) for f in files]
|
||||
json.dump(properties, outfile, indent=4)
|
||||
properties = GetUrlProperties(output, package)
|
||||
finally:
|
||||
if upload_to_temp_dir:
|
||||
DoSSHCommand("rm -rf %s" % path, user, host, port=port,
|
||||
ssh_key=ssh_key)
|
||||
if verbose:
|
||||
print "Upload complete"
|
||||
return properties
|
||||
|
||||
def WriteProperties(files, properties_file, url_properties, package):
|
||||
properties = url_properties
|
||||
for file in files:
|
||||
if file.endswith('.complete.mar'):
|
||||
properties.update(GetMarProperties(file))
|
||||
with open(properties_file, 'w') as outfile:
|
||||
properties['packageFilename'] = package
|
||||
properties['uploadFiles'] = [os.path.abspath(f) for f in files]
|
||||
json.dump(properties, outfile, indent=4)
|
||||
|
||||
if __name__ == '__main__':
|
||||
host = RequireEnvironmentVariable('UPLOAD_HOST')
|
||||
user = RequireEnvironmentVariable('UPLOAD_USER')
|
||||
host = OptionalEnvironmentVariable('UPLOAD_HOST')
|
||||
user = OptionalEnvironmentVariable('UPLOAD_USER')
|
||||
path = OptionalEnvironmentVariable('UPLOAD_PATH')
|
||||
upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
|
||||
port = OptionalEnvironmentVariable('UPLOAD_PORT')
|
||||
@ -216,10 +256,7 @@ if __name__ == '__main__':
|
||||
port = int(port)
|
||||
key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
|
||||
post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
|
||||
if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
|
||||
print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
|
||||
"defined."
|
||||
sys.exit(1)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
if path is not None:
|
||||
path = FixupMsysPath(path)
|
||||
@ -240,12 +277,16 @@ if __name__ == '__main__':
|
||||
if len(args) < 1:
|
||||
print "You must specify at least one file to upload"
|
||||
sys.exit(1)
|
||||
if not options.properties_file:
|
||||
print "You must specify a --properties-file"
|
||||
sys.exit(1)
|
||||
try:
|
||||
UploadFiles(user, host, path, args, base_path=options.base_path,
|
||||
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
|
||||
post_upload_command=post_upload_command,
|
||||
properties_file=options.properties_file, package=options.package,
|
||||
verbose=True)
|
||||
url_properties = UploadFiles(user, host, path, args, base_path=options.base_path,
|
||||
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
|
||||
post_upload_command=post_upload_command,
|
||||
package=options.package,
|
||||
verbose=True)
|
||||
WriteProperties(args, options.properties_file, url_properties, options.package)
|
||||
except IOError, (strerror):
|
||||
print strerror
|
||||
sys.exit(1)
|
||||
|
@ -1595,6 +1595,7 @@ if test "$GNU_CXX"; then
|
||||
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
||||
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wrange-loop-analysis - catches copies during range-based for loops.
|
||||
# -Wreturn-type - catches missing returns, zero false positives
|
||||
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||
@ -1626,6 +1627,7 @@ if test "$GNU_CXX"; then
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
|
||||
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, range-loop-analysis, ac_cxx_has_range_loop_analysis)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
|
||||
fi
|
||||
|
||||
|
@ -190,6 +190,30 @@ FlattenedChildIterator::Init(bool aIgnoreXBL)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ExplicitChildIterator::Seek(nsIContent* aChildToFind)
|
||||
{
|
||||
if (aChildToFind->GetParent() == mParent &&
|
||||
!aChildToFind->IsRootOfAnonymousSubtree()) {
|
||||
// Fast path: just point ourselves to aChildToFind, which is a
|
||||
// normal DOM child of ours.
|
||||
MOZ_ASSERT(!ShadowRoot::IsShadowInsertionPoint(aChildToFind));
|
||||
MOZ_ASSERT(!nsContentUtils::IsContentInsertionPoint(aChildToFind));
|
||||
mChild = aChildToFind;
|
||||
mIndexInInserted = 0;
|
||||
mShadowIterator = nullptr;
|
||||
mDefaultChild = nullptr;
|
||||
mIsFirst = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Can we add more fast paths here based on whether the parent of aChildToFind
|
||||
// is a shadow insertion point or content insertion point?
|
||||
|
||||
// Slow path: just walk all our kids.
|
||||
Seek(aChildToFind, nullptr);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
ExplicitChildIterator::Get()
|
||||
{
|
||||
|
@ -60,16 +60,24 @@ public:
|
||||
|
||||
nsIContent* GetNextChild();
|
||||
|
||||
// Looks for aChildToFind respecting insertion points until aChildToFind
|
||||
// Looks for aChildToFind respecting insertion points until aChildToFind is
|
||||
// found. This version can take shortcuts that the two-argument version
|
||||
// can't, so can be faster (and in fact can be O(1) instead of O(N) in many
|
||||
// cases).
|
||||
void Seek(nsIContent* aChildToFind);
|
||||
|
||||
// Looks for aChildToFind respecting insertion points until aChildToFind is found.
|
||||
// or aBound is found. If aBound is nullptr then the seek is unbounded. Returns
|
||||
// whether aChildToFind was found as an explicit child prior to encountering
|
||||
// aBound.
|
||||
bool Seek(nsIContent* aChildToFind, nsIContent* aBound = nullptr)
|
||||
bool Seek(nsIContent* aChildToFind, nsIContent* aBound)
|
||||
{
|
||||
// It would be nice to assert that we find aChildToFind, but bz thinks that
|
||||
// we might not find aChildToFind when called from ContentInserted
|
||||
// if first-letter frames are about.
|
||||
|
||||
// We can't easily take shortcuts here because we'd have to have a way to
|
||||
// compare aChildToFind to aBound.
|
||||
nsIContent* child;
|
||||
do {
|
||||
child = GetNextChild();
|
||||
|
@ -316,7 +316,7 @@ ShadowRoot::DistributeSingleNode(nsIContent* aContent)
|
||||
if (!isIndexFound) {
|
||||
// We have still not found an index in the insertion point,
|
||||
// thus it must be at the end.
|
||||
MOZ_ASSERT(childIterator.Seek(aContent),
|
||||
MOZ_ASSERT(childIterator.Seek(aContent, nullptr),
|
||||
"Trying to match a node that is not a candidate to be matched");
|
||||
insertionPoint->AppendMatchedNode(aContent);
|
||||
}
|
||||
|
@ -42,3 +42,7 @@ method SVGSVGElement.getElementById
|
||||
attribute SVGSVGElement.currentScale
|
||||
property Fill
|
||||
property FillOpacity
|
||||
|
||||
// Push API
|
||||
method PushManager.subscribe
|
||||
method PushSubscription.unsubscribe
|
||||
|
@ -631,8 +631,8 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
||||
*aActionTaken = false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aEventMessage == NS_CUT || aEventMessage == NS_COPY ||
|
||||
aEventMessage == NS_PASTE,
|
||||
NS_ASSERTION(aEventMessage == eCut || aEventMessage == eCopy ||
|
||||
aEventMessage == ePaste,
|
||||
"Invalid clipboard event type");
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = aPresShell;
|
||||
@ -688,7 +688,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
||||
nsRefPtr<DataTransfer> clipboardData;
|
||||
if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
|
||||
clipboardData =
|
||||
new DataTransfer(piWindow, aEventMessage, aEventMessage == NS_PASTE,
|
||||
new DataTransfer(piWindow, aEventMessage, aEventMessage == ePaste,
|
||||
aClipboardType);
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
@ -703,7 +703,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
||||
// No need to do anything special during a paste. Either an event listener
|
||||
// took care of it and cancelled the event, or the caller will handle it.
|
||||
// Return true to indicate that the event wasn't cancelled.
|
||||
if (aEventMessage == NS_PASTE) {
|
||||
if (aEventMessage == ePaste) {
|
||||
// Clear and mark the clipboardData as readonly. This prevents someone
|
||||
// from reading the clipboard contents after the paste event has fired.
|
||||
if (clipboardData) {
|
||||
@ -743,7 +743,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
||||
|
||||
// when cutting non-editable content, do nothing
|
||||
// XXX this is probably the wrong editable flag to check
|
||||
if (aEventMessage != NS_CUT || content->IsEditable()) {
|
||||
if (aEventMessage != eCut || content->IsEditable()) {
|
||||
// get the data from the selection if any
|
||||
bool isCollapsed;
|
||||
sel->GetIsCollapsed(&isCollapsed);
|
||||
|
@ -64,8 +64,8 @@ class nsCopySupport
|
||||
|
||||
/**
|
||||
* Fires a cut, copy or paste event, on the given presshell, depending
|
||||
* on the value of aEventMessage, which should be either NS_CUT, NS_COPY or
|
||||
* NS_PASTE, and perform the default copy action if the event was not
|
||||
* on the value of aEventMessage, which should be either eCut, eCopy or
|
||||
* ePaste, and perform the default copy action if the event was not
|
||||
* cancelled.
|
||||
*
|
||||
* If aSelection is specified, then this selection is used as the target
|
||||
|
@ -2026,7 +2026,7 @@ nsDOMWindowUtils::SendSelectionSetEvent(uint32_t aOffset,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
|
||||
WidgetSelectionEvent selectionEvent(true, eSetSelection, widget);
|
||||
InitEvent(selectionEvent);
|
||||
|
||||
selectionEvent.mOffset = aOffset;
|
||||
|
@ -8593,9 +8593,6 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
||||
// The misspelled key 'referer' is as per the HTTP spec
|
||||
rv = httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("referer"),
|
||||
mReferrer);
|
||||
if (NS_FAILED(rv)) {
|
||||
mReferrer.Truncate();
|
||||
}
|
||||
|
||||
static const char *const headers[] = {
|
||||
"default-style",
|
||||
|
@ -6918,7 +6918,9 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
|
||||
if (!AreDialogsEnabled()) {
|
||||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
// Just silently return. In the case of alert(), the return value is
|
||||
// ignored. In the case of confirm(), returning false is the same thing as
|
||||
// would happen if the user cancels.
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -7058,7 +7060,7 @@ nsGlobalWindow::PromptOuter(const nsAString& aMessage, const nsAString& aInitial
|
||||
SetDOMStringToNull(aReturn);
|
||||
|
||||
if (!AreDialogsEnabled()) {
|
||||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
// Return null, as if the user just canceled the prompt.
|
||||
return;
|
||||
}
|
||||
|
||||
@ -7496,6 +7498,8 @@ nsGlobalWindow::PrintOuter(ErrorResult& aError)
|
||||
}
|
||||
|
||||
if (!AreDialogsEnabled()) {
|
||||
// We probably want to keep throwing here; silently doing nothing is a bit
|
||||
// weird given the typical use cases of print().
|
||||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return;
|
||||
}
|
||||
@ -9553,6 +9557,8 @@ nsGlobalWindow::ShowModalDialogOuter(const nsAString& aUrl, nsIVariant* aArgumen
|
||||
EnsureReflowFlushAndPaint();
|
||||
|
||||
if (!AreDialogsEnabled()) {
|
||||
// We probably want to keep throwing here; silently doing nothing is a bit
|
||||
// weird given the typical use cases of showModalDialog().
|
||||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -520,9 +520,9 @@ nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
|
||||
nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
|
||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||
|
||||
EventMessage eventMessage = NS_COPY;
|
||||
EventMessage eventMessage = eCopy;
|
||||
if (strcmp(aCommandName, "cmd_cut") == 0) {
|
||||
eventMessage = NS_CUT;
|
||||
eventMessage = eCut;
|
||||
}
|
||||
|
||||
bool actionTaken = false;
|
||||
|
@ -79,7 +79,7 @@ ClipboardEvent::Constructor(const GlobalObject& aGlobal,
|
||||
// Always create a clipboardData for the copy event. If this is changed to
|
||||
// support other types of events, make sure that read/write privileges are
|
||||
// checked properly within DataTransfer.
|
||||
clipboardData = new DataTransfer(ToSupports(e), NS_COPY, false, -1);
|
||||
clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1);
|
||||
clipboardData->SetData(aParam.mDataType, aParam.mData);
|
||||
}
|
||||
}
|
||||
@ -105,11 +105,11 @@ ClipboardEvent::GetClipboardData()
|
||||
if (!event->clipboardData) {
|
||||
if (mEventIsInternal) {
|
||||
event->clipboardData =
|
||||
new DataTransfer(ToSupports(this), NS_COPY, false, -1);
|
||||
new DataTransfer(ToSupports(this), eCopy, false, -1);
|
||||
} else {
|
||||
event->clipboardData =
|
||||
new DataTransfer(ToSupports(this), event->mMessage,
|
||||
event->mMessage == NS_PASTE,
|
||||
event->mMessage == ePaste,
|
||||
nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
}
|
||||
|
@ -86,13 +86,13 @@ DataTransfer::DataTransfer(nsISupports* aParent, EventMessage aEventMessage,
|
||||
// For these events, we want to be able to add data to the data transfer, so
|
||||
// clear the readonly state. Otherwise, the data is already present. For
|
||||
// external usage, cache the data from the native clipboard or drag.
|
||||
if (aEventMessage == NS_CUT ||
|
||||
aEventMessage == NS_COPY ||
|
||||
if (aEventMessage == eCut ||
|
||||
aEventMessage == eCopy ||
|
||||
aEventMessage == eDragStart ||
|
||||
aEventMessage == eLegacyDragGesture) {
|
||||
mReadOnly = false;
|
||||
} else if (mIsExternal) {
|
||||
if (aEventMessage == NS_PASTE) {
|
||||
if (aEventMessage == ePaste) {
|
||||
CacheExternalClipboardFormats();
|
||||
} else if (aEventMessage >= eDragDropEventFirst &&
|
||||
aEventMessage <= eDragDropEventLast) {
|
||||
@ -271,7 +271,7 @@ DataTransfer::GetFiles(ErrorResult& aRv)
|
||||
{
|
||||
if (mEventMessage != eDrop &&
|
||||
mEventMessage != eLegacyDragDrop &&
|
||||
mEventMessage != NS_PASTE) {
|
||||
mEventMessage != ePaste) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -543,8 +543,8 @@ DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv)
|
||||
{
|
||||
// Only the first item is valid for clipboard events
|
||||
if (aIndex > 0 &&
|
||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
||||
mEventMessage == NS_PASTE)) {
|
||||
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||
mEventMessage == ePaste)) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -584,8 +584,8 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
|
||||
// Only the first item is valid for clipboard events
|
||||
if (aIndex > 0 &&
|
||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
||||
mEventMessage == NS_PASTE)) {
|
||||
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||
mEventMessage == ePaste)) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
|
||||
@ -604,7 +604,7 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
nsIPrincipal* principal = nullptr;
|
||||
if (mIsCrossDomainSubFrameDrop ||
|
||||
(mEventMessage != eDrop && mEventMessage != eLegacyDragDrop &&
|
||||
mEventMessage != NS_PASTE &&
|
||||
mEventMessage != ePaste &&
|
||||
!nsContentUtils::IsCallerChrome())) {
|
||||
principal = nsContentUtils::SubjectPrincipal();
|
||||
}
|
||||
@ -696,8 +696,8 @@ DataTransfer::MozSetDataAt(const nsAString& aFormat, nsIVariant* aData,
|
||||
|
||||
// Only the first item is valid for clipboard events
|
||||
if (aIndex > 0 &&
|
||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
||||
mEventMessage == NS_PASTE)) {
|
||||
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||
mEventMessage == ePaste)) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
|
||||
@ -742,8 +742,8 @@ DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
|
||||
// Only the first item is valid for clipboard events
|
||||
if (aIndex > 0 &&
|
||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
||||
mEventMessage == NS_PASTE)) {
|
||||
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||
mEventMessage == ePaste)) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return;
|
||||
}
|
||||
@ -758,8 +758,8 @@ DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||
MOZ_ASSERT(!mReadOnly);
|
||||
MOZ_ASSERT(aIndex < mItems.Length());
|
||||
MOZ_ASSERT(aIndex == 0 ||
|
||||
(mEventMessage != NS_CUT && mEventMessage != NS_COPY &&
|
||||
mEventMessage != NS_PASTE));
|
||||
(mEventMessage != eCut && mEventMessage != eCopy &&
|
||||
mEventMessage != ePaste));
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
@ -1258,7 +1258,7 @@ DataTransfer::CacheExternalDragFormats()
|
||||
void
|
||||
DataTransfer::CacheExternalClipboardFormats()
|
||||
{
|
||||
NS_ASSERTION(mEventMessage == NS_PASTE,
|
||||
NS_ASSERTION(mEventMessage == ePaste,
|
||||
"caching clipboard data for invalid event");
|
||||
|
||||
// Called during the constructor for paste events to cache the formats
|
||||
@ -1300,7 +1300,7 @@ DataTransfer::FillInExternalData(TransferItem& aItem, uint32_t aIndex)
|
||||
}
|
||||
|
||||
// only drag and paste events should be calling FillInExternalData
|
||||
NS_ASSERTION(mEventMessage != NS_CUT && mEventMessage != NS_COPY,
|
||||
NS_ASSERTION(mEventMessage != eCut && mEventMessage != eCopy,
|
||||
"clipboard event with empty data");
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat);
|
||||
@ -1318,7 +1318,7 @@ DataTransfer::FillInExternalData(TransferItem& aItem, uint32_t aIndex)
|
||||
trans->Init(nullptr);
|
||||
trans->AddDataFlavor(format);
|
||||
|
||||
if (mEventMessage == NS_PASTE) {
|
||||
if (mEventMessage == ePaste) {
|
||||
MOZ_ASSERT(aIndex == 0, "index in clipboard must be 0");
|
||||
|
||||
nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
|
||||
|
@ -153,11 +153,11 @@ EVENT(abort,
|
||||
EventNameType_All,
|
||||
eBasicEventClass)
|
||||
EVENT(canplay,
|
||||
NS_CANPLAY,
|
||||
eCanPlay,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(canplaythrough,
|
||||
NS_CANPLAYTHROUGH,
|
||||
eCanPlayThrough,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(change,
|
||||
@ -207,15 +207,15 @@ EVENT(drop,
|
||||
EventNameType_HTMLXUL,
|
||||
eDragEventClass)
|
||||
EVENT(durationchange,
|
||||
NS_DURATIONCHANGE,
|
||||
eDurationChange,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(emptied,
|
||||
NS_EMPTIED,
|
||||
eEmptied,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(ended,
|
||||
NS_ENDED,
|
||||
eEnded,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(input,
|
||||
@ -255,15 +255,15 @@ NON_IDL_EVENT(mozbrowserafterkeyup,
|
||||
EventNameType_None,
|
||||
eBeforeAfterKeyboardEventClass)
|
||||
EVENT(loadeddata,
|
||||
NS_LOADEDDATA,
|
||||
eLoadedData,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(loadedmetadata,
|
||||
NS_LOADEDMETADATA,
|
||||
eLoadedMetaData,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(loadstart,
|
||||
NS_LOADSTART,
|
||||
eLoadStart,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(mousedown,
|
||||
@ -354,23 +354,23 @@ EVENT(lostpointercapture,
|
||||
// Not supported yet; probably never because "wheel" is a better idea.
|
||||
// EVENT(mousewheel)
|
||||
EVENT(pause,
|
||||
NS_PAUSE,
|
||||
ePause,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(play,
|
||||
NS_PLAY,
|
||||
ePlay,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(playing,
|
||||
NS_PLAYING,
|
||||
ePlaying,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(progress,
|
||||
NS_PROGRESS,
|
||||
eProgress,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(ratechange,
|
||||
NS_RATECHANGE,
|
||||
eRateChange,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(reset,
|
||||
@ -378,11 +378,11 @@ EVENT(reset,
|
||||
EventNameType_HTMLXUL,
|
||||
eBasicEventClass)
|
||||
EVENT(seeked,
|
||||
NS_SEEKED,
|
||||
eSeeked,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(seeking,
|
||||
NS_SEEKING,
|
||||
eSeeking,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(select,
|
||||
@ -394,7 +394,7 @@ EVENT(show,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(stalled,
|
||||
NS_STALLED,
|
||||
eStalled,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(submit,
|
||||
@ -402,19 +402,19 @@ EVENT(submit,
|
||||
EventNameType_HTMLXUL,
|
||||
eBasicEventClass)
|
||||
EVENT(suspend,
|
||||
NS_SUSPEND,
|
||||
eSuspend,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(timeupdate,
|
||||
NS_TIMEUPDATE,
|
||||
eTimeUpdate,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(volumechange,
|
||||
NS_VOLUMECHANGE,
|
||||
eVolumeChange,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(waiting,
|
||||
NS_WAITING,
|
||||
eWaiting,
|
||||
EventNameType_HTML,
|
||||
eBasicEventClass)
|
||||
EVENT(wheel,
|
||||
@ -422,15 +422,15 @@ EVENT(wheel,
|
||||
EventNameType_All,
|
||||
eWheelEventClass)
|
||||
EVENT(copy,
|
||||
NS_COPY,
|
||||
eCopy,
|
||||
EventNameType_HTMLXUL,
|
||||
eClipboardEventClass)
|
||||
EVENT(cut,
|
||||
NS_CUT,
|
||||
eCut,
|
||||
EventNameType_HTMLXUL,
|
||||
eClipboardEventClass)
|
||||
EVENT(paste,
|
||||
NS_PASTE,
|
||||
ePaste,
|
||||
EventNameType_HTMLXUL,
|
||||
eClipboardEventClass)
|
||||
// Gecko-specific extensions that apply to elements
|
||||
|
@ -743,7 +743,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
|
||||
}
|
||||
break;
|
||||
case NS_SELECTION_SET:
|
||||
case eSetSelection:
|
||||
IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
|
||||
aEvent->AsSelectionEvent());
|
||||
break;
|
||||
|
@ -149,8 +149,8 @@ GetEventMessageName(EventMessage aMessage)
|
||||
return "NS_COMPOSITION_COMMIT_AS_IS";
|
||||
case NS_COMPOSITION_COMMIT:
|
||||
return "NS_COMPOSITION_COMMIT";
|
||||
case NS_SELECTION_SET:
|
||||
return "NS_SELECTION_SET";
|
||||
case eSetSelection:
|
||||
return "eSetSelection";
|
||||
default:
|
||||
return "unacceptable event message";
|
||||
}
|
||||
|
@ -291,14 +291,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
||||
|
||||
mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread());
|
||||
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
auto audioSinkCreator = [self] () {
|
||||
MOZ_ASSERT(self->OnTaskQueue());
|
||||
return new DecodedAudioDataSink(
|
||||
self->mAudioQueue, self->GetMediaTime(),
|
||||
self->mInfo.mAudio, self->mDecoder->GetAudioChannel());
|
||||
};
|
||||
mAudioSink = new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
|
||||
mMediaSink = CreateAudioSink();
|
||||
}
|
||||
|
||||
MediaDecoderStateMachine::~MediaDecoderStateMachine()
|
||||
@ -348,6 +341,19 @@ MediaDecoderStateMachine::InitializationTask()
|
||||
SameOriginMediaChanged();
|
||||
}
|
||||
|
||||
media::MediaSink*
|
||||
MediaDecoderStateMachine::CreateAudioSink()
|
||||
{
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
auto audioSinkCreator = [self] () {
|
||||
MOZ_ASSERT(self->OnTaskQueue());
|
||||
return new DecodedAudioDataSink(
|
||||
self->mAudioQueue, self->GetMediaTime(),
|
||||
self->mInfo.mAudio, self->mDecoder->GetAudioChannel());
|
||||
};
|
||||
return new AudioSinkWrapper(mTaskQueue, audioSinkCreator);
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HasFutureAudio()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
@ -377,7 +383,7 @@ int64_t MediaDecoderStateMachine::GetDecodedAudioDuration()
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
int64_t audioDecoded = AudioQueue().Duration();
|
||||
if (mAudioSink->IsStarted()) {
|
||||
if (mMediaSink->IsStarted()) {
|
||||
audioDecoded += AudioEndTime() - GetMediaTime();
|
||||
}
|
||||
return audioDecoded;
|
||||
@ -387,7 +393,6 @@ void MediaDecoderStateMachine::DiscardStreamData()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
MOZ_ASSERT(!mAudioSink->IsStarted(), "Should've been stopped in RunStateMachine()");
|
||||
|
||||
const auto clockTime = GetClock();
|
||||
while (true) {
|
||||
@ -1077,8 +1082,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
||||
SetPlayStartTime(TimeStamp::Now());
|
||||
MOZ_ASSERT(IsPlaying());
|
||||
|
||||
StartAudioSink();
|
||||
StartDecodedStream();
|
||||
StartMediaSink();
|
||||
|
||||
DispatchDecodeTasksIfNeeded();
|
||||
}
|
||||
@ -1152,8 +1156,7 @@ void MediaDecoderStateMachine::VolumeChanged()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mAudioSink->SetVolume(mVolume);
|
||||
mStreamSink->SetVolume(mVolume);
|
||||
mMediaSink->SetVolume(mVolume);
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::RecomputeDuration()
|
||||
@ -1273,7 +1276,7 @@ void MediaDecoderStateMachine::Shutdown()
|
||||
|
||||
Reset();
|
||||
|
||||
mAudioSink->Shutdown();
|
||||
mMediaSink->Shutdown();
|
||||
|
||||
// Shut down our start time rendezvous.
|
||||
if (mStartTimeRendezvous) {
|
||||
@ -1466,15 +1469,15 @@ MediaDecoderStateMachine::Seek(SeekTarget aTarget)
|
||||
return mPendingSeek.mPromise.Ensure(__func__);
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::StopAudioSink()
|
||||
void MediaDecoderStateMachine::StopMediaSink()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
if (mAudioSink->IsStarted()) {
|
||||
DECODER_LOG("Stop AudioSink");
|
||||
mAudioSink->Stop();
|
||||
mAudioSinkPromise.DisconnectIfExists();
|
||||
if (mMediaSink->IsStarted()) {
|
||||
DECODER_LOG("Stop MediaSink");
|
||||
mMediaSink->Stop();
|
||||
mMediaSinkPromise.DisconnectIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1752,59 +1755,25 @@ MediaDecoderStateMachine::RequestVideoData()
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::StartAudioSink()
|
||||
MediaDecoderStateMachine::StartMediaSink()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
if (mAudioCaptured) {
|
||||
MOZ_ASSERT(!mAudioSink->IsStarted());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mAudioSink->IsStarted()) {
|
||||
if (!mMediaSink->IsStarted()) {
|
||||
mAudioCompleted = false;
|
||||
mAudioSink->Start(GetMediaTime(), mInfo);
|
||||
mMediaSink->Start(GetMediaTime(), mInfo);
|
||||
|
||||
auto promise = mAudioSink->OnEnded(TrackInfo::kAudioTrack);
|
||||
auto promise = mMediaSink->OnEnded(TrackInfo::kAudioTrack);
|
||||
if (promise) {
|
||||
mAudioSinkPromise.Begin(promise->Then(
|
||||
mMediaSinkPromise.Begin(promise->Then(
|
||||
OwnerThread(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnAudioSinkComplete,
|
||||
&MediaDecoderStateMachine::OnAudioSinkError));
|
||||
&MediaDecoderStateMachine::OnMediaSinkComplete,
|
||||
&MediaDecoderStateMachine::OnMediaSinkError));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::StopDecodedStream()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
if (mStreamSink->IsStarted()) {
|
||||
mStreamSink->Stop();
|
||||
mDecodedStreamPromise.DisconnectIfExists();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::StartDecodedStream()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
|
||||
// Tell DecodedStream to start playback with specified start time and media
|
||||
// info. This is consistent with how we create AudioSink in StartAudioThread().
|
||||
if (mAudioCaptured && !mStreamSink->IsStarted()) {
|
||||
mStreamSink->Start(GetMediaTime(), mInfo);
|
||||
mDecodedStreamPromise.Begin(
|
||||
mStreamSink->OnEnded(TrackInfo::kAudioTrack)->Then(
|
||||
OwnerThread(), __func__, this,
|
||||
&MediaDecoderStateMachine::OnDecodedStreamFinish,
|
||||
&MediaDecoderStateMachine::OnDecodedStreamError));
|
||||
}
|
||||
}
|
||||
|
||||
int64_t MediaDecoderStateMachine::AudioDecodedUsecs()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
@ -1813,7 +1782,7 @@ int64_t MediaDecoderStateMachine::AudioDecodedUsecs()
|
||||
// The amount of audio we have decoded is the amount of audio data we've
|
||||
// already decoded and pushed to the hardware, plus the amount of audio
|
||||
// data waiting to be pushed to the hardware.
|
||||
int64_t pushed = mAudioSink->IsStarted() ? (AudioEndTime() - GetMediaTime()) : 0;
|
||||
int64_t pushed = mMediaSink->IsStarted() ? (AudioEndTime() - GetMediaTime()) : 0;
|
||||
|
||||
// Currently for real time streams, AudioQueue().Duration() produce
|
||||
// wrong values (Bug 1114434), so we use frame counts to calculate duration.
|
||||
@ -1842,7 +1811,7 @@ bool MediaDecoderStateMachine::OutOfDecodedAudio()
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
return IsAudioDecoding() && !AudioQueue().IsFinished() &&
|
||||
AudioQueue().GetSize() == 0 &&
|
||||
!mAudioSink->HasUnplayedFrames(TrackInfo::kAudioTrack);
|
||||
!mMediaSink->HasUnplayedFrames(TrackInfo::kAudioTrack);
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::HasLowUndecodedData()
|
||||
@ -2416,8 +2385,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
||||
mSentPlaybackEndedEvent = true;
|
||||
|
||||
// MediaSink::GetEndTime() must be called before stopping playback.
|
||||
StopAudioSink();
|
||||
StopDecodedStream();
|
||||
StopMediaSink();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -2443,11 +2411,10 @@ MediaDecoderStateMachine::Reset()
|
||||
mState == DECODER_STATE_DORMANT ||
|
||||
mState == DECODER_STATE_DECODING_NONE);
|
||||
|
||||
// Stop the audio thread. Otherwise, AudioSink might be accessing AudioQueue
|
||||
// Stop the audio thread. Otherwise, MediaSink might be accessing AudioQueue
|
||||
// outside of the decoder monitor while we are clearing the queue and causes
|
||||
// crash for no samples to be popped.
|
||||
StopAudioSink();
|
||||
StopDecodedStream();
|
||||
StopMediaSink();
|
||||
|
||||
mVideoFrameEndTime = -1;
|
||||
mDecodedVideoEndTime = -1;
|
||||
@ -2585,11 +2552,7 @@ int64_t MediaDecoderStateMachine::GetClock(TimeStamp* aTimeStamp) const
|
||||
if (!IsPlaying()) {
|
||||
clock_time = mPlayDuration;
|
||||
} else {
|
||||
if (mAudioCaptured) {
|
||||
clock_time = mStreamSink->GetPosition(&t);
|
||||
} else {
|
||||
clock_time = mAudioSink->GetPosition(&t);
|
||||
}
|
||||
clock_time = mMediaSink->GetPosition(&t);
|
||||
NS_ASSERTION(GetMediaTime() <= clock_time, "Clock should go forwards.");
|
||||
}
|
||||
if (aTimeStamp) {
|
||||
@ -2879,9 +2842,7 @@ void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
mPlayStartTime = aTimeStamp;
|
||||
|
||||
mAudioSink->SetPlaying(!mPlayStartTime.IsNull());
|
||||
mStreamSink->SetPlaying(!mPlayStartTime.IsNull());
|
||||
mMediaSink->SetPlaying(!mPlayStartTime.IsNull());
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder()
|
||||
@ -2959,7 +2920,7 @@ MediaDecoderStateMachine::LogicalPlaybackRateChanged()
|
||||
}
|
||||
|
||||
mPlaybackRate = mLogicalPlaybackRate;
|
||||
mAudioSink->SetPlaybackRate(mPlaybackRate);
|
||||
mMediaSink->SetPlaybackRate(mPlaybackRate);
|
||||
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
@ -2968,7 +2929,7 @@ void MediaDecoderStateMachine::PreservesPitchChanged()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
mAudioSink->SetPreservesPitch(mPreservesPitch);
|
||||
mMediaSink->SetPreservesPitch(mPreservesPitch);
|
||||
}
|
||||
|
||||
bool MediaDecoderStateMachine::IsShutdown()
|
||||
@ -2982,33 +2943,33 @@ MediaDecoderStateMachine::AudioEndTime() const
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
AssertCurrentThreadInMonitor();
|
||||
if (mAudioSink->IsStarted()) {
|
||||
return mAudioSink->GetEndTime(TrackInfo::kAudioTrack);
|
||||
} else if (mAudioCaptured) {
|
||||
return mStreamSink->GetEndTime(TrackInfo::kAudioTrack);
|
||||
if (mMediaSink->IsStarted()) {
|
||||
return mMediaSink->GetEndTime(TrackInfo::kAudioTrack);
|
||||
}
|
||||
MOZ_ASSERT(!HasAudio());
|
||||
return -1;
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::OnAudioSinkComplete()
|
||||
void MediaDecoderStateMachine::OnMediaSinkComplete()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
|
||||
|
||||
mAudioSinkPromise.Complete();
|
||||
mAudioCompleted = true;
|
||||
mMediaSinkPromise.Complete();
|
||||
// Set true only when we have audio.
|
||||
mAudioCompleted = mInfo.HasAudio();
|
||||
// To notify PlaybackEnded as soon as possible.
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::OnAudioSinkError()
|
||||
void MediaDecoderStateMachine::OnMediaSinkError()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
|
||||
|
||||
mAudioSinkPromise.Complete();
|
||||
mAudioCompleted = true;
|
||||
mMediaSinkPromise.Complete();
|
||||
// Set true only when we have audio.
|
||||
mAudioCompleted = mInfo.HasAudio();
|
||||
|
||||
// Make the best effort to continue playback when there is video.
|
||||
if (HasVideo()) {
|
||||
@ -3021,31 +2982,41 @@ void MediaDecoderStateMachine::OnAudioSinkError()
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnDecodedStreamFinish()
|
||||
MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
MOZ_ASSERT(mAudioCaptured, "Audio should be captured.");
|
||||
|
||||
mDecodedStreamPromise.Complete();
|
||||
if (mInfo.HasAudio()) {
|
||||
mAudioCompleted = true;
|
||||
if (aCaptured == mAudioCaptured) {
|
||||
return;
|
||||
}
|
||||
// To notify PlaybackEnded as soon as possible.
|
||||
|
||||
// Backup current playback parameters.
|
||||
MediaSink::PlaybackParams params = mMediaSink->GetPlaybackParams();
|
||||
|
||||
// Stop and shut down the existing sink.
|
||||
StopMediaSink();
|
||||
mMediaSink->Shutdown();
|
||||
|
||||
// Create a new sink according to whether audio is captured.
|
||||
// TODO: We can't really create a new DecodedStream until OutputStreamManager
|
||||
// is extracted. It is tricky that the implementation of DecodedStream
|
||||
// happens to allow reuse after shutdown without creating a new one.
|
||||
mMediaSink = aCaptured ? mStreamSink : CreateAudioSink();
|
||||
|
||||
// Restore playback parameters.
|
||||
mMediaSink->SetPlaybackParams(params);
|
||||
|
||||
// Start the sink if we are already playing. Otherwise it will be
|
||||
// handled in MaybeStartPlayback().
|
||||
if (IsPlaying()) {
|
||||
StartMediaSink();
|
||||
}
|
||||
|
||||
mAudioCaptured = aCaptured;
|
||||
ScheduleStateMachine();
|
||||
}
|
||||
|
||||
void
|
||||
MediaDecoderStateMachine::OnDecodedStreamError()
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
MOZ_ASSERT(mAudioCaptured, "Audio should be captured.");
|
||||
|
||||
mDecodedStreamPromise.Complete();
|
||||
DecodeError();
|
||||
}
|
||||
|
||||
uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
||||
{
|
||||
MOZ_ASSERT(OnTaskQueue());
|
||||
@ -3055,55 +3026,15 @@ uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
||||
: std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::DispatchAudioCaptured()
|
||||
{
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
MOZ_ASSERT(self->OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
|
||||
if (!self->mAudioCaptured) {
|
||||
// Stop the audio sink if it's running.
|
||||
self->StopAudioSink();
|
||||
self->mAudioCaptured = true;
|
||||
// Start DecodedStream if we are already playing. Otherwise it will be
|
||||
// handled in MaybeStartPlayback().
|
||||
if (self->IsPlaying()) {
|
||||
self->StartDecodedStream();
|
||||
}
|
||||
self->ScheduleStateMachine();
|
||||
}
|
||||
});
|
||||
OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::DispatchAudioUncaptured()
|
||||
{
|
||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([self] () -> void
|
||||
{
|
||||
MOZ_ASSERT(self->OnTaskQueue());
|
||||
ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor());
|
||||
if (self->mAudioCaptured) {
|
||||
self->StopDecodedStream();
|
||||
// Start again the audio sink.
|
||||
self->mAudioCaptured = false;
|
||||
if (self->IsPlaying()) {
|
||||
self->StartAudioSink();
|
||||
}
|
||||
self->ScheduleStateMachine();
|
||||
}
|
||||
});
|
||||
OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
|
||||
bool aFinishWhenEnded)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
|
||||
mStreamSink->AddOutput(aStream, aFinishWhenEnded);
|
||||
DispatchAudioCaptured();
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<bool>(
|
||||
this, &MediaDecoderStateMachine::SetAudioCaptured, true);
|
||||
OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
|
||||
void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
|
||||
@ -3112,7 +3043,9 @@ void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
|
||||
DECODER_LOG("RemoveOutputStream=%p!", aStream);
|
||||
mStreamSink->RemoveOutput(aStream);
|
||||
if (!mStreamSink->HasConsumers()) {
|
||||
DispatchAudioUncaptured();
|
||||
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<bool>(
|
||||
this, &MediaDecoderStateMachine::SetAudioCaptured, false);
|
||||
OwnerThread()->Dispatch(r.forget());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,8 +167,7 @@ private:
|
||||
// constructor immediately after the task queue is created.
|
||||
void InitializationTask();
|
||||
|
||||
void DispatchAudioCaptured();
|
||||
void DispatchAudioUncaptured();
|
||||
void SetAudioCaptured(bool aCaptured);
|
||||
|
||||
void Shutdown();
|
||||
public:
|
||||
@ -489,19 +488,17 @@ protected:
|
||||
// state machine thread.
|
||||
void UpdateRenderedVideoFrames();
|
||||
|
||||
// Stops the audio sink and shut it down.
|
||||
media::MediaSink* CreateAudioSink();
|
||||
|
||||
// Stops the media sink and shut it down.
|
||||
// The decoder monitor must be held with exactly one lock count.
|
||||
// Called on the state machine thread.
|
||||
void StopAudioSink();
|
||||
void StopMediaSink();
|
||||
|
||||
// Create and start the audio sink.
|
||||
// Create and start the media sink.
|
||||
// The decoder monitor must be held with exactly one lock count.
|
||||
// Called on the state machine thread.
|
||||
void StartAudioSink();
|
||||
|
||||
void StopDecodedStream();
|
||||
|
||||
void StartDecodedStream();
|
||||
void StartMediaSink();
|
||||
|
||||
// Notification method invoked when mPlayState changes.
|
||||
void PlayStateChanged();
|
||||
@ -648,16 +645,12 @@ protected:
|
||||
void SetPlayStartTime(const TimeStamp& aTimeStamp);
|
||||
|
||||
private:
|
||||
// Resolved by the AudioSink to signal that all outstanding work is complete
|
||||
// Resolved by the MediaSink to signal that all outstanding work is complete
|
||||
// and the sink is shutting down.
|
||||
void OnAudioSinkComplete();
|
||||
void OnMediaSinkComplete();
|
||||
|
||||
// Rejected by the AudioSink to signal errors.
|
||||
void OnAudioSinkError();
|
||||
|
||||
void OnDecodedStreamFinish();
|
||||
|
||||
void OnDecodedStreamError();
|
||||
// Rejected by the MediaSink to signal errors.
|
||||
void OnMediaSinkError();
|
||||
|
||||
// Return true if the video decoder's decode speed can not catch up the
|
||||
// play time.
|
||||
@ -977,15 +970,15 @@ private:
|
||||
// Media Fragment end time in microseconds. Access controlled by decoder monitor.
|
||||
int64_t mFragmentEndTime;
|
||||
|
||||
// The audio sink resource. Used on the state machine thread.
|
||||
nsRefPtr<media::MediaSink> mAudioSink;
|
||||
// The media sink resource. Used on the state machine thread.
|
||||
nsRefPtr<media::MediaSink> mMediaSink;
|
||||
|
||||
// The reader, don't call its methods with the decoder monitor held.
|
||||
// This is created in the state machine's constructor.
|
||||
nsRefPtr<MediaDecoderReader> mReader;
|
||||
|
||||
// The end time of the last audio frame that's been pushed onto the audio sink
|
||||
// or DecodedStream in microseconds. This will approximately be the end time
|
||||
// The end time of the last audio frame that's been pushed onto the media sink
|
||||
// in microseconds. This will approximately be the end time
|
||||
// of the audio stream, unless another frame is pushed to the hardware.
|
||||
int64_t AudioEndTime() const;
|
||||
|
||||
@ -1270,8 +1263,7 @@ private:
|
||||
// Media data resource from the decoder.
|
||||
nsRefPtr<MediaResource> mResource;
|
||||
|
||||
MozPromiseRequestHolder<GenericPromise> mAudioSinkPromise;
|
||||
MozPromiseRequestHolder<GenericPromise> mDecodedStreamPromise;
|
||||
MozPromiseRequestHolder<GenericPromise> mMediaSinkPromise;
|
||||
|
||||
MediaEventListener mAudioQueueListener;
|
||||
MediaEventListener mVideoQueueListener;
|
||||
|
@ -12,7 +12,7 @@
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Turn off the authentication dialog blocking for this test.
|
||||
SpecialPowers.setIntPref("network.auth.allow-subresource-auth", 2)
|
||||
SpecialPowers.setIntPref("network.auth.subresource-http-auth-allow", 2)
|
||||
|
||||
var tests = [
|
||||
// Not the same origin no CORS asked for, should have silence
|
||||
|
@ -36,6 +36,9 @@
|
||||
#include "WorkerPrivate.h"
|
||||
#include "WorkerRunnable.h"
|
||||
#include "xpcpublic.h"
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "nsExceptionHandler.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -536,10 +539,10 @@ Promise::JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
|
||||
PromiseCallback::Task task = static_cast<PromiseCallback::Task>(v.toInt32());
|
||||
|
||||
if (task == PromiseCallback::Resolve) {
|
||||
promise->MaybeResolveInternal(aCx, args.get(0));
|
||||
if (!promise->CaptureStack(aCx, promise->mFullfillmentStack)) {
|
||||
return false;
|
||||
}
|
||||
promise->MaybeResolveInternal(aCx, args.get(0));
|
||||
} else {
|
||||
promise->MaybeRejectInternal(aCx, args.get(0));
|
||||
if (!promise->CaptureStack(aCx, promise->mRejectionStack)) {
|
||||
@ -1342,6 +1345,29 @@ Promise::RejectInternal(JSContext* aCx,
|
||||
void
|
||||
Promise::Settle(JS::Handle<JS::Value> aValue, PromiseState aState)
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
if (!mGlobal && mFullfillmentStack) {
|
||||
AutoJSAPI jsapi;
|
||||
jsapi.Init();
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::RootedObject stack(cx, mFullfillmentStack);
|
||||
JSAutoCompartment ac(cx, stack);
|
||||
JS::RootedString stackJSString(cx);
|
||||
if (JS::BuildStackString(cx, stack, &stackJSString)) {
|
||||
nsAutoJSString stackString;
|
||||
if (stackString.init(cx, stackJSString)) {
|
||||
// Put the string in the crash report here, since we're about to crash
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("cced_promise_stack"),
|
||||
NS_ConvertUTF16toUTF8(stackString));
|
||||
} else {
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
} else {
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mGlobal->IsDying()) {
|
||||
return;
|
||||
}
|
||||
|
@ -628,7 +628,6 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
||||
|
||||
// The "Access-Control-Allow-Headers" header contains a comma separated
|
||||
// list of header names.
|
||||
headerVal.Truncate();
|
||||
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
|
||||
headerVal);
|
||||
nsTArray<nsCString> headers;
|
||||
@ -1130,7 +1129,6 @@ nsCORSPreflightListener::AddResultToCache(nsIRequest *aRequest)
|
||||
|
||||
// The "Access-Control-Allow-Methods" header contains a comma separated
|
||||
// list of method names.
|
||||
headerVal.Truncate();
|
||||
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
|
||||
headerVal);
|
||||
|
||||
@ -1161,7 +1159,6 @@ nsCORSPreflightListener::AddResultToCache(nsIRequest *aRequest)
|
||||
|
||||
// The "Access-Control-Allow-Headers" header contains a comma separated
|
||||
// list of method names.
|
||||
headerVal.Truncate();
|
||||
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
|
||||
headerVal);
|
||||
|
||||
|
28
dom/system/gonk/GeolocationUtil.cpp
Normal file
28
dom/system/gonk/GeolocationUtil.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GeolocationUtil.h"
|
||||
|
||||
double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon)
|
||||
{
|
||||
// Use spherical law of cosines to calculate difference
|
||||
// Not quite as correct as the Haversine but simpler and cheaper
|
||||
const double radsInDeg = M_PI / 180.0;
|
||||
const double rNewLat = aLat * radsInDeg;
|
||||
const double rNewLon = aLon * radsInDeg;
|
||||
const double rOldLat = aLastLat * radsInDeg;
|
||||
const double rOldLon = aLastLon * radsInDeg;
|
||||
// WGS84 equatorial radius of earth = 6378137m
|
||||
double cosDelta = (sin(rNewLat) * sin(rOldLat)) +
|
||||
(cos(rNewLat) * cos(rOldLat) * cos(rOldLon - rNewLon));
|
||||
if (cosDelta > 1.0) {
|
||||
cosDelta = 1.0;
|
||||
} else if (cosDelta < -1.0) {
|
||||
cosDelta = -1.0;
|
||||
}
|
||||
return acos(cosDelta) * 6378137;
|
||||
}
|
||||
|
13
dom/system/gonk/GeolocationUtil.h
Normal file
13
dom/system/gonk/GeolocationUtil.h
Normal file
@ -0,0 +1,13 @@
|
||||
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef GEOLOCATIONUTIL_H
|
||||
#define GEOLOCATIONUTIL_H
|
||||
|
||||
double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon);
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include <pthread.h>
|
||||
#include <hardware/gps.h>
|
||||
|
||||
#include "GeolocationUtil.h"
|
||||
#include "mozstumbler/MozStumbler.h"
|
||||
#include "mozilla/Constants.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
@ -88,71 +90,6 @@ AGpsCallbacks GonkGPSGeolocationProvider::mAGPSCallbacks;
|
||||
AGpsRilCallbacks GonkGPSGeolocationProvider::mAGPSRILCallbacks;
|
||||
#endif // MOZ_B2G_RIL
|
||||
|
||||
double CalculateDeltaInMeter(double aLat, double aLon, double aLastLat, double aLastLon)
|
||||
{
|
||||
// Use spherical law of cosines to calculate difference
|
||||
// Not quite as correct as the Haversine but simpler and cheaper
|
||||
const double radsInDeg = M_PI / 180.0;
|
||||
const double rNewLat = aLat * radsInDeg;
|
||||
const double rNewLon = aLon * radsInDeg;
|
||||
const double rOldLat = aLastLat * radsInDeg;
|
||||
const double rOldLon = aLastLon * radsInDeg;
|
||||
// WGS84 equatorial radius of earth = 6378137m
|
||||
double cosDelta = (sin(rNewLat) * sin(rOldLat)) +
|
||||
(cos(rNewLat) * cos(rOldLat) * cos(rOldLon - rNewLon));
|
||||
if (cosDelta > 1.0) {
|
||||
cosDelta = 1.0;
|
||||
} else if (cosDelta < -1.0) {
|
||||
cosDelta = -1.0;
|
||||
}
|
||||
return acos(cosDelta) * 6378137;
|
||||
}
|
||||
|
||||
class RequestCellInfoEvent : public nsRunnable {
|
||||
public:
|
||||
RequestCellInfoEvent(StumblerInfo *callback)
|
||||
: mRequestCallback(callback)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Get Cell Info
|
||||
nsCOMPtr<nsIMobileConnectionService> service =
|
||||
do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
|
||||
|
||||
if (!service) {
|
||||
nsContentUtils::LogMessageToConsole("Stumbler-can not get nsIMobileConnectionService \n");
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIMobileConnection> connection;
|
||||
uint32_t numberOfRilServices = 1, cellInfoNum = 0;
|
||||
|
||||
service->GetNumItems(&numberOfRilServices);
|
||||
for (uint32_t rilNum = 0; rilNum < numberOfRilServices; rilNum++) {
|
||||
service->GetItemByServiceId(rilNum /* Client Id */, getter_AddRefs(connection));
|
||||
if (!connection) {
|
||||
nsContentUtils::LogMessageToConsole("Stumbler-can not get nsIMobileConnection by ServiceId %d \n", rilNum);
|
||||
} else {
|
||||
cellInfoNum++;
|
||||
connection->GetCellInfoList(mRequestCallback);
|
||||
}
|
||||
}
|
||||
mRequestCallback->SetCellInfoResponsesExpected(cellInfoNum);
|
||||
|
||||
// Get Wifi AP Info
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1");
|
||||
nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir);
|
||||
if (!wifi) {
|
||||
mRequestCallback->SetWifiInfoResponseReceived();
|
||||
nsContentUtils::LogMessageToConsole("Stumbler-can not get nsIWifi interface\n");
|
||||
return NS_OK;
|
||||
}
|
||||
wifi->GetWifiScanResults(mRequestCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<StumblerInfo> mRequestCallback;
|
||||
};
|
||||
|
||||
void
|
||||
GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
|
||||
@ -211,35 +148,7 @@ GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
|
||||
nsRefPtr<UpdateLocationEvent> event = new UpdateLocationEvent(somewhere);
|
||||
NS_DispatchToMainThread(event);
|
||||
|
||||
const double kMinChangeInMeters = 30;
|
||||
static int64_t lastTime_ms = 0;
|
||||
static double sLastLat = 0;
|
||||
static double sLastLon = 0;
|
||||
double delta = -1.0;
|
||||
int64_t timediff = (PR_Now() / PR_USEC_PER_MSEC) - lastTime_ms;
|
||||
|
||||
if (0 != sLastLon || 0 != sLastLat) {
|
||||
delta = CalculateDeltaInMeter(location->latitude, location->longitude, sLastLat, sLastLon);
|
||||
}
|
||||
if (gDebug_isLoggingEnabled) {
|
||||
nsContentUtils::LogMessageToConsole("Stumbler-Location. [%f , %f] time_diff:%lld, delta : %f\n",
|
||||
location->longitude, location->latitude, timediff, delta);
|
||||
}
|
||||
|
||||
// Consecutive GPS locations must be 30 meters and 3 seconds apart
|
||||
if (lastTime_ms == 0 || ((timediff >= STUMBLE_INTERVAL_MS) && (delta > kMinChangeInMeters))){
|
||||
lastTime_ms = (PR_Now() / PR_USEC_PER_MSEC);
|
||||
sLastLat = location->latitude;
|
||||
sLastLon = location->longitude;
|
||||
nsRefPtr<StumblerInfo> requestCallback = new StumblerInfo(somewhere);
|
||||
nsRefPtr<RequestCellInfoEvent> runnable = new RequestCellInfoEvent(requestCallback);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
} else {
|
||||
if (gDebug_isLoggingEnabled) {
|
||||
nsContentUtils::LogMessageToConsole(
|
||||
"Stumbler-GPS locations less than 30 meters and 3 seconds. Ignore!\n");
|
||||
}
|
||||
}
|
||||
MozStumble(somewhere);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -33,6 +33,7 @@ XPIDL_SOURCES += [
|
||||
XPIDL_MODULE = 'dom_system_gonk'
|
||||
|
||||
EXPORTS += [
|
||||
'GeolocationUtil.h',
|
||||
'GonkGPSGeolocationProvider.h',
|
||||
'mozstumbler/MozStumbler.h',
|
||||
'nsVolume.h',
|
||||
@ -43,6 +44,7 @@ UNIFIED_SOURCES += [
|
||||
'AudioManager.cpp',
|
||||
'AutoMounter.cpp',
|
||||
'AutoMounterSetting.cpp',
|
||||
'GeolocationUtil.cpp',
|
||||
'GonkGPSGeolocationProvider.cpp',
|
||||
'MozMtpDatabase.cpp',
|
||||
'MozMtpServer.cpp',
|
||||
|
@ -5,12 +5,22 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MozStumbler.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsGeoPosition.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "StumblerLogging.h"
|
||||
#include "WriteStumbleOnThread.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "../GeolocationUtil.h"
|
||||
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIMobileConnectionInfo.h"
|
||||
#include "nsIMobileConnectionService.h"
|
||||
#include "nsIMobileCellInfo.h"
|
||||
#include "nsIMobileNetworkInfo.h"
|
||||
#include "nsINetworkInterface.h"
|
||||
#include "nsIRadioInterfaceLayer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -18,6 +28,101 @@ using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_ISUPPORTS(StumblerInfo, nsICellInfoListCallback, nsIWifiScanResultsReady)
|
||||
|
||||
class RequestCellInfoEvent : public nsRunnable {
|
||||
public:
|
||||
RequestCellInfoEvent(StumblerInfo *callback)
|
||||
: mRequestCallback(callback)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
// Get Cell Info
|
||||
nsCOMPtr<nsIMobileConnectionService> service =
|
||||
do_GetService(NS_MOBILE_CONNECTION_SERVICE_CONTRACTID);
|
||||
|
||||
if (!service) {
|
||||
STUMBLER_ERR("Stumbler-can not get nsIMobileConnectionService \n");
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIMobileConnection> connection;
|
||||
uint32_t numberOfRilServices = 1, cellInfoNum = 0;
|
||||
|
||||
service->GetNumItems(&numberOfRilServices);
|
||||
for (uint32_t rilNum = 0; rilNum < numberOfRilServices; rilNum++) {
|
||||
service->GetItemByServiceId(rilNum /* Client Id */, getter_AddRefs(connection));
|
||||
if (!connection) {
|
||||
STUMBLER_ERR("Stumbler-can not get nsIMobileConnection by ServiceId %d \n", rilNum);
|
||||
} else {
|
||||
cellInfoNum++;
|
||||
connection->GetCellInfoList(mRequestCallback);
|
||||
}
|
||||
}
|
||||
mRequestCallback->SetCellInfoResponsesExpected(cellInfoNum);
|
||||
|
||||
// Get Wifi AP Info
|
||||
nsCOMPtr<nsIInterfaceRequestor> ir = do_GetService("@mozilla.org/telephony/system-worker-manager;1");
|
||||
nsCOMPtr<nsIWifi> wifi = do_GetInterface(ir);
|
||||
if (!wifi) {
|
||||
mRequestCallback->SetWifiInfoResponseReceived();
|
||||
STUMBLER_ERR("Stumbler-can not get nsIWifi interface\n");
|
||||
return NS_OK;
|
||||
}
|
||||
wifi->GetWifiScanResults(mRequestCallback);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
nsRefPtr<StumblerInfo> mRequestCallback;
|
||||
};
|
||||
|
||||
void
|
||||
MozStumble(nsGeoPosition* position)
|
||||
{
|
||||
if (WriteStumbleOnThread::IsFileWaitingForUpload()) {
|
||||
nsCOMPtr<nsIEventTarget> target = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(target);
|
||||
// Knowing that file is waiting to upload, and no collection will take place,
|
||||
// just trigger the thread with an empty string.
|
||||
nsCOMPtr<nsIRunnable> event = new WriteStumbleOnThread(EmptyCString());
|
||||
target->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
|
||||
position->GetCoords(getter_AddRefs(coords));
|
||||
if (!coords) {
|
||||
return;
|
||||
}
|
||||
|
||||
double latitude, longitude;
|
||||
coords->GetLatitude(&latitude);
|
||||
coords->GetLongitude(&longitude);
|
||||
|
||||
const double kMinChangeInMeters = 30;
|
||||
static int64_t lastTime_ms = 0;
|
||||
static double sLastLat = 0;
|
||||
static double sLastLon = 0;
|
||||
double delta = -1.0;
|
||||
int64_t timediff = (PR_Now() / PR_USEC_PER_MSEC) - lastTime_ms;
|
||||
|
||||
if (0 != sLastLon || 0 != sLastLat) {
|
||||
delta = CalculateDeltaInMeter(latitude, longitude, sLastLat, sLastLon);
|
||||
}
|
||||
STUMBLER_DBG("Stumbler-Location. [%f , %f] time_diff:%lld, delta : %f\n",
|
||||
longitude, latitude, timediff, delta);
|
||||
|
||||
// Consecutive GPS locations must be 30 meters and 3 seconds apart
|
||||
if (lastTime_ms == 0 || ((timediff >= STUMBLE_INTERVAL_MS) && (delta > kMinChangeInMeters))){
|
||||
lastTime_ms = (PR_Now() / PR_USEC_PER_MSEC);
|
||||
sLastLat = latitude;
|
||||
sLastLon = longitude;
|
||||
nsRefPtr<StumblerInfo> requestCallback = new StumblerInfo(position);
|
||||
nsRefPtr<RequestCellInfoEvent> runnable = new RequestCellInfoEvent(requestCallback);
|
||||
NS_DispatchToMainThread(runnable);
|
||||
} else {
|
||||
STUMBLER_DBG("Stumbler-GPS locations less than 30 meters and 3 seconds. Ignore!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StumblerInfo::SetWifiInfoResponseReceived()
|
||||
{
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
class nsGeoPosition;
|
||||
|
||||
void MozStumble(nsGeoPosition* position);
|
||||
|
||||
class StumblerInfo final : public nsICellInfoListCallback,
|
||||
public nsIWifiScanResultsReady
|
||||
{
|
||||
|
@ -7,14 +7,15 @@
|
||||
#include "UploadStumbleRunnable.h"
|
||||
#include "StumblerLogging.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIURLFormatter.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIXMLHttpRequest.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
UploadStumbleRunnable::UploadStumbleRunnable(const nsACString& aUploadData)
|
||||
: mUploadData(aUploadData)
|
||||
UploadStumbleRunnable::UploadStumbleRunnable(nsIInputStream* aUploadData)
|
||||
: mUploadInputStream(aUploadData)
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,7 +37,7 @@ UploadStumbleRunnable::Upload()
|
||||
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance("@mozilla.org/variant;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = variant->SetAsACString(mUploadData);
|
||||
rv = variant->SetAsISupports(mUploadInputStream);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIXMLHttpRequest> xhr = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &rv);
|
||||
@ -63,13 +64,13 @@ UploadStumbleRunnable::Upload()
|
||||
rv = xhr->Open(NS_LITERAL_CSTRING("POST"), NS_ConvertUTF16toUTF8(url), false, EmptyString(), EmptyString());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
xhr->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), NS_LITERAL_CSTRING("application/json"));
|
||||
xhr->SetRequestHeader(NS_LITERAL_CSTRING("Content-Type"), NS_LITERAL_CSTRING("gzip"));
|
||||
xhr->SetMozBackgroundRequest(true);
|
||||
// 60s timeout
|
||||
xhr->SetTimeout(60 * 1000);
|
||||
|
||||
nsCOMPtr<EventTarget> target(do_QueryInterface(xhr));
|
||||
nsRefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr, mUploadData.Length());
|
||||
nsRefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr);
|
||||
|
||||
const char* const sEventStrings[] = {
|
||||
// nsIXMLHttpRequestEventTarget event types
|
||||
@ -93,8 +94,8 @@ UploadStumbleRunnable::Upload()
|
||||
|
||||
NS_IMPL_ISUPPORTS(UploadEventListener, nsIDOMEventListener)
|
||||
|
||||
UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR, int64_t aFileSize)
|
||||
: mXHR(aXHR), mFileSize(aFileSize)
|
||||
UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR)
|
||||
: mXHR(aXHR)
|
||||
{
|
||||
}
|
||||
|
||||
@ -109,7 +110,7 @@ UploadEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
}
|
||||
|
||||
if (type.EqualsLiteral("load")) {
|
||||
STUMBLER_DBG("Got load Event : size %lld", mFileSize);
|
||||
STUMBLER_DBG("Got load Event\n");
|
||||
} else if (type.EqualsLiteral("error") && mXHR) {
|
||||
STUMBLER_ERR("Upload Error");
|
||||
} else {
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
class nsIXMLHttpRequest;
|
||||
class nsIInputStream;
|
||||
|
||||
/*
|
||||
This runnable is managed by WriteStumbleOnThread only, see that class
|
||||
@ -19,12 +20,12 @@ class nsIXMLHttpRequest;
|
||||
class UploadStumbleRunnable final : public nsRunnable
|
||||
{
|
||||
public:
|
||||
explicit UploadStumbleRunnable(const nsACString& aUploadData);
|
||||
explicit UploadStumbleRunnable(nsIInputStream* aUploadInputStream);
|
||||
|
||||
NS_IMETHOD Run() override;
|
||||
private:
|
||||
virtual ~UploadStumbleRunnable() {}
|
||||
const nsCString mUploadData;
|
||||
nsCOMPtr<nsIInputStream> mUploadInputStream;
|
||||
nsresult Upload();
|
||||
};
|
||||
|
||||
@ -32,7 +33,7 @@ private:
|
||||
class UploadEventListener : public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
UploadEventListener(nsIXMLHttpRequest* aXHR, int64_t aFileSize);
|
||||
UploadEventListener(nsIXMLHttpRequest* aXHR);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
@ -40,7 +41,6 @@ public:
|
||||
protected:
|
||||
virtual ~UploadEventListener() {}
|
||||
nsCOMPtr<nsIXMLHttpRequest> mXHR;
|
||||
int64_t mFileSize;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -17,12 +17,12 @@
|
||||
#define ONEDAY_IN_MSEC (24 * 60 * 60 * 1000)
|
||||
#define MAX_UPLOAD_ATTEMPTS 20
|
||||
|
||||
mozilla::Atomic<bool> WriteStumbleOnThread::sIsUploading(false);
|
||||
mozilla::Atomic<bool> WriteStumbleOnThread::sIsFileWaitingForUpload(false);
|
||||
mozilla::Atomic<bool> WriteStumbleOnThread::sIsAlreadyRunning(false);
|
||||
WriteStumbleOnThread::UploadFreqGuard WriteStumbleOnThread::sUploadFreqGuard = {0};
|
||||
|
||||
#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json")
|
||||
#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json")
|
||||
#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json.gz")
|
||||
#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json.gz")
|
||||
#define OUTPUT_DIR NS_LITERAL_CSTRING("mozstumbler")
|
||||
|
||||
class DeleteRunnable : public nsRunnable
|
||||
@ -42,7 +42,8 @@ class DeleteRunnable : public nsRunnable
|
||||
tmpFile->Remove(true);
|
||||
}
|
||||
// critically, this sets this flag to false so writing can happen again
|
||||
WriteStumbleOnThread::sIsUploading = false;
|
||||
WriteStumbleOnThread::sIsAlreadyRunning = false;
|
||||
WriteStumbleOnThread::sIsFileWaitingForUpload = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -50,11 +51,17 @@ class DeleteRunnable : public nsRunnable
|
||||
~DeleteRunnable() {}
|
||||
};
|
||||
|
||||
bool
|
||||
WriteStumbleOnThread::IsFileWaitingForUpload()
|
||||
{
|
||||
return sIsFileWaitingForUpload;
|
||||
}
|
||||
|
||||
void
|
||||
WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
|
||||
{
|
||||
if (!deleteUploadFile) {
|
||||
sIsUploading = false;
|
||||
sIsAlreadyRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -64,15 +71,6 @@ WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
|
||||
target->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
#define DUMP(o, s) \
|
||||
do { \
|
||||
const char* s2 = (s); \
|
||||
uint32_t dummy; \
|
||||
nsresult rv = (o)->Write((s2), strlen(s2), &dummy); \
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) \
|
||||
STUMBLER_ERR("write err"); \
|
||||
} while (0)
|
||||
|
||||
void
|
||||
WriteStumbleOnThread::WriteJSON(Partition aPart)
|
||||
{
|
||||
@ -87,10 +85,10 @@ WriteStumbleOnThread::WriteJSON(Partition aPart)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFileOutputStream> ostream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
|
||||
rv = ostream->Init(tmpFile, PR_WRONLY | PR_APPEND, 0666, 0);
|
||||
nsRefPtr<nsGZFileWriter> gzWriter = new nsGZFileWriter(nsGZFileWriter::Append);
|
||||
rv = gzWriter->Init(tmpFile);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
STUMBLER_ERR("Open a file for stumble failed");
|
||||
STUMBLER_ERR("gzWriter init failed");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -105,8 +103,8 @@ WriteStumbleOnThread::WriteJSON(Partition aPart)
|
||||
|
||||
// Need to add "]}" after the last item
|
||||
if (aPart == Partition::End) {
|
||||
DUMP(ostream, "]}");
|
||||
rv = ostream->Close();
|
||||
gzWriter->Write("]}");
|
||||
rv = gzWriter->Finish();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
STUMBLER_ERR("ostream finish failed");
|
||||
}
|
||||
@ -136,14 +134,14 @@ WriteStumbleOnThread::WriteJSON(Partition aPart)
|
||||
|
||||
// Need to add "{items:[" before the first item
|
||||
if (aPart == Partition::Begining) {
|
||||
DUMP(ostream, "{\"items\":[{");
|
||||
gzWriter->Write("{\"items\":[{");
|
||||
} else if (aPart == Partition::Middle) {
|
||||
DUMP(ostream, ",{");
|
||||
gzWriter->Write(",{");
|
||||
}
|
||||
DUMP(ostream, mDesc.get());
|
||||
gzWriter->Write(mDesc.get());
|
||||
// one item is ended with '}' (e.g. {item})
|
||||
DUMP(ostream, "}");
|
||||
rv = ostream->Close();
|
||||
gzWriter->Write("}");
|
||||
rv = gzWriter->Finish();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
STUMBLER_ERR("ostream finish failed");
|
||||
}
|
||||
@ -204,7 +202,9 @@ WriteStumbleOnThread::Run()
|
||||
|
||||
if (UploadFileStatus::NoFile != status) {
|
||||
if (UploadFileStatus::ExistsAndReadyToUpload == status) {
|
||||
sIsFileWaitingForUpload = true;
|
||||
Upload();
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
Partition partition = GetWritePosition();
|
||||
@ -215,6 +215,7 @@ WriteStumbleOnThread::Run()
|
||||
}
|
||||
}
|
||||
|
||||
sIsFileWaitingForUpload = false;
|
||||
sIsAlreadyRunning = false;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -259,11 +260,6 @@ WriteStumbleOnThread::Upload()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
bool b = sIsUploading.exchange(true);
|
||||
if (b) {
|
||||
return;
|
||||
}
|
||||
|
||||
time_t seconds = time(0);
|
||||
int day = seconds / (60 * 60 * 24);
|
||||
|
||||
@ -275,7 +271,7 @@ WriteStumbleOnThread::Upload()
|
||||
sUploadFreqGuard.attempts++;
|
||||
if (sUploadFreqGuard.attempts > MAX_UPLOAD_ATTEMPTS) {
|
||||
STUMBLER_ERR("Too many upload attempts today");
|
||||
sIsUploading = false;
|
||||
sIsAlreadyRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -286,32 +282,23 @@ WriteStumbleOnThread::Upload()
|
||||
rv = tmpFile->GetFileSize(&fileSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
STUMBLER_ERR("GetFileSize failed");
|
||||
sIsUploading = false;
|
||||
sIsAlreadyRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (fileSize <= 0) {
|
||||
sIsUploading = false;
|
||||
sIsAlreadyRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare json into nsIInputStream
|
||||
nsCOMPtr<nsIInputStream> inStream;
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile, -1, -1,
|
||||
nsIFileInputStream::DEFER_OPEN);
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile);
|
||||
if (NS_FAILED(rv)) {
|
||||
sIsUploading = false;
|
||||
sIsAlreadyRunning = false;
|
||||
return;
|
||||
}
|
||||
|
||||
nsCString bufStr;
|
||||
rv = NS_ReadInputStreamToString(inStream, bufStr, fileSize);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
sIsUploading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(bufStr);
|
||||
nsRefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(inStream);
|
||||
NS_DispatchToMainThread(uploader);
|
||||
}
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
class DeleteRunnable;
|
||||
|
||||
/*
|
||||
This class is the entry point to stumbling, in that it
|
||||
receives the location+cell+wifi string and writes it
|
||||
@ -43,10 +45,13 @@ public:
|
||||
NS_IMETHODIMP Run() override;
|
||||
|
||||
static void UploadEnded(bool deleteUploadFile);
|
||||
// Don't write while uploading is happening
|
||||
static mozilla::Atomic<bool> sIsUploading;
|
||||
|
||||
// Used externally to determine if cell+wifi scans should happen
|
||||
// (returns false for that case).
|
||||
static bool IsFileWaitingForUpload();
|
||||
|
||||
private:
|
||||
friend class DeleteRunnable;
|
||||
|
||||
enum class Partition {
|
||||
Begining,
|
||||
@ -71,6 +76,8 @@ private:
|
||||
// Only run one instance of this
|
||||
static mozilla::Atomic<bool> sIsAlreadyRunning;
|
||||
|
||||
static mozilla::Atomic<bool> sIsFileWaitingForUpload;
|
||||
|
||||
// Limit the upload attempts per day. If the device is rebooted
|
||||
// this resets the allowed attempts, which is acceptable.
|
||||
struct UploadFreqGuard {
|
||||
|
@ -27,7 +27,7 @@ interface PushManager {
|
||||
[ChromeOnly, Throws, Exposed=Window]
|
||||
void setPushManagerImpl(PushManagerImpl store);
|
||||
|
||||
[Throws]
|
||||
[Throws, UseCounter]
|
||||
Promise<PushSubscription> subscribe();
|
||||
[Throws]
|
||||
Promise<PushSubscription?> getSubscription();
|
||||
|
@ -14,7 +14,7 @@ interface Principal;
|
||||
interface PushSubscription
|
||||
{
|
||||
readonly attribute USVString endpoint;
|
||||
[Throws]
|
||||
[Throws, UseCounter]
|
||||
Promise<boolean> unsubscribe();
|
||||
jsonifier;
|
||||
|
||||
|
@ -1323,8 +1323,9 @@ bool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::Paste(int32_t aSelectionType)
|
||||
{
|
||||
if (!FireClipboardEvent(NS_PASTE, aSelectionType))
|
||||
if (!FireClipboardEvent(ePaste, aSelectionType)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get Clipboard Service
|
||||
nsresult rv;
|
||||
@ -1406,8 +1407,9 @@ NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
|
||||
{
|
||||
// Use an invalid value for the clipboard type as data comes from aTransferable
|
||||
// and we don't currently implement a way to put that in the data transfer yet.
|
||||
if (!FireClipboardEvent(NS_PASTE, nsIClipboard::kGlobalClipboard))
|
||||
if (!FireClipboardEvent(ePaste, nsIClipboard::kGlobalClipboard)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// handle transferable hooks
|
||||
nsCOMPtr<nsIDOMDocument> domdoc = GetDOMDocument();
|
||||
@ -1424,8 +1426,9 @@ NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
|
||||
//
|
||||
NS_IMETHODIMP nsHTMLEditor::PasteNoFormatting(int32_t aSelectionType)
|
||||
{
|
||||
if (!FireClipboardEvent(NS_PASTE, aSelectionType))
|
||||
if (!FireClipboardEvent(ePaste, aSelectionType)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ForceCompositionEnd();
|
||||
|
||||
|
@ -322,8 +322,9 @@ nsresult nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
||||
|
||||
NS_IMETHODIMP nsPlaintextEditor::Paste(int32_t aSelectionType)
|
||||
{
|
||||
if (!FireClipboardEvent(NS_PASTE, aSelectionType))
|
||||
if (!FireClipboardEvent(ePaste, aSelectionType)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Get Clipboard Service
|
||||
nsresult rv;
|
||||
@ -355,8 +356,9 @@ NS_IMETHODIMP nsPlaintextEditor::PasteTransferable(nsITransferable *aTransferabl
|
||||
{
|
||||
// Use an invalid value for the clipboard type as data comes from aTransferable
|
||||
// and we don't currently implement a way to put that in the data transfer yet.
|
||||
if (!FireClipboardEvent(NS_PASTE, -1))
|
||||
if (!FireClipboardEvent(ePaste, -1)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!IsModifiable())
|
||||
return NS_OK;
|
||||
|
@ -1173,7 +1173,7 @@ nsPlaintextEditor::FireClipboardEvent(EventMessage aEventMessage,
|
||||
int32_t aSelectionType,
|
||||
bool* aActionTaken)
|
||||
{
|
||||
if (aEventMessage == NS_PASTE) {
|
||||
if (aEventMessage == ePaste) {
|
||||
ForceCompositionEnd();
|
||||
}
|
||||
|
||||
@ -1198,7 +1198,7 @@ nsPlaintextEditor::FireClipboardEvent(EventMessage aEventMessage,
|
||||
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
||||
{
|
||||
bool actionTaken = false;
|
||||
if (FireClipboardEvent(NS_CUT, nsIClipboard::kGlobalClipboard, &actionTaken)) {
|
||||
if (FireClipboardEvent(eCut, nsIClipboard::kGlobalClipboard, &actionTaken)) {
|
||||
DeleteSelection(eNone, eStrip);
|
||||
}
|
||||
return actionTaken ? NS_OK : NS_ERROR_FAILURE;
|
||||
@ -1217,7 +1217,7 @@ NS_IMETHODIMP nsPlaintextEditor::CanCut(bool *aCanCut)
|
||||
NS_IMETHODIMP nsPlaintextEditor::Copy()
|
||||
{
|
||||
bool actionTaken = false;
|
||||
FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, &actionTaken);
|
||||
FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard, &actionTaken);
|
||||
|
||||
return actionTaken ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -629,6 +629,12 @@ FilterNodeSoftware::GetOutput(const IntRect &aRect)
|
||||
void
|
||||
FilterNodeSoftware::RequestRect(const IntRect &aRect)
|
||||
{
|
||||
if (mRequestedRect.Contains(aRect)) {
|
||||
// Bail out now. Otherwise pathological filters can spend time exponential
|
||||
// in the number of primitives, e.g. if each primitive takes the
|
||||
// previous primitive as its two inputs.
|
||||
return;
|
||||
}
|
||||
mRequestedRect = mRequestedRect.Union(aRect);
|
||||
RequestFromInputsForRect(aRect);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#ifndef gfx_src_DriverCrashGuard_h__
|
||||
#define gfx_src_DriverCrashGuard_h__
|
||||
|
||||
#include "gfxCore.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#include "nsIFile.h"
|
||||
|
@ -347,6 +347,12 @@ FilterCachedColorModels::WrapForColorModel(ColorModel aColorModel)
|
||||
return FilterWrappers::LinearRGBToSRGB(mDT, unpremultipliedOriginal);
|
||||
}
|
||||
|
||||
static const float identityMatrix[] =
|
||||
{ 1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0 };
|
||||
|
||||
// When aAmount == 0, the identity matrix is returned.
|
||||
// When aAmount == 1, aToMatrix is returned.
|
||||
// When aAmount > 1, an exaggerated version of aToMatrix is returned. This can
|
||||
@ -363,12 +369,6 @@ static void
|
||||
InterpolateFromIdentityMatrix(const float aToMatrix[20], float aAmount,
|
||||
float aOutMatrix[20])
|
||||
{
|
||||
static const float identityMatrix[] =
|
||||
{ 1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0 };
|
||||
|
||||
PodCopy(aOutMatrix, identityMatrix, 20);
|
||||
|
||||
float oneMinusAmount = 1 - aAmount;
|
||||
@ -392,12 +392,6 @@ static nsresult
|
||||
ComputeColorMatrix(uint32_t aColorMatrixType, const nsTArray<float>& aValues,
|
||||
float aOutMatrix[20])
|
||||
{
|
||||
static const float identityMatrix[] =
|
||||
{ 1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
0, 0, 1, 0, 0,
|
||||
0, 0, 0, 1, 0 };
|
||||
|
||||
// Luminance coefficients.
|
||||
static const float lumR = 0.2126f;
|
||||
static const float lumG = 0.7152f;
|
||||
@ -760,7 +754,8 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
||||
float colorMatrix[20];
|
||||
uint32_t type = atts.GetUint(eColorMatrixType);
|
||||
const nsTArray<float>& values = atts.GetFloats(eColorMatrixValues);
|
||||
if (NS_FAILED(ComputeColorMatrix(type, values, colorMatrix))) {
|
||||
if (NS_FAILED(ComputeColorMatrix(type, values, colorMatrix)) ||
|
||||
PodEqual(colorMatrix, identityMatrix)) {
|
||||
RefPtr<FilterNode> filter(aSources[0]);
|
||||
return filter.forget();
|
||||
}
|
||||
@ -954,11 +949,15 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
||||
RefPtr<FilterNode> filter;
|
||||
uint32_t op = atts.GetUint(eCompositeOperator);
|
||||
if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
|
||||
const nsTArray<float>& coefficients = atts.GetFloats(eCompositeCoefficients);
|
||||
static const float allZero[4] = { 0, 0, 0, 0 };
|
||||
filter = aDT->CreateFilter(FilterType::ARITHMETIC_COMBINE);
|
||||
if (!filter) {
|
||||
// All-zero coefficients sometimes occur in junk filters.
|
||||
if (!filter ||
|
||||
(coefficients.Length() == ArrayLength(allZero) &&
|
||||
PodEqual(coefficients.Elements(), allZero, ArrayLength(allZero)))) {
|
||||
return nullptr;
|
||||
}
|
||||
const nsTArray<float>& coefficients = atts.GetFloats(eCompositeCoefficients);
|
||||
filter->SetAttribute(ATT_ARITHMETIC_COMBINE_COEFFICIENTS,
|
||||
coefficients.Elements(), coefficients.Length());
|
||||
filter->SetInput(IN_ARITHMETIC_COMBINE_IN, aSources[0]);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#endif
|
||||
|
||||
#include <string.h> // for memset
|
||||
#include "gfxCore.h" // for NS_GFX
|
||||
#include "mozilla/Scoped.h" // for SCOPED_TEMPLATE
|
||||
|
||||
namespace mozilla {
|
||||
@ -91,7 +90,7 @@ SCOPED_TEMPLATE(ScopedXFree, ScopedXFreePtrTraits)
|
||||
* This class is not thread-safe at all. It is assumed that only one thread is using any ScopedXErrorHandler's. Given that it's
|
||||
* not used on Mac, it should be easy to make it thread-safe by using thread-local storage with __thread.
|
||||
*/
|
||||
class NS_GFX ScopedXErrorHandler
|
||||
class ScopedXErrorHandler
|
||||
{
|
||||
public:
|
||||
// trivial wrapper around XErrorEvent, just adding ctor initializing by zero.
|
||||
|
@ -1,15 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef gfxCore_h__
|
||||
#define gfxCore_h__
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
#define NS_GFX
|
||||
#define NS_GFX_(type) type
|
||||
#define NS_GFX_STATIC_MEMBER_(type) type
|
||||
|
||||
#endif
|
@ -6,7 +6,6 @@
|
||||
#ifndef gfxCrashReporterUtils_h__
|
||||
#define gfxCrashReporterUtils_h__
|
||||
|
||||
#include "gfxCore.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -21,7 +20,7 @@ namespace mozilla {
|
||||
* have many exit points. We don't want to encourage having function with many exit points.
|
||||
* It just happens that our graphics features initialization functions are like that.
|
||||
*/
|
||||
class NS_GFX ScopedGfxFeatureReporter
|
||||
class ScopedGfxFeatureReporter
|
||||
{
|
||||
public:
|
||||
explicit ScopedGfxFeatureReporter(const char *aFeature, bool force = false)
|
||||
|
@ -16,7 +16,6 @@ DEFINES['MOZ_APP_VERSION'] = '"%s"' % CONFIG['MOZ_APP_VERSION']
|
||||
EXPORTS += [
|
||||
'DriverCrashGuard.h',
|
||||
'FilterSupport.h',
|
||||
'gfxCore.h',
|
||||
'gfxCrashReporterUtils.h',
|
||||
'gfxTelemetry.h',
|
||||
'nsBoundingMetrics.h',
|
||||
|
@ -75,8 +75,7 @@ static int ComponentValue(const char16_t* aColorSpec, int aLen, int color, int d
|
||||
return component;
|
||||
}
|
||||
|
||||
NS_GFX_(bool) NS_HexToRGB(const nsAString& aColorSpec,
|
||||
nscolor* aResult)
|
||||
bool NS_HexToRGB(const nsAString& aColorSpec, nscolor* aResult)
|
||||
{
|
||||
const char16_t* buffer = aColorSpec.BeginReading();
|
||||
|
||||
@ -121,7 +120,7 @@ NS_GFX_(bool) NS_HexToRGB(const nsAString& aColorSpec,
|
||||
|
||||
// This implements part of the algorithm for legacy behavior described in
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/complete/common-microsyntaxes.html#rules-for-parsing-a-legacy-color-value
|
||||
NS_GFX_(bool) NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
|
||||
bool NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
|
||||
{
|
||||
if (aColorSpec.EqualsLiteral("transparent")) {
|
||||
return false;
|
||||
@ -185,7 +184,7 @@ NS_GFX_(bool) NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_GFX_(bool) NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
|
||||
bool NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
|
||||
{
|
||||
if (!gColorTable) return false;
|
||||
|
||||
@ -203,7 +202,7 @@ NS_GFX_(bool) NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
|
||||
|
||||
// Returns kColorNames, an array of all possible color names, and sets
|
||||
// *aSizeArray to the size of that array. Do NOT call free() on this array.
|
||||
NS_GFX_(const char * const *) NS_AllColorNames(size_t *aSizeArray)
|
||||
const char * const * NS_AllColorNames(size_t *aSizeArray)
|
||||
{
|
||||
*aSizeArray = ArrayLength(kColorNames);
|
||||
return kColorNames;
|
||||
@ -215,7 +214,7 @@ NS_GFX_(const char * const *) NS_AllColorNames(size_t *aSizeArray)
|
||||
#define MOZ_BLEND(target, bg, fg, fgalpha) \
|
||||
FAST_DIVIDE_BY_255(target, (bg)*(255-fgalpha) + (fg)*(fgalpha))
|
||||
|
||||
NS_GFX_(nscolor)
|
||||
nscolor
|
||||
NS_ComposeColors(nscolor aBG, nscolor aFG)
|
||||
{
|
||||
// This function uses colors that are non premultiplied alpha.
|
||||
@ -264,7 +263,7 @@ HSL_HueToRGB(float m1, float m2, float h)
|
||||
}
|
||||
|
||||
// The float parameters are all expected to be in the range 0-1
|
||||
NS_GFX_(nscolor)
|
||||
nscolor
|
||||
NS_HSL2RGB(float h, float s, float l)
|
||||
{
|
||||
uint8_t r, g, b;
|
||||
@ -281,7 +280,7 @@ NS_HSL2RGB(float h, float s, float l)
|
||||
return NS_RGB(r, g, b);
|
||||
}
|
||||
|
||||
NS_GFX_(const char*)
|
||||
const char*
|
||||
NS_RGBToColorName(nscolor aColor)
|
||||
{
|
||||
for (size_t idx = 0; idx < ArrayLength(kColors); ++idx) {
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint8_t, uint32_t
|
||||
#include "gfxCore.h" // for NS_GFX_
|
||||
#include "nscore.h" // for nsAString
|
||||
|
||||
class nsAString;
|
||||
@ -53,37 +52,37 @@ typedef uint32_t nscolor;
|
||||
// Translate a hex string to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
// This accepts only 3 or 6 digits
|
||||
NS_GFX_(bool) NS_HexToRGB(const nsAString& aBuf, nscolor* aResult);
|
||||
bool NS_HexToRGB(const nsAString& aBuf, nscolor* aResult);
|
||||
|
||||
// Compose one NS_RGB color onto another. The result is what
|
||||
// you get if you draw aFG on top of aBG with operator OVER.
|
||||
NS_GFX_(nscolor) NS_ComposeColors(nscolor aBG, nscolor aFG);
|
||||
nscolor NS_ComposeColors(nscolor aBG, nscolor aFG);
|
||||
|
||||
// Translate a hex string to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
// This version accepts 1 to 9 digits (missing digits are 0)
|
||||
NS_GFX_(bool) NS_LooseHexToRGB(const nsString& aBuf, nscolor* aResult);
|
||||
bool NS_LooseHexToRGB(const nsString& aBuf, nscolor* aResult);
|
||||
|
||||
// There is no function to translate a color to a hex string, because
|
||||
// the hex-string syntax does not support transparency.
|
||||
|
||||
// Translate a color name to a color. Return true if it parses ok,
|
||||
// otherwise return false.
|
||||
NS_GFX_(bool) NS_ColorNameToRGB(const nsAString& aBuf, nscolor* aResult);
|
||||
bool NS_ColorNameToRGB(const nsAString& aBuf, nscolor* aResult);
|
||||
|
||||
// Returns an array of all possible color names, and sets
|
||||
// *aSizeArray to the size of that array. Do NOT call |free()| on this array.
|
||||
NS_GFX_(const char * const *) NS_AllColorNames(size_t *aSizeArray);
|
||||
const char * const * NS_AllColorNames(size_t *aSizeArray);
|
||||
|
||||
// function to convert from HSL color space to RGB color space
|
||||
// the float parameters are all expected to be in the range 0-1
|
||||
NS_GFX_(nscolor) NS_HSL2RGB(float h, float s, float l);
|
||||
nscolor NS_HSL2RGB(float h, float s, float l);
|
||||
|
||||
// Return a color name for the given nscolor. If there is no color
|
||||
// name for it, returns null. If there are multiple possible color
|
||||
// names for the given color, the first one in nsColorNameList.h
|
||||
// (which is generally the first one in alphabetical order) will be
|
||||
// returned.
|
||||
NS_GFX_(const char*) NS_RGBToColorName(nscolor aColor);
|
||||
const char* NS_RGBToColorName(nscolor aColor);
|
||||
|
||||
#endif /* nsColor_h___ */
|
||||
|
@ -6,9 +6,8 @@
|
||||
#ifndef nsColorNames_h___
|
||||
#define nsColorNames_h___
|
||||
|
||||
#include "gfxCore.h"
|
||||
|
||||
class NS_GFX nsColorNames {
|
||||
class nsColorNames {
|
||||
public:
|
||||
static void AddRefTable(void);
|
||||
static void ReleaseTable(void);
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <stdint.h> // for uint8_t, uint16_t
|
||||
#include <sys/types.h> // for int16_t
|
||||
#include "gfxCore.h" // for NS_GFX
|
||||
#include "gfxFontFamilyList.h"
|
||||
#include "gfxFontFeatures.h"
|
||||
#include "nsAutoPtr.h" // for nsRefPtr
|
||||
@ -40,7 +39,7 @@ const uint8_t kGenericFont_cursive = 0x10;
|
||||
const uint8_t kGenericFont_fantasy = 0x20;
|
||||
|
||||
// Font structure.
|
||||
struct NS_GFX nsFont {
|
||||
struct nsFont {
|
||||
|
||||
// list of font families, either named or generic
|
||||
mozilla::FontFamilyList fontlist;
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "nsCoord.h"
|
||||
#include "nsPoint.h"
|
||||
#include "gfxCore.h"
|
||||
#include "mozilla/gfx/BaseMargin.h"
|
||||
|
||||
struct nsMargin : public mozilla::gfx::BaseMargin<nscoord, nsMargin> {
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <stdio.h> // for FILE
|
||||
#include <stdint.h> // for int32_t, int64_t
|
||||
#include <algorithm> // for min/max
|
||||
#include "gfxCore.h" // for NS_GFX
|
||||
#include "mozilla/Likely.h" // for MOZ_UNLIKELY
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "nsCoord.h" // for nscoord, etc
|
||||
@ -24,7 +23,7 @@ struct nsIntMargin;
|
||||
|
||||
typedef mozilla::gfx::IntRect nsIntRect;
|
||||
|
||||
struct NS_GFX nsRect :
|
||||
struct nsRect :
|
||||
public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
|
||||
typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
|
||||
|
||||
@ -290,7 +289,7 @@ ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Diagnostics
|
||||
extern NS_GFX FILE* operator<<(FILE* out, const nsRect& rect);
|
||||
extern FILE* operator<<(FILE* out, const nsRect& rect);
|
||||
#endif // DEBUG
|
||||
|
||||
#endif /* NSRECT_H */
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint32_t, uint64_t
|
||||
#include <sys/types.h> // for int32_t
|
||||
#include "gfxCore.h" // for NS_GFX
|
||||
#include "mozilla/ToString.h" // for mozilla::ToString
|
||||
#include "nsCoord.h" // for nscoord
|
||||
#include "nsError.h" // for nsresult
|
||||
@ -420,7 +419,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class NS_GFX nsRegionRectIterator
|
||||
class nsRegionRectIterator
|
||||
{
|
||||
const nsRegion* mRegion;
|
||||
int i;
|
||||
@ -474,7 +473,7 @@ namespace gfx {
|
||||
* BaseIntRegions use int32_t coordinates.
|
||||
*/
|
||||
template <typename Derived, typename Rect, typename Point, typename Margin>
|
||||
class NS_GFX BaseIntRegion
|
||||
class BaseIntRegion
|
||||
{
|
||||
friend class ::nsRegion;
|
||||
|
||||
@ -763,7 +762,7 @@ public:
|
||||
|
||||
nsCString ToString() const { return mImpl.ToString(); }
|
||||
|
||||
class NS_GFX RectIterator
|
||||
class RectIterator
|
||||
{
|
||||
nsRegionRectIterator mImpl;
|
||||
Rect mTmp;
|
||||
@ -825,7 +824,7 @@ private:
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
||||
class NS_GFX nsIntRegion : public mozilla::gfx::BaseIntRegion<nsIntRegion, mozilla::gfx::IntRect, nsIntPoint, nsIntMargin>
|
||||
class nsIntRegion : public mozilla::gfx::BaseIntRegion<nsIntRegion, mozilla::gfx::IntRect, nsIntPoint, nsIntMargin>
|
||||
{
|
||||
public:
|
||||
// Forward constructors.
|
||||
|
@ -8,12 +8,11 @@
|
||||
#define nsScriptableRegion_h
|
||||
|
||||
#include "nsIScriptableRegion.h"
|
||||
#include "gfxCore.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsRegion.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
class NS_GFX nsScriptableRegion final : public nsIScriptableRegion {
|
||||
class nsScriptableRegion final : public nsIScriptableRegion {
|
||||
public:
|
||||
nsScriptableRegion();
|
||||
|
||||
|
@ -6,10 +6,9 @@
|
||||
#ifndef nsTransform2D_h___
|
||||
#define nsTransform2D_h___
|
||||
|
||||
#include "gfxCore.h"
|
||||
#include "nsCoord.h"
|
||||
|
||||
class NS_GFX nsTransform2D
|
||||
class nsTransform2D
|
||||
{
|
||||
private:
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
||||
--- a/gfx/ycbcr/yuv_convert.cpp
|
||||
+++ b/gfx/ycbcr/yuv_convert.cpp
|
||||
@@ -337,16 +337,17 @@ NS_GFX_(void) ScaleYCbCrToRGB32(const ui
|
||||
@@ -337,16 +337,17 @@ void ScaleYCbCrToRGB32(const uint* yplan
|
||||
source_dx_uv >> kFractionBits);
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,10 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
||||
const int kFractionMax = 1 << kFractionBits;
|
||||
const int kFractionMask = ((1 << kFractionBits) - 1);
|
||||
|
||||
+NS_GFX_(YUVType) TypeFromSize(int ywidth,
|
||||
+ int yheight,
|
||||
+ int cbcrwidth,
|
||||
+ int cbcrheight)
|
||||
+YUVType TypeFromSize(int ywidth,
|
||||
+ int yheight,
|
||||
+ int cbcrwidth,
|
||||
+ int cbcrheight)
|
||||
+{
|
||||
+ if (ywidth == cbcrwidth && yheight == cbcrheight) {
|
||||
+ return YV24;
|
||||
@ -27,13 +27,13 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
||||
+}
|
||||
+
|
||||
// Convert a frame of YUV to 32 bit ARGB.
|
||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
||||
--- a/gfx/ycbcr/yuv_convert.h
|
||||
+++ b/gfx/ycbcr/yuv_convert.h
|
||||
@ -46,13 +46,13 @@ diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
||||
FILTER_BILINEAR = 3 // Bilinear filter.
|
||||
};
|
||||
|
||||
+NS_GFX_(YUVType) TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
|
||||
+YUVType TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
|
||||
+
|
||||
// Convert a frame of YUV to 32 bit ARGB.
|
||||
// Pass in YV16/YV12 depending on source format
|
||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
|
@ -71,18 +71,18 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
||||
- rgb_row,
|
||||
- width);
|
||||
- }
|
||||
+NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
+ const uint8* u_buf,
|
||||
+ const uint8* v_buf,
|
||||
+ uint8* rgb_buf,
|
||||
+ int pic_x,
|
||||
+ int pic_y,
|
||||
+ int pic_width,
|
||||
+ int pic_height,
|
||||
+ int y_pitch,
|
||||
+ int uv_pitch,
|
||||
+ int rgb_pitch,
|
||||
+ YUVType yuv_type) {
|
||||
+void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
+ const uint8* u_buf,
|
||||
+ const uint8* v_buf,
|
||||
+ uint8* rgb_buf,
|
||||
+ int pic_x,
|
||||
+ int pic_y,
|
||||
+ int pic_width,
|
||||
+ int pic_height,
|
||||
+ int y_pitch,
|
||||
+ int uv_pitch,
|
||||
+ int rgb_pitch,
|
||||
+ YUVType yuv_type) {
|
||||
+ unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
|
||||
+ unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
|
||||
+ // Test for SSE because the optimized code uses movntq, which is not part of MMX.
|
||||
@ -275,20 +275,20 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
||||
- YUVType yuv_type,
|
||||
- Rotate view_rotate,
|
||||
- ScaleFilter filter) {
|
||||
+NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||
+ const uint8* u_buf,
|
||||
+ const uint8* v_buf,
|
||||
+ uint8* rgb_buf,
|
||||
+ int source_width,
|
||||
+ int source_height,
|
||||
+ int width,
|
||||
+ int height,
|
||||
+ int y_pitch,
|
||||
+ int uv_pitch,
|
||||
+ int rgb_pitch,
|
||||
+ YUVType yuv_type,
|
||||
+ Rotate view_rotate,
|
||||
+ ScaleFilter filter) {
|
||||
+void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||
+ const uint8* u_buf,
|
||||
+ const uint8* v_buf,
|
||||
+ uint8* rgb_buf,
|
||||
+ int source_width,
|
||||
+ int source_height,
|
||||
+ int width,
|
||||
+ int height,
|
||||
+ int y_pitch,
|
||||
+ int uv_pitch,
|
||||
+ int rgb_pitch,
|
||||
+ YUVType yuv_type,
|
||||
+ Rotate view_rotate,
|
||||
+ ScaleFilter filter) {
|
||||
+ bool has_mmx = supports_mmx();
|
||||
+
|
||||
// 4096 allows 3 buffers to fit in 12k.
|
||||
@ -469,18 +469,18 @@ diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
||||
- int uvstride,
|
||||
- int rgbstride,
|
||||
- YUVType yuv_type);
|
||||
+NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
|
||||
+ const uint8* uplane,
|
||||
+ const uint8* vplane,
|
||||
+ uint8* rgbframe,
|
||||
+ int pic_x,
|
||||
+ int pic_y,
|
||||
+ int pic_width,
|
||||
+ int pic_height,
|
||||
+ int ystride,
|
||||
+ int uvstride,
|
||||
+ int rgbstride,
|
||||
+ YUVType yuv_type);
|
||||
+void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||
+ const uint8* uplane,
|
||||
+ const uint8* vplane,
|
||||
+ uint8* rgbframe,
|
||||
+ int pic_x,
|
||||
+ int pic_y,
|
||||
+ int pic_width,
|
||||
+ int pic_height,
|
||||
+ int ystride,
|
||||
+ int uvstride,
|
||||
+ int rgbstride,
|
||||
+ YUVType yuv_type);
|
||||
|
||||
// Scale a frame of YUV to 32 bit ARGB.
|
||||
// Supports rotation and mirroring.
|
||||
@ -501,20 +501,20 @@ diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
||||
-
|
||||
-} // namespace media
|
||||
-
|
||||
+NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane,
|
||||
+ const uint8* uplane,
|
||||
+ const uint8* vplane,
|
||||
+ uint8* rgbframe,
|
||||
+ int source_width,
|
||||
+ int source_height,
|
||||
+ int width,
|
||||
+ int height,
|
||||
+ int ystride,
|
||||
+ int uvstride,
|
||||
+ int rgbstride,
|
||||
+ YUVType yuv_type,
|
||||
+ Rotate view_rotate,
|
||||
+ ScaleFilter filter);
|
||||
+void ScaleYCbCrToRGB32(const uint8* yplane,
|
||||
+ const uint8* uplane,
|
||||
+ const uint8* vplane,
|
||||
+ uint8* rgbframe,
|
||||
+ int source_width,
|
||||
+ int source_height,
|
||||
+ int width,
|
||||
+ int height,
|
||||
+ int ystride,
|
||||
+ int uvstride,
|
||||
+ int rgbstride,
|
||||
+ YUVType yuv_type,
|
||||
+ Rotate view_rotate,
|
||||
+ ScaleFilter filter);
|
||||
+
|
||||
+} // namespace gfx
|
||||
+} // namespace mozilla
|
||||
|
@ -281,7 +281,7 @@ static void ScaleYCbCr444ToRGB565_Nearest_Row_C(
|
||||
}
|
||||
}
|
||||
|
||||
NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *y_buf,
|
||||
void ScaleYCbCrToRGB565(const uint8_t *y_buf,
|
||||
const uint8_t *u_buf,
|
||||
const uint8_t *v_buf,
|
||||
uint8_t *rgb_buf,
|
||||
@ -537,7 +537,7 @@ NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *y_buf,
|
||||
}
|
||||
}
|
||||
|
||||
NS_GFX_(bool) IsScaleYCbCrToRGB565Fast(int source_x0,
|
||||
bool IsScaleYCbCrToRGB565Fast(int source_x0,
|
||||
int source_y0,
|
||||
int source_width,
|
||||
int source_height,
|
||||
@ -599,7 +599,7 @@ void yuv_to_rgb565_row_c(uint16 *dst,
|
||||
}
|
||||
}
|
||||
|
||||
NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* y_buf,
|
||||
void ConvertYCbCrToRGB565(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
@ -652,7 +652,7 @@ NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* y_buf,
|
||||
}
|
||||
}
|
||||
|
||||
NS_GFX_(bool) IsConvertYCbCrToRGB565Fast(int pic_x,
|
||||
bool IsConvertYCbCrToRGB565Fast(int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
int pic_height,
|
||||
|
@ -17,7 +17,7 @@ namespace gfx {
|
||||
|
||||
#ifdef HAVE_YCBCR_TO_RGB565
|
||||
// Convert a frame of YUV to 16 bit RGB565.
|
||||
NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* yplane,
|
||||
void ConvertYCbCrToRGB565(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
@ -31,14 +31,14 @@ NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* yplane,
|
||||
YUVType yuv_type);
|
||||
|
||||
// Used to test if we have an accelerated version.
|
||||
NS_GFX_(bool) IsConvertYCbCrToRGB565Fast(int pic_x,
|
||||
bool IsConvertYCbCrToRGB565Fast(int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
int pic_height,
|
||||
YUVType yuv_type);
|
||||
|
||||
// Scale a frame of YUV to 16 bit RGB565.
|
||||
NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *yplane,
|
||||
void ScaleYCbCrToRGB565(const uint8_t *yplane,
|
||||
const uint8_t *uplane,
|
||||
const uint8_t *vplane,
|
||||
uint8_t *rgbframe,
|
||||
@ -55,7 +55,7 @@ NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *yplane,
|
||||
ScaleFilter filter);
|
||||
|
||||
// Used to test if we have an accelerated version.
|
||||
NS_GFX_(bool) IsScaleYCbCrToRGB565Fast(int source_x0,
|
||||
bool IsScaleYCbCrToRGB565Fast(int source_x0,
|
||||
int source_y0,
|
||||
int source_width,
|
||||
int source_height,
|
||||
|
@ -31,7 +31,7 @@ const int kFractionBits = 16;
|
||||
const int kFractionMax = 1 << kFractionBits;
|
||||
const int kFractionMask = ((1 << kFractionBits) - 1);
|
||||
|
||||
NS_GFX_(YUVType) TypeFromSize(int ywidth,
|
||||
YUVType TypeFromSize(int ywidth,
|
||||
int yheight,
|
||||
int cbcrwidth,
|
||||
int cbcrheight)
|
||||
@ -48,18 +48,18 @@ NS_GFX_(YUVType) TypeFromSize(int ywidth,
|
||||
}
|
||||
|
||||
// Convert a frame of YUV to 32 bit ARGB.
|
||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
int pic_height,
|
||||
int y_pitch,
|
||||
int uv_pitch,
|
||||
int rgb_pitch,
|
||||
YUVType yuv_type) {
|
||||
void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
int pic_height,
|
||||
int y_pitch,
|
||||
int uv_pitch,
|
||||
int rgb_pitch,
|
||||
YUVType yuv_type) {
|
||||
unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
|
||||
unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
|
||||
// Test for SSE because the optimized code uses movntq, which is not part of MMX.
|
||||
@ -163,20 +163,20 @@ static inline void FilterRows(uint8* ybuf, const uint8* y0_ptr,
|
||||
|
||||
|
||||
// Scale a frame of YUV to 32 bit ARGB.
|
||||
NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int width,
|
||||
int height,
|
||||
int y_pitch,
|
||||
int uv_pitch,
|
||||
int rgb_pitch,
|
||||
YUVType yuv_type,
|
||||
Rotate view_rotate,
|
||||
ScaleFilter filter) {
|
||||
void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||
const uint8* u_buf,
|
||||
const uint8* v_buf,
|
||||
uint8* rgb_buf,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int width,
|
||||
int height,
|
||||
int y_pitch,
|
||||
int uv_pitch,
|
||||
int rgb_pitch,
|
||||
YUVType yuv_type,
|
||||
Rotate view_rotate,
|
||||
ScaleFilter filter) {
|
||||
bool has_mmx = supports_mmx();
|
||||
|
||||
// 4096 allows 3 buffers to fit in 12k.
|
||||
|
@ -6,7 +6,6 @@
|
||||
#define MEDIA_BASE_YUV_CONVERT_H_
|
||||
|
||||
#include "chromium_types.h"
|
||||
#include "gfxCore.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -41,39 +40,39 @@ enum ScaleFilter {
|
||||
FILTER_BILINEAR = 3 // Bilinear filter.
|
||||
};
|
||||
|
||||
NS_GFX_(YUVType) TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
|
||||
YUVType TypeFromSize(int ywidth, int yheight, int cbcrwidth, int cbcrheight);
|
||||
|
||||
// Convert a frame of YUV to 32 bit ARGB.
|
||||
// Pass in YV16/YV12 depending on source format
|
||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
int pic_height,
|
||||
int ystride,
|
||||
int uvstride,
|
||||
int rgbstride,
|
||||
YUVType yuv_type);
|
||||
void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
int pic_x,
|
||||
int pic_y,
|
||||
int pic_width,
|
||||
int pic_height,
|
||||
int ystride,
|
||||
int uvstride,
|
||||
int rgbstride,
|
||||
YUVType yuv_type);
|
||||
|
||||
// Scale a frame of YUV to 32 bit ARGB.
|
||||
// Supports rotation and mirroring.
|
||||
NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int width,
|
||||
int height,
|
||||
int ystride,
|
||||
int uvstride,
|
||||
int rgbstride,
|
||||
YUVType yuv_type,
|
||||
Rotate view_rotate,
|
||||
ScaleFilter filter);
|
||||
void ScaleYCbCrToRGB32(const uint8* yplane,
|
||||
const uint8* uplane,
|
||||
const uint8* vplane,
|
||||
uint8* rgbframe,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int width,
|
||||
int height,
|
||||
int ystride,
|
||||
int uvstride,
|
||||
int rgbstride,
|
||||
YUVType yuv_type,
|
||||
Rotate view_rotate,
|
||||
ScaleFilter filter);
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mozilla
|
||||
|
@ -418,9 +418,10 @@ Decoder::PostIsAnimated(int32_t aFirstFrameTimeout)
|
||||
}
|
||||
|
||||
void
|
||||
Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */,
|
||||
Decoder::PostFrameStop(Opacity aFrameOpacity
|
||||
/* = Opacity::SOME_TRANSPARENCY */,
|
||||
DisposalMethod aDisposalMethod
|
||||
/* = DisposalMethod::KEEP */,
|
||||
/* = DisposalMethod::KEEP */,
|
||||
int32_t aTimeout /* = 0 */,
|
||||
BlendMethod aBlendMethod /* = BlendMethod::OVER */)
|
||||
{
|
||||
|
@ -27,6 +27,7 @@ Downscaler::Downscaler(const nsIntSize& aTargetSize)
|
||||
, mYFilter(MakeUnique<skia::ConvolutionFilter1D>())
|
||||
, mWindowCapacity(0)
|
||||
, mHasAlpha(true)
|
||||
, mFlipVertically(false)
|
||||
{
|
||||
MOZ_ASSERT(gfxPrefs::ImageDownscaleDuringDecodeEnabled(),
|
||||
"Downscaling even though downscale-during-decode is disabled?");
|
||||
@ -57,7 +58,8 @@ Downscaler::ReleaseWindow()
|
||||
nsresult
|
||||
Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||
uint8_t* aOutputBuffer,
|
||||
bool aHasAlpha)
|
||||
bool aHasAlpha,
|
||||
bool aFlipVertically /* = false */)
|
||||
{
|
||||
MOZ_ASSERT(aOutputBuffer);
|
||||
MOZ_ASSERT(mTargetSize != aOriginalSize,
|
||||
@ -74,6 +76,7 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||
double(mOriginalSize.height) / mTargetSize.height);
|
||||
mOutputBuffer = aOutputBuffer;
|
||||
mHasAlpha = aHasAlpha;
|
||||
mFlipVertically = aFlipVertically;
|
||||
|
||||
ResetForNextProgressivePass();
|
||||
ReleaseWindow();
|
||||
@ -145,6 +148,16 @@ GetFilterOffsetAndLength(UniquePtr<skia::ConvolutionFilter1D>& aFilter,
|
||||
aFilterLengthOut);
|
||||
}
|
||||
|
||||
void
|
||||
Downscaler::ClearRow(uint32_t aStartingAtCol)
|
||||
{
|
||||
MOZ_ASSERT(int64_t(mOriginalSize.width) > int64_t(aStartingAtCol));
|
||||
uint32_t bytesToClear = (mOriginalSize.width - aStartingAtCol)
|
||||
* sizeof(uint32_t);
|
||||
memset(mRowBuffer.get() + (aStartingAtCol * sizeof(uint32_t)),
|
||||
0, bytesToClear);
|
||||
}
|
||||
|
||||
void
|
||||
Downscaler::CommitRow()
|
||||
{
|
||||
@ -198,9 +211,18 @@ Downscaler::TakeInvalidRect()
|
||||
DownscalerInvalidRect invalidRect;
|
||||
|
||||
// Compute the target size invalid rect.
|
||||
invalidRect.mTargetSizeRect =
|
||||
nsIntRect(0, mPrevInvalidatedLine,
|
||||
if (mFlipVertically) {
|
||||
// We need to flip it. This will implicitly flip the original size invalid
|
||||
// rect, since we compute it by scaling this rect.
|
||||
invalidRect.mTargetSizeRect =
|
||||
IntRect(0, mTargetSize.height - mCurrentOutLine,
|
||||
mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
|
||||
} else {
|
||||
invalidRect.mTargetSizeRect =
|
||||
IntRect(0, mPrevInvalidatedLine,
|
||||
mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
|
||||
}
|
||||
|
||||
mPrevInvalidatedLine = mCurrentOutLine;
|
||||
|
||||
// Compute the original size invalid rect.
|
||||
@ -225,8 +247,13 @@ Downscaler::DownscaleInputLine()
|
||||
auto filterValues =
|
||||
mYFilter->FilterForValue(mCurrentOutLine, &filterOffset, &filterLength);
|
||||
|
||||
int32_t currentOutLine = mFlipVertically
|
||||
? mTargetSize.height - (mCurrentOutLine + 1)
|
||||
: mCurrentOutLine;
|
||||
MOZ_ASSERT(currentOutLine >= 0);
|
||||
|
||||
uint8_t* outputLine =
|
||||
&mOutputBuffer[mCurrentOutLine * mTargetSize.width * sizeof(uint32_t)];
|
||||
&mOutputBuffer[currentOutLine * mTargetSize.width * sizeof(uint32_t)];
|
||||
skia::ConvolveVertically(static_cast<const FilterValue*>(filterValues),
|
||||
filterLength, mWindow.get(), mXFilter->num_values(),
|
||||
outputLine, mHasAlpha, supports_sse2());
|
||||
|
@ -70,14 +70,21 @@ public:
|
||||
* decode.
|
||||
* @param aHasAlpha Whether or not this frame has an alpha channel.
|
||||
* Performance is a little better if it doesn't have one.
|
||||
* @param aFlipVertically If true, output rows will be written to the output
|
||||
* buffer in reverse order vertically, which matches
|
||||
* the way they are stored in some image formats.
|
||||
*/
|
||||
nsresult BeginFrame(const nsIntSize& aOriginalSize,
|
||||
uint8_t* aOutputBuffer,
|
||||
bool aHasAlpha);
|
||||
bool aHasAlpha,
|
||||
bool aFlipVertically = false);
|
||||
|
||||
/// Retrieves the buffer into which the Decoder should write each row.
|
||||
uint8_t* RowBuffer() { return mRowBuffer.get(); }
|
||||
|
||||
/// Clears the current row buffer (optionally starting at @aStartingAtCol).
|
||||
void ClearRow(uint32_t aStartingAtCol = 0);
|
||||
|
||||
/// Signals that the decoder has finished writing a row into the row buffer.
|
||||
void CommitRow();
|
||||
|
||||
@ -117,7 +124,8 @@ private:
|
||||
int32_t mCurrentOutLine;
|
||||
int32_t mCurrentInLine;
|
||||
|
||||
bool mHasAlpha;
|
||||
bool mHasAlpha : 1;
|
||||
bool mFlipVertically : 1;
|
||||
};
|
||||
|
||||
#else
|
||||
@ -139,12 +147,13 @@ public:
|
||||
const nsIntSize& TargetSize() const { return nsIntSize(); }
|
||||
const gfxSize& Scale() const { return gfxSize(1.0, 1.0); }
|
||||
|
||||
nsresult BeginFrame(const nsIntSize&, uint8_t*, bool)
|
||||
nsresult BeginFrame(const nsIntSize&, uint8_t*, bool, bool = false)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
uint8_t* RowBuffer() { return nullptr; }
|
||||
void ClearRow(uint32_t = 0);
|
||||
void CommitRow() { }
|
||||
bool HasInvalidation() const { return false; }
|
||||
DownscalerInvalidRect TakeInvalidRect() { return DownscalerInvalidRect(); }
|
||||
|
@ -36,7 +36,10 @@ static bool
|
||||
ShouldDownscaleDuringDecode(const nsCString& aMimeType)
|
||||
{
|
||||
DecoderType type = DecoderFactory::GetDecoderType(aMimeType.get());
|
||||
return type == DecoderType::JPEG || type == DecoderType::PNG;
|
||||
return type == DecoderType::JPEG ||
|
||||
type == DecoderType::ICON ||
|
||||
type == DecoderType::PNG ||
|
||||
type == DecoderType::BMP;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "RasterImage.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
@ -62,6 +64,20 @@ nsBMPDecoder::~nsBMPDecoder()
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBMPDecoder::SetTargetSize(const nsIntSize& aSize)
|
||||
{
|
||||
// Make sure the size is reasonable.
|
||||
if (MOZ_UNLIKELY(aSize.width <= 0 || aSize.height <= 0)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create a downscaler that we'll filter our output through.
|
||||
mDownscaler.emplace(aSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Sets whether or not the BMP will use alpha data
|
||||
void
|
||||
nsBMPDecoder::SetUseAlphaData(bool useAlphaData)
|
||||
@ -122,15 +138,6 @@ nsBMPDecoder::GetCompressedImageSize() const
|
||||
return pixelArraySize;
|
||||
}
|
||||
|
||||
// Obtains whether or not a BMP file had alpha data in its 4th byte
|
||||
// for 32BPP bitmaps. Only use after the bitmap has been processed.
|
||||
bool
|
||||
nsBMPDecoder::HasAlphaData() const
|
||||
{
|
||||
return mHaveAlphaData;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsBMPDecoder::FinishInternal()
|
||||
{
|
||||
@ -147,7 +154,7 @@ nsBMPDecoder::FinishInternal()
|
||||
nsIntRect r(0, 0, mBIH.width, GetHeight());
|
||||
PostInvalidation(r);
|
||||
|
||||
if (mUseAlphaData) {
|
||||
if (mUseAlphaData && mHaveAlphaData) {
|
||||
PostFrameStop(Opacity::SOME_TRANSPARENCY);
|
||||
} else {
|
||||
PostFrameStop(Opacity::OPAQUE);
|
||||
@ -372,9 +379,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// We treat BMPs as transparent if they're 32bpp and alpha is enabled, but
|
||||
// also if they use RLE encoding, because the 'delta' mode can skip pixels
|
||||
// and cause implicit transparency.
|
||||
if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
|
||||
(mBIH.compression == BMPINFOHEADER::RLE4) ||
|
||||
(mBIH.bpp == 32 && mUseAlphaData)) {
|
||||
bool hasTransparency = (mBIH.compression == BMPINFOHEADER::RLE8) ||
|
||||
(mBIH.compression == BMPINFOHEADER::RLE4) ||
|
||||
(mBIH.bpp == 32 && mUseAlphaData);
|
||||
if (hasTransparency) {
|
||||
PostHasTransparency();
|
||||
}
|
||||
|
||||
@ -453,18 +461,25 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
||||
nsresult rv = AllocateBasicFrame();
|
||||
IntSize targetSize = mDownscaler ? mDownscaler->TargetSize()
|
||||
: GetSize();
|
||||
nsresult rv = AllocateFrame(/* aFrameNum = */ 0, targetSize,
|
||||
IntRect(IntPoint(), targetSize),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||
|
||||
// Prepare for transparency
|
||||
if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
|
||||
(mBIH.compression == BMPINFOHEADER::RLE4)) {
|
||||
// Clear the image, as the RLE may jump over areas
|
||||
memset(mImageData, 0, mImageDataLength);
|
||||
if (mDownscaler) {
|
||||
// BMPs store their rows in reverse order, so the downscaler needs to
|
||||
// reverse them again when writing its output.
|
||||
rv = mDownscaler->BeginFrame(GetSize(), mImageData, hasTransparency,
|
||||
/* aFlipVertically = */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -606,8 +621,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
if (rowSize == mRowBytes) {
|
||||
// Collected a whole row into mRow, process it
|
||||
uint8_t* p = mRow;
|
||||
uint32_t* d = reinterpret_cast<uint32_t*>(mImageData) +
|
||||
PIXEL_OFFSET(mCurLine, 0);
|
||||
uint32_t* d = mDownscaler
|
||||
? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
|
||||
: reinterpret_cast<uint32_t*>(mImageData)
|
||||
+ PIXEL_OFFSET(mCurLine, 0);
|
||||
uint32_t lpos = mBIH.width;
|
||||
switch (mBIH.bpp) {
|
||||
case 1:
|
||||
@ -664,28 +681,11 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
case 32:
|
||||
while (lpos > 0) {
|
||||
if (mUseAlphaData) {
|
||||
if (!mHaveAlphaData && p[3]) {
|
||||
// Non-zero alpha byte detected! Clear previous
|
||||
// pixels that we have already processed.
|
||||
// This works because we know that if we
|
||||
// are reaching here then the alpha data in byte
|
||||
// 4 has been right all along. And we know it
|
||||
// has been set to 0 the whole time, so that
|
||||
// means that everything is transparent so far.
|
||||
uint32_t* start = reinterpret_cast<uint32_t*>
|
||||
(mImageData) + GetWidth() *
|
||||
(mCurLine - 1);
|
||||
uint32_t heightDifference = GetHeight() -
|
||||
mCurLine + 1;
|
||||
uint32_t pixelCount = GetWidth() *
|
||||
heightDifference;
|
||||
|
||||
memset(start, 0, pixelCount * sizeof(uint32_t));
|
||||
|
||||
if (MOZ_UNLIKELY(!mHaveAlphaData && p[3])) {
|
||||
PostHasTransparency();
|
||||
mHaveAlphaData = true;
|
||||
}
|
||||
SetPixel(d, p[2], p[1], p[0], mHaveAlphaData ? p[3] : 0xFF);
|
||||
SetPixel(d, p[2], p[1], p[0], p[3]);
|
||||
} else {
|
||||
SetPixel(d, p[2], p[1], p[0]);
|
||||
}
|
||||
@ -697,6 +697,11 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
NS_NOTREACHED("Unsupported color depth,"
|
||||
" but earlier check didn't catch it");
|
||||
}
|
||||
|
||||
if (mDownscaler) {
|
||||
mDownscaler->CommitRow();
|
||||
}
|
||||
|
||||
mCurLine --;
|
||||
if (mCurLine == 0) { // Finished last line
|
||||
break;
|
||||
@ -741,8 +746,12 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
uint32_t pixelsNeeded = std::min<uint32_t>(mBIH.width - mCurPos,
|
||||
mStateData);
|
||||
if (pixelsNeeded) {
|
||||
uint32_t* d = reinterpret_cast<uint32_t*>
|
||||
(mImageData) + PIXEL_OFFSET(mCurLine, mCurPos);
|
||||
uint32_t* d = mDownscaler
|
||||
? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
|
||||
+ mCurPos
|
||||
: reinterpret_cast<uint32_t*>(mImageData)
|
||||
+ PIXEL_OFFSET(mCurLine, mCurPos);
|
||||
|
||||
mCurPos += pixelsNeeded;
|
||||
if (mBIH.compression == BMPINFOHEADER::RLE8) {
|
||||
do {
|
||||
@ -761,6 +770,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
switch(byte) {
|
||||
case RLE::ESCAPE_EOL:
|
||||
// End of Line: Go to next row
|
||||
if (mDownscaler) {
|
||||
mDownscaler->CommitRow();
|
||||
}
|
||||
|
||||
mCurLine --;
|
||||
mCurPos = 0;
|
||||
mState = eRLEStateInitial;
|
||||
@ -810,11 +823,20 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// Handle the XDelta and proceed to get Y Delta
|
||||
byte = *aBuffer++;
|
||||
aCount--;
|
||||
|
||||
if (mDownscaler) {
|
||||
// Clear the skipped pixels. (This clears to the end of the row,
|
||||
// which is perfect if there's a Y delta and harmless if not).
|
||||
mDownscaler->ClearRow(/* aStartingAtCol = */ mCurPos);
|
||||
}
|
||||
|
||||
mCurPos += byte;
|
||||
|
||||
// Delta encoding makes it possible to skip pixels
|
||||
// making the image transparent.
|
||||
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
|
||||
PostHasTransparency();
|
||||
mHaveAlphaData = true;
|
||||
}
|
||||
mUseAlphaData = mHaveAlphaData = true;
|
||||
if (mCurPos > mBIH.width) {
|
||||
@ -824,7 +846,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
mState = eRLEStateNeedYDelta;
|
||||
continue;
|
||||
|
||||
case eRLEStateNeedYDelta:
|
||||
case eRLEStateNeedYDelta: {
|
||||
// Get the Y Delta and then "handle" the move
|
||||
byte = *aBuffer++;
|
||||
aCount--;
|
||||
@ -833,10 +855,26 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// making the image transparent.
|
||||
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
|
||||
PostHasTransparency();
|
||||
mHaveAlphaData = true;
|
||||
}
|
||||
mUseAlphaData = mHaveAlphaData = true;
|
||||
mCurLine -= std::min<int32_t>(byte, mCurLine);
|
||||
|
||||
int32_t yDelta = std::min<int32_t>(byte, mCurLine);
|
||||
mCurLine -= yDelta;
|
||||
|
||||
if (mDownscaler && yDelta > 0) {
|
||||
// Commit the current row (the first of the skipped rows).
|
||||
mDownscaler->CommitRow();
|
||||
|
||||
// Clear and commit the remaining skipped rows.
|
||||
for (int32_t line = 1 ; line < yDelta ; ++line) {
|
||||
mDownscaler->ClearRow();
|
||||
mDownscaler->CommitRow();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case eRLEStateAbsoluteMode: // Absolute Mode
|
||||
case eRLEStateAbsoluteModePadded:
|
||||
@ -845,9 +883,12 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// represents the number of pixels
|
||||
// that follow, each of which contains
|
||||
// the color index of a single pixel.
|
||||
uint32_t* d = reinterpret_cast<uint32_t*>
|
||||
(mImageData) +
|
||||
PIXEL_OFFSET(mCurLine, mCurPos);
|
||||
uint32_t* d = mDownscaler
|
||||
? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
|
||||
+ mCurPos
|
||||
: reinterpret_cast<uint32_t*>(mImageData)
|
||||
+ PIXEL_OFFSET(mCurLine, mCurPos);
|
||||
|
||||
uint32_t* oldPos = d;
|
||||
if (mBIH.compression == BMPINFOHEADER::RLE8) {
|
||||
while (aCount > 0 && mStateData > 0) {
|
||||
@ -903,9 +944,15 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
const uint32_t rows = mOldLine - mCurLine;
|
||||
if (rows) {
|
||||
// Invalidate
|
||||
nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
|
||||
mBIH.width, rows);
|
||||
PostInvalidation(r);
|
||||
if (!mDownscaler) {
|
||||
nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
|
||||
mBIH.width, rows);
|
||||
PostInvalidation(r);
|
||||
} else if (mDownscaler->HasInvalidation()) {
|
||||
DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
|
||||
PostInvalidation(invalidRect.mOriginalSizeRect,
|
||||
Some(invalidRect.mTargetSizeRect));
|
||||
}
|
||||
|
||||
mOldLine = mCurLine;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "BMPFileHeaders.h"
|
||||
#include "Decoder.h"
|
||||
#include "Downscaler.h"
|
||||
#include "gfxColor.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
@ -24,6 +25,8 @@ class nsBMPDecoder : public Decoder
|
||||
public:
|
||||
~nsBMPDecoder();
|
||||
|
||||
nsresult SetTargetSize(const nsIntSize& aSize) override;
|
||||
|
||||
// Specifies whether or not the BMP file will contain alpha data
|
||||
// If set to true and the BMP is 32BPP, the alpha data will be
|
||||
// retrieved from the 4th byte of image data per pixel
|
||||
@ -46,7 +49,10 @@ public:
|
||||
|
||||
// Obtains whether or not a BMP file had alpha data in its 4th byte
|
||||
// for 32BPP bitmaps. Only use after the bitmap has been processed.
|
||||
bool HasAlphaData() const;
|
||||
bool HasAlphaData() const { return mHaveAlphaData; }
|
||||
|
||||
/// Marks this BMP as having alpha data (due to e.g. an ICO alpha mask).
|
||||
void SetHasAlphaData() { mHaveAlphaData = true; }
|
||||
|
||||
virtual void WriteInternal(const char* aBuffer,
|
||||
uint32_t aCount) override;
|
||||
@ -71,6 +77,8 @@ private:
|
||||
char mRawBuf[BIH_INTERNAL_LENGTH::WIN_V3]; //< If this is changed,
|
||||
// WriteInternal() MUST be updated
|
||||
|
||||
Maybe<Downscaler> mDownscaler;
|
||||
|
||||
uint32_t mLOH; //< Length of the header
|
||||
|
||||
uint32_t mNumColors; //< The number of used colors, i.e. the number of
|
||||
|
@ -532,14 +532,14 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// If the bitmap is fully processed, treat any left over data as the ICO's
|
||||
// 'AND buffer mask' which appears after the bitmap resource.
|
||||
if (!mIsPNG && mPos >= bmpDataEnd) {
|
||||
nsRefPtr<nsBMPDecoder> bmpDecoder =
|
||||
static_cast<nsBMPDecoder*>(mContainedDecoder.get());
|
||||
|
||||
// There may be an optional AND bit mask after the data. This is
|
||||
// only used if the alpha data is not already set. The alpha data
|
||||
// is used for 32bpp bitmaps as per the comment in ICODecoder.h
|
||||
// The alpha mask should be checked in all other cases.
|
||||
if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
||||
GetBitsPerPixel() != 32 ||
|
||||
!static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
||||
HasAlphaData()) {
|
||||
if (bmpDecoder->GetBitsPerPixel() != 32 || !bmpDecoder->HasAlphaData()) {
|
||||
uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
|
||||
if (mPos == bmpDataEnd) {
|
||||
mPos++;
|
||||
@ -573,9 +573,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
mCurLine--;
|
||||
mRowBytes = 0;
|
||||
|
||||
uint32_t* imageData =
|
||||
static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
||||
GetImageData();
|
||||
uint32_t* imageData = bmpDecoder->GetImageData();
|
||||
if (!imageData) {
|
||||
PostDataError();
|
||||
return;
|
||||
@ -601,7 +599,8 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
// If any bits are set in sawTransparency, then we know at least one
|
||||
// pixel was transparent.
|
||||
if (sawTransparency) {
|
||||
PostHasTransparency();
|
||||
PostHasTransparency();
|
||||
bmpDecoder->SetHasAlphaData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,15 +12,20 @@
|
||||
#include "RasterImage.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
using std::min;
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
||||
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
||||
: Decoder(aImage),
|
||||
mWidth(-1),
|
||||
mHeight(-1),
|
||||
mPixBytesRead(0),
|
||||
mState(iconStateStart)
|
||||
: Decoder(aImage)
|
||||
, mExpectedDataLength(0)
|
||||
, mPixBytesRead(0)
|
||||
, mState(iconStateStart)
|
||||
, mWidth(-1)
|
||||
, mHeight(-1)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
@ -28,15 +33,25 @@ nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
||||
nsIconDecoder::~nsIconDecoder()
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
nsIconDecoder::SetTargetSize(const nsIntSize& aSize)
|
||||
{
|
||||
// Make sure the size is reasonable.
|
||||
if (MOZ_UNLIKELY(aSize.width <= 0 || aSize.height <= 0)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Create a downscaler that we'll filter our output through.
|
||||
mDownscaler.emplace(aSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
{
|
||||
MOZ_ASSERT(!HasError(), "Shouldn't call WriteInternal after error!");
|
||||
|
||||
// We put this here to avoid errors about crossing initialization with case
|
||||
// jumps on linux.
|
||||
uint32_t bytesToRead = 0;
|
||||
|
||||
// Loop until the input data is gone
|
||||
while (aCount > 0) {
|
||||
switch (mState) {
|
||||
@ -73,9 +88,16 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
break;
|
||||
}
|
||||
|
||||
// The input is 32bpp, so we expect 4 bytes of data per pixel.
|
||||
mExpectedDataLength = mWidth * mHeight * 4;
|
||||
|
||||
{
|
||||
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
||||
nsresult rv = AllocateBasicFrame();
|
||||
IntSize targetSize = mDownscaler ? mDownscaler->TargetSize()
|
||||
: GetSize();
|
||||
nsresult rv = AllocateFrame(0, targetSize,
|
||||
IntRect(IntPoint(), targetSize),
|
||||
gfx::SurfaceFormat::B8G8R8A8);
|
||||
if (NS_FAILED(rv)) {
|
||||
mState = iconStateFinished;
|
||||
return;
|
||||
@ -84,6 +106,16 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
|
||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||
|
||||
if (mDownscaler) {
|
||||
nsresult rv = mDownscaler->BeginFrame(GetSize(),
|
||||
mImageData,
|
||||
/* aHasAlpha = */ true);
|
||||
if (NS_FAILED(rv)) {
|
||||
mState = iconStateFinished;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Book Keeping
|
||||
aBuffer++;
|
||||
aCount--;
|
||||
@ -93,25 +125,60 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||
case iconStateReadPixels: {
|
||||
|
||||
// How many bytes are we reading?
|
||||
bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
|
||||
uint32_t bytesToRead = min(aCount, mExpectedDataLength - mPixBytesRead);
|
||||
|
||||
// Copy the bytes
|
||||
memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
|
||||
if (mDownscaler) {
|
||||
uint8_t* row = mDownscaler->RowBuffer();
|
||||
const uint32_t bytesPerRow = mWidth * 4;
|
||||
const uint32_t rowOffset = mPixBytesRead % bytesPerRow;
|
||||
|
||||
// Performance isn't critical here, so our update rectangle is
|
||||
// always the full icon
|
||||
nsIntRect r(0, 0, mWidth, mHeight);
|
||||
// Update global state; we're about to read |bytesToRead| bytes.
|
||||
aCount -= bytesToRead;
|
||||
mPixBytesRead += bytesToRead;
|
||||
|
||||
// Invalidate
|
||||
PostInvalidation(r);
|
||||
if (rowOffset > 0) {
|
||||
// Finish the current row.
|
||||
const uint32_t remaining = bytesPerRow - rowOffset;
|
||||
memcpy(row + rowOffset, aBuffer, remaining);
|
||||
aBuffer += remaining;
|
||||
bytesToRead -= remaining;
|
||||
mDownscaler->CommitRow();
|
||||
}
|
||||
|
||||
// Book Keeping
|
||||
aBuffer += bytesToRead;
|
||||
aCount -= bytesToRead;
|
||||
mPixBytesRead += bytesToRead;
|
||||
// Copy the bytes a row at a time.
|
||||
while (bytesToRead > bytesPerRow) {
|
||||
memcpy(row, aBuffer, bytesPerRow);
|
||||
aBuffer += bytesPerRow;
|
||||
bytesToRead -= bytesPerRow;
|
||||
mDownscaler->CommitRow();
|
||||
}
|
||||
|
||||
// Copy any leftover bytes. (Leaving the current row incomplete.)
|
||||
if (bytesToRead > 0) {
|
||||
memcpy(row, aBuffer, bytesToRead);
|
||||
aBuffer += bytesPerRow;
|
||||
bytesToRead -= bytesPerRow;
|
||||
}
|
||||
|
||||
if (mDownscaler->HasInvalidation()) {
|
||||
DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
|
||||
PostInvalidation(invalidRect.mOriginalSizeRect,
|
||||
Some(invalidRect.mTargetSizeRect));
|
||||
}
|
||||
} else {
|
||||
// Copy all the bytes at once.
|
||||
memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
|
||||
aBuffer += bytesToRead;
|
||||
aCount -= bytesToRead;
|
||||
mPixBytesRead += bytesToRead;
|
||||
|
||||
// Invalidate. Performance isn't critical here, so our update
|
||||
// rectangle is always the full icon.
|
||||
PostInvalidation(IntRect(0, 0, mWidth, mHeight));
|
||||
}
|
||||
|
||||
// If we've got all the pixel bytes, we're finished
|
||||
if (mPixBytesRead == mImageDataLength) {
|
||||
if (mPixBytesRead == mExpectedDataLength) {
|
||||
PostFrameStop();
|
||||
PostDecodeDone();
|
||||
mState = iconStateFinished;
|
||||
|
@ -39,6 +39,8 @@ class nsIconDecoder : public Decoder
|
||||
public:
|
||||
virtual ~nsIconDecoder();
|
||||
|
||||
virtual nsresult SetTargetSize(const nsIntSize& aSize) override;
|
||||
|
||||
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
|
||||
|
||||
private:
|
||||
@ -47,11 +49,13 @@ private:
|
||||
// Decoders should only be instantiated via DecoderFactory.
|
||||
explicit nsIconDecoder(RasterImage* aImage);
|
||||
|
||||
public:
|
||||
uint8_t mWidth;
|
||||
uint8_t mHeight;
|
||||
Maybe<Downscaler> mDownscaler;
|
||||
|
||||
uint32_t mExpectedDataLength;
|
||||
uint32_t mPixBytesRead;
|
||||
uint32_t mState;
|
||||
uint8_t mWidth;
|
||||
uint8_t mHeight;
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -1314,6 +1314,7 @@ if test "$GNU_CXX"; then
|
||||
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||
# -Wpointer-to-int-cast - catches casts from pointer to different sized int
|
||||
# -Wrange-loop-analysis - catches copies during range-based for loops.
|
||||
# -Wreorder - catches ctor initializer list not matching class definition order
|
||||
# -Wreturn-type - catches missing returns, zero false positives
|
||||
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
||||
@ -1354,6 +1355,7 @@ if test "$GNU_CXX"; then
|
||||
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, conversion-null, ac_cxx_has_werror_conversion_null)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_werror_non_literal_null_conversion)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, range-loop-analysis, ac_cxx_has_range_loop_analysis)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
|
||||
fi
|
||||
|
||||
|
@ -2620,7 +2620,8 @@ NS_IMETHODIMP nsDocumentViewer::SelectAll()
|
||||
|
||||
NS_IMETHODIMP nsDocumentViewer::CopySelection()
|
||||
{
|
||||
nsCopySupport::FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, mPresShell, nullptr);
|
||||
nsCopySupport::FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard,
|
||||
mPresShell, nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -5320,7 +5320,7 @@ bool PresShell::AsyncPanZoomEnabled()
|
||||
return widget->AsyncPanZoomEnabled();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return gfxPlatform::AsyncPanZoomEnabled();
|
||||
}
|
||||
|
||||
void PresShell::SetIgnoreViewportScrolling(bool aIgnore)
|
||||
|
@ -371,6 +371,11 @@ CommonAnimationManager::FlushAnimations()
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(collection->mElement->GetComposedDoc() ==
|
||||
mPresContext->Document(),
|
||||
"Should not have a transition/animations collection for an "
|
||||
"element that is not part of the document tree");
|
||||
|
||||
collection->RequestRestyle(AnimationCollection::RestyleType::Standard);
|
||||
}
|
||||
}
|
||||
@ -883,10 +888,6 @@ AnimationCollection::RequestRestyle(RestyleType aRestyleType)
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mElement->GetCrossShadowCurrentDoc() == presContext->Document(),
|
||||
"Element::UnbindFromTree should have destroyed the element "
|
||||
"transition/animations object");
|
||||
|
||||
// Steps for Restyle::Layer:
|
||||
|
||||
if (aRestyleType == RestyleType::Layer) {
|
||||
|
16
layout/style/crashtests/1200568-1.html
Normal file
16
layout/style/crashtests/1200568-1.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
.anim { animation: anim 2s infinite linear }
|
||||
@keyframes anim { }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var i = document.createElement('i');
|
||||
i.setAttribute('class', 'anim');
|
||||
getComputedStyle(i).display;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -120,5 +120,6 @@ load 1161366-1.html
|
||||
load 1163446-1.html
|
||||
load 1164813-1.html
|
||||
load 1167782-1.html
|
||||
load 1200568-1.html
|
||||
load large_border_image_width.html
|
||||
load border-image-visited-link.html
|
||||
|
@ -371,8 +371,9 @@ nsIStyleRule*
|
||||
nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
||||
mozilla::dom::Element* aElement)
|
||||
{
|
||||
if (!mPresContext->IsDynamic()) {
|
||||
// For print or print preview, ignore animations.
|
||||
// Ignore animations for print or print preview, and for elements
|
||||
// that are not attached to the document tree.
|
||||
if (!mPresContext->IsDynamic() || !aElement->IsInComposedDoc()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,17 @@ PodEqual(const T* one, const T* two, size_t len)
|
||||
return !memcmp(one, two, len * sizeof(T));
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine whether the |N| elements at |one| are memory-identical to the
|
||||
* |N| elements at |two|.
|
||||
*/
|
||||
template <class T, size_t N>
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
PodEqual(const T (&one)[N], const T (&two)[N])
|
||||
{
|
||||
return PodEqual(one, two, N);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_PodOperations_h */
|
||||
|
@ -1,84 +1 @@
|
||||
[testAboutPage]
|
||||
|
||||
#[testAddonManager]
|
||||
# fails on gs2, nexus one, lg revolution, droid pro, nexus s
|
||||
|
||||
[testAwesomebarSwipes]
|
||||
|
||||
[testAwesomebar]
|
||||
|
||||
#[testAxisLocking]
|
||||
# fails on gs2, nexus one, lg revolution, droid pro, nexus s
|
||||
|
||||
[testBookmark]
|
||||
# fails on gs2 4.0.3
|
||||
|
||||
[testBookmarklets]
|
||||
|
||||
[testBrowserProvider]
|
||||
# fails on gs2 4.0.3
|
||||
|
||||
#[testClearPrivateData]
|
||||
# fails on gs2, nexus-one, lg revolution, droid pro, nexus s
|
||||
|
||||
#[testDoorHanger]
|
||||
# fails on gs2, nexus-one, lg revolution, droid pro, nexus s
|
||||
|
||||
#[testFlingCorrectness]
|
||||
# fails on gs2, nexus one, lg revolution, droid pro, nexus s
|
||||
|
||||
[testFormHistory]
|
||||
|
||||
#[testHistory]
|
||||
# fails on gs2, nexus one,lg revolution, droid pro, nexus s
|
||||
|
||||
#[testJarReader]
|
||||
# fails on gs2, nexus one, lg revolution, droid pro, nexus s
|
||||
|
||||
#[testLoad]
|
||||
# fails on gs2, nexus one, lg revolution, droid pro, nexus s
|
||||
|
||||
[testNewTab]
|
||||
# fails on nexus s random crash [@ libpvrANDROID_WSEGL.so + 0x73c]
|
||||
|
||||
#[testPanCorrectness]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testPasswordEncrypt]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
[testPasswordProvider]
|
||||
|
||||
#[testPermissions]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testSearchSuggestions]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testSettingsMenuItems]
|
||||
# fails on nexus one, lg revolution, nexus s
|
||||
|
||||
#[testShareLink]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
[testSystemPages]
|
||||
|
||||
#[testTabHistory]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testTabsLayoutMenu]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testThumbnails]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testVkbOverlap]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[testWebContentContextMenu]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
#[test_bug720538]
|
||||
# fails on gs2, nexus one, lg revolution, nexus s
|
||||
|
||||
[testBrowserSearchVisibility]
|
||||
[testAdobeFlash]
|
||||
|
@ -1786,7 +1786,7 @@ pref("network.generic-ntlm-auth.workstation", "WORKSTATION");
|
||||
// 1 - allow sub-resources to open HTTP authentication credentials dialogs,
|
||||
// but don't allow it for cross-origin sub-resources
|
||||
// 2 - allow the cross-origin authentication as well.
|
||||
pref("network.auth.allow-subresource-auth", 2);
|
||||
pref("network.auth.subresource-http-auth-allow", 2);
|
||||
|
||||
pref("permissions.default.image", 1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
|
||||
|
||||
|
@ -1288,6 +1288,8 @@ NS_IMETHODIMP
|
||||
HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
|
||||
nsACString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
// XXX might be better to search the header list directly instead of
|
||||
// hitting the http atom hash table.
|
||||
nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
|
||||
@ -1333,6 +1335,8 @@ HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *visitor)
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::GetResponseHeader(const nsACString &header, nsACString &value)
|
||||
{
|
||||
value.Truncate();
|
||||
|
||||
if (!mResponseHead)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
|
@ -95,6 +95,7 @@ NullHttpChannel::SetReferrerWithPolicy(nsIURI *referrer, uint32_t referrerPolicy
|
||||
NS_IMETHODIMP
|
||||
NullHttpChannel::GetRequestHeader(const nsACString & aHeader, nsACString & _retval)
|
||||
{
|
||||
_retval.Truncate();
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -167,6 +168,7 @@ NullHttpChannel::GetRequestSucceeded(bool *aRequestSucceeded)
|
||||
NS_IMETHODIMP
|
||||
NullHttpChannel::GetResponseHeader(const nsACString & header, nsACString & _retval)
|
||||
{
|
||||
_retval.Truncate();
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
@ -75,15 +75,15 @@ nsHttpChannelAuthProvider::~nsHttpChannelAuthProvider()
|
||||
}
|
||||
|
||||
uint32_t nsHttpChannelAuthProvider::sAuthAllowPref =
|
||||
SUBRESOURCE_AUTH_DIALOG_DISALLOW_CROSS_ORIGIN;
|
||||
SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL;
|
||||
|
||||
void
|
||||
nsHttpChannelAuthProvider::InitializePrefs()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mozilla::Preferences::AddUintVarCache(&sAuthAllowPref,
|
||||
"network.auth.allow-subresource-auth",
|
||||
SUBRESOURCE_AUTH_DIALOG_DISALLOW_CROSS_ORIGIN);
|
||||
"network.auth.subresource-http-auth-allow",
|
||||
SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -9,7 +9,9 @@
|
||||
#include "nsHttpNTLMAuth.h"
|
||||
#include "nsIAuthModule.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "plbase64.h"
|
||||
#include "plstr.h"
|
||||
#include "prnetdb.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -733,6 +733,7 @@ NS_IMETHODIMP
|
||||
nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
|
||||
nsACString & aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
||||
mHttpChannel->GetRequestHeader(aHeader, aValue);
|
||||
}
|
||||
@ -820,6 +821,7 @@ NS_IMETHODIMP
|
||||
nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
|
||||
nsACString & aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
if (!mHttpChannel)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
@ -831,10 +833,9 @@ nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
|
||||
nsCaseInsensitiveCStringComparator()) &&
|
||||
!aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
|
||||
nsCaseInsensitiveCStringComparator())) {
|
||||
aValue.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
return mHttpChannel->GetResponseHeader(aHeader, aValue);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// This file tests authentication prompt depending on pref
|
||||
// network.auth.allow-subresource-auth:
|
||||
// network.auth.subresource-http-auth-allow:
|
||||
// 0 - don't allow sub-resources to open HTTP authentication credentials
|
||||
// dialogs
|
||||
// 1 - allow sub-resources to open HTTP authentication credentials dialogs,
|
||||
@ -130,9 +130,9 @@ function makeChan(loadingUrl, url, contentPolicy) {
|
||||
return chan;
|
||||
}
|
||||
|
||||
function Test(allow_subresource_auth_pref, loadingUri, uri, contentPolicy,
|
||||
function Test(subresource_http_auth_allow_pref, loadingUri, uri, contentPolicy,
|
||||
expectedCode) {
|
||||
this._allow_subresource_auth_pref = allow_subresource_auth_pref;
|
||||
this._subresource_http_auth_allow_pref = subresource_http_auth_allow_pref;
|
||||
this._loadingUri = loadingUri;
|
||||
this._uri = uri;
|
||||
this._contentPolicy = contentPolicy;
|
||||
@ -140,7 +140,7 @@ function Test(allow_subresource_auth_pref, loadingUri, uri, contentPolicy,
|
||||
}
|
||||
|
||||
Test.prototype = {
|
||||
_allow_subresource_auth_pref: 1,
|
||||
_subresource_http_auth_allow_pref: 1,
|
||||
_loadingUri: null,
|
||||
_uri: null,
|
||||
_contentPolicy: Ci.nsIContentPolicy.TYPE_OTHER,
|
||||
@ -183,14 +183,14 @@ Test.prototype = {
|
||||
},
|
||||
|
||||
run: function() {
|
||||
dump("Run test: " + this._allow_subresource_auth_pref
|
||||
dump("Run test: " + this._subresource_http_auth_allow_pref
|
||||
+ this._loadingUri
|
||||
+ this._uri
|
||||
+ this._contentPolicy
|
||||
+ this._expectedCode + " \n");
|
||||
|
||||
prefs.setIntPref("network.auth.allow-subresource-auth",
|
||||
this._allow_subresource_auth_pref);
|
||||
prefs.setIntPref("network.auth.subresource-http-auth-allow",
|
||||
this._subresource_http_auth_allow_pref);
|
||||
let chan = makeChan(this._loadingUri, this._uri, this._contentPolicy);
|
||||
chan.notificationCallbacks = new Requestor(this._expectedCode == 200);
|
||||
chan.asyncOpen(this, null);
|
||||
|
@ -245,7 +245,7 @@ function run_test() {
|
||||
prefs.setIntPref("network.proxy.type", 1);
|
||||
|
||||
// Turn off the authentication dialog blocking for this test.
|
||||
prefs.setIntPref("network.auth.allow-subresource-auth", 2);
|
||||
prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
|
||||
|
||||
tests[current_test]();
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
// Turn off the authentication dialog blocking for this test.
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
prefs.setIntPref("network.auth.allow-subresource-auth", 2);
|
||||
prefs.setIntPref("network.auth.subresource-http-auth-allow", 2);
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||
return "http://localhost:" + httpserv.identity.primaryPort;
|
||||
|
@ -79,10 +79,10 @@ class HgtoolVCS(ScriptMixin, LogMixin, TransferMixin):
|
||||
if self._is_windows():
|
||||
# SYSTEMROOT is needed for 'import random'
|
||||
if 'SYSTEMROOT' not in env:
|
||||
env['SYSTEMROOT'] = os.environ.get('SYSTEMROOT')
|
||||
env['SYSTEMROOT'] = os.environ.get('SYSTEMROOT', '')
|
||||
# HOME is needed for the 'hg help share' check
|
||||
if 'HOME' not in env:
|
||||
env['HOME'] = os.environ.get('HOME')
|
||||
env['HOME'] = os.environ.get('HOME', '')
|
||||
|
||||
cmd = self.hgtool[:]
|
||||
|
||||
|
@ -1241,7 +1241,7 @@ or run without that action (ie: --no-{action})"
|
||||
|
||||
def _query_props_set_by_mach(self, console_output=True, error_level=FATAL):
|
||||
mach_properties_path = os.path.join(
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json'
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json'
|
||||
)
|
||||
self.info("setting properties set by mach build. Looking in path: %s"
|
||||
% mach_properties_path)
|
||||
@ -1262,9 +1262,7 @@ or run without that action (ie: --no-{action})"
|
||||
if prop != 'UNKNOWN':
|
||||
self.set_buildbot_property(key, prop, write_to_file=True)
|
||||
else:
|
||||
self.log("Could not determine path for build properties. "
|
||||
"Does this exist: `%s` ?" % mach_properties_path,
|
||||
level=error_level)
|
||||
self.info("No mach_build_properties.json found - not importing properties.")
|
||||
|
||||
def generate_build_props(self, console_output=True, halt_on_failure=False):
|
||||
"""sets props found from mach build and, in addition, buildid,
|
||||
@ -1644,7 +1642,7 @@ or run without that action (ie: --no-{action})"
|
||||
self._run_tooltool()
|
||||
self._create_mozbuild_dir()
|
||||
mach_props = os.path.join(
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'mach_build_properties.json'
|
||||
self.query_abs_dirs()['abs_obj_dir'], 'dist', 'mach_build_properties.json'
|
||||
)
|
||||
if os.path.exists(mach_props):
|
||||
self.info("Removing previous mach property file: %s" % mach_props)
|
||||
|
@ -165,6 +165,13 @@ class FirefoxUITests(VCSToolsScript, VirtualenvMixin):
|
||||
else:
|
||||
self.fatal('Can\'t find symbols_url from installer_url: {}!'.format(installer_url))
|
||||
|
||||
@PreScriptAction('checkout')
|
||||
def _pre_checkout(self, action):
|
||||
if not self.firefox_ui_branch:
|
||||
self.fatal(
|
||||
'Please specify --firefox-ui-branch. Valid values can be found '
|
||||
'in here https://github.com/mozilla/firefox-ui-tests/branches')
|
||||
|
||||
def checkout(self):
|
||||
"""
|
||||
We checkout firefox_ui_tests and update to the right branch
|
||||
@ -203,13 +210,14 @@ class FirefoxUITests(VCSToolsScript, VirtualenvMixin):
|
||||
"""All required steps for running the tests against an installer."""
|
||||
dirs = self.query_abs_dirs()
|
||||
|
||||
bin_dir = os.path.dirname(self.query_python_path())
|
||||
fx_ui_tests_bin = os.path.join(bin_dir, script_name)
|
||||
venv_python_path = self.query_python_path()
|
||||
update_script = os.path.join(dirs['fx_ui_dir'], 'firefox_ui_harness', 'cli_update.py')
|
||||
gecko_log = os.path.join(dirs['abs_log_dir'], 'gecko.log')
|
||||
|
||||
# Build the command
|
||||
cmd = [
|
||||
fx_ui_tests_bin,
|
||||
venv_python_path,
|
||||
update_script,
|
||||
'--installer', installer_path,
|
||||
# Log to stdout until tests are stable.
|
||||
'--gecko-log=-',
|
||||
|
@ -214,8 +214,9 @@ class ReleaseFirefoxUIUpdateTests(FirefoxUIUpdateTests):
|
||||
|
||||
@PreScriptAction('run-tests')
|
||||
def _pre_run_tests(self, action):
|
||||
assert 'release_update_config' in self.config, \
|
||||
'You have to specify --release-update-config.'
|
||||
assert ('release_update_config' in self.config or
|
||||
self.installer_url or self.installer_path),
|
||||
'Either specify --update-verify-config, --installer-url or --installer-path.'
|
||||
|
||||
def run_tests(self):
|
||||
dirs = self.query_abs_dirs()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user