mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 05:10:49 +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
|
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||||
# don't change CLOBBER for WebIDL changes any more.
|
# 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"
|
macanimationtype="document"
|
||||||
fullscreenbutton="true"
|
fullscreenbutton="true"
|
||||||
screenX="4" screenY="4"
|
screenX="4" screenY="4"
|
||||||
width="640" height="480"
|
width="800" height="600"
|
||||||
persist="screenX screenY width height sizemode">
|
persist="screenX screenY width height sizemode">
|
||||||
|
|
||||||
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"></script>
|
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"></script>
|
||||||
|
@ -142,6 +142,7 @@ ProjectList.prototype = {
|
|||||||
icon.setAttribute("src", opts.icon);
|
icon.setAttribute("src", opts.icon);
|
||||||
opts.panel.appendChild(icon);
|
opts.panel.appendChild(icon);
|
||||||
opts.panel.appendChild(span);
|
opts.panel.appendChild(span);
|
||||||
|
opts.panel.setAttribute("title", opts.name);
|
||||||
} else {
|
} else {
|
||||||
opts.panel.setAttribute("label", opts.name);
|
opts.panel.setAttribute("label", opts.name);
|
||||||
opts.panel.setAttribute("image", opts.icon);
|
opts.panel.setAttribute("image", opts.icon);
|
||||||
|
@ -23,7 +23,7 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#custom-value-name {
|
#custom-value-name {
|
||||||
width: 70%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@ -38,13 +38,15 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#device-fields td {
|
#device-fields td {
|
||||||
background-color: #f1f1f1;
|
background-color: #F9F9F9;
|
||||||
border-bottom: 1px solid #ccc;
|
border-bottom: 1px solid #CCC;
|
||||||
border-right: 1px solid #fff;
|
border-right: 1px solid #FFF;
|
||||||
|
font-size: 0.75em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#device-fields td:first-child {
|
#device-fields td:first-child {
|
||||||
min-width: 400px;
|
max-width: 250px;
|
||||||
|
min-width: 150px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#device-fields td.preference-name, #device-fields td.setting-name {
|
#device-fields td.preference-name, #device-fields td.setting-name {
|
||||||
@ -65,7 +67,7 @@ header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#device-fields .custom-input {
|
#device-fields .custom-input {
|
||||||
width: 300px;
|
width: 130px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#search {
|
#search {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
font: message-box;
|
font: message-box;
|
||||||
font-size: 15px;
|
font-size: 0.9em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -28,7 +28,7 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2.5em;
|
font-size: 2em;
|
||||||
font-weight: lighter;
|
font-weight: lighter;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -60,7 +60,7 @@ th, td {
|
|||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
min-width: 130px;
|
min-width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
th:first-of-type, td:first-of-type {
|
th:first-of-type, td:first-of-type {
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
html {
|
html {
|
||||||
font: message-box;
|
font: message-box;
|
||||||
font-size: 12px;
|
font-size: 11px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,42 +53,59 @@ label,
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-item span {
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
width: 75%;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
.panel-item {
|
.panel-item {
|
||||||
padding: 3%;
|
padding: 3%;
|
||||||
display: block;
|
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%;
|
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 {
|
button.panel-item {
|
||||||
background-position: 8px 8px;
|
background-position: 5px 5px;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 14px 14px;
|
background-size: 14px 14px;
|
||||||
padding-left: 25px;
|
padding-left: 25px;
|
||||||
width: 100%;
|
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 {
|
.panel-item:disabled {
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
color: #5A5A5A;
|
color: #5A5A5A;
|
||||||
opacity: 0.5;
|
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;
|
background-color: #CCF0FD;
|
||||||
|
border-top: 1px solid #EDEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
.configure-button {
|
.configure-button {
|
||||||
@ -101,7 +118,7 @@ button.project-panel-item-refreshtabs {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 14px 14px;
|
background-size: 14px 14px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: -2px;
|
||||||
right: 0;
|
right: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
@ -162,10 +162,14 @@ panel > .panel-arrowcontainer > .panel-arrowcontent {
|
|||||||
.panel-list {
|
.panel-list {
|
||||||
display: none;
|
display: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
max-width: 250px;
|
max-width: 180px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#project-listing-panel.panel-list {
|
||||||
|
max-width: 165px;
|
||||||
|
}
|
||||||
|
|
||||||
.panel-list-wrapper {
|
.panel-list-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 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)
|
# Clear out DIST_FILES if it was set by upload-files.mk (for Android builds)
|
||||||
DIST_FILES =
|
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
|
# Helper variables to convert from MOZ_AUTOMATION_* variables to the
|
||||||
# corresponding the make target
|
# corresponding the make target
|
||||||
tier_MOZ_AUTOMATION_BUILD_SYMBOLS = buildsymbols
|
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/update-packaging: automation/pretty-update-packaging
|
||||||
|
|
||||||
automation/build: $(addprefix automation/,$(MOZ_AUTOMATION_TIERS))
|
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.
|
# Note: We have to force -j1 here, at least until bug 1036563 is fixed.
|
||||||
AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1
|
AUTOMATION_EXTRA_CMDLINE-l10n-check = -j1
|
||||||
|
@ -8,7 +8,12 @@
|
|||||||
# to be set:
|
# to be set:
|
||||||
# UPLOAD_HOST : host to upload files to
|
# UPLOAD_HOST : host to upload files to
|
||||||
# UPLOAD_USER : username on that host
|
# UPLOAD_USER : username on that host
|
||||||
|
# and one of the following:
|
||||||
# UPLOAD_PATH : path on that host to put the files in
|
# 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:
|
# And will use the following optional environment variables if set:
|
||||||
# UPLOAD_SSH_KEY : path to a ssh private key to use
|
# UPLOAD_SSH_KEY : path to a ssh private key to use
|
||||||
@ -25,18 +30,12 @@
|
|||||||
import sys, os
|
import sys, os
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
import errno
|
||||||
|
import hashlib
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
from subprocess import check_call, check_output, STDOUT
|
from subprocess import check_call, check_output, STDOUT
|
||||||
import redo
|
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):
|
def OptionalEnvironmentVariable(v):
|
||||||
"""Return the value of the environment variable named v, or None
|
"""Return the value of the environment variable named v, or None
|
||||||
if it's unset (or empty)."""
|
if it's unset (or empty)."""
|
||||||
@ -119,6 +118,33 @@ def GetRemotePath(path, local_file, base_path):
|
|||||||
dir = dir[len(base_path)+1:].replace('\\','/')
|
dir = dir[len(base_path)+1:].replace('\\','/')
|
||||||
return path + dir
|
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):
|
def GetUrlProperties(output, package):
|
||||||
# let's create a switch case using name-spaces/dict
|
# let's create a switch case using name-spaces/dict
|
||||||
# rather than a long if/else with duplicate code
|
# 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}
|
properties = {prop: 'UNKNOWN' for prop, condition in property_conditions}
|
||||||
return properties
|
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
|
"""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
|
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
|
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
|
after uploading all files, passing it the upload path, and the full paths to
|
||||||
all files uploaded.
|
all files uploaded.
|
||||||
If verbose is True, print status updates while working."""
|
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:
|
if upload_to_temp_dir:
|
||||||
path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
|
path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
|
||||||
if not path.endswith("/"):
|
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:
|
if base_path is not None:
|
||||||
base_path = os.path.abspath(base_path)
|
base_path = os.path.abspath(base_path)
|
||||||
remote_files = []
|
remote_files = []
|
||||||
|
properties = {}
|
||||||
try:
|
try:
|
||||||
for file in files:
|
for file in files:
|
||||||
file = os.path.abspath(file)
|
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)
|
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.
|
# We print since mozharness may parse URLs from the output stream.
|
||||||
print output
|
print output
|
||||||
if properties_file:
|
properties = GetUrlProperties(output, package)
|
||||||
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)
|
|
||||||
finally:
|
finally:
|
||||||
if upload_to_temp_dir:
|
if upload_to_temp_dir:
|
||||||
DoSSHCommand("rm -rf %s" % path, user, host, port=port,
|
DoSSHCommand("rm -rf %s" % path, user, host, port=port,
|
||||||
ssh_key=ssh_key)
|
ssh_key=ssh_key)
|
||||||
if verbose:
|
if verbose:
|
||||||
print "Upload complete"
|
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__':
|
if __name__ == '__main__':
|
||||||
host = RequireEnvironmentVariable('UPLOAD_HOST')
|
host = OptionalEnvironmentVariable('UPLOAD_HOST')
|
||||||
user = RequireEnvironmentVariable('UPLOAD_USER')
|
user = OptionalEnvironmentVariable('UPLOAD_USER')
|
||||||
path = OptionalEnvironmentVariable('UPLOAD_PATH')
|
path = OptionalEnvironmentVariable('UPLOAD_PATH')
|
||||||
upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
|
upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
|
||||||
port = OptionalEnvironmentVariable('UPLOAD_PORT')
|
port = OptionalEnvironmentVariable('UPLOAD_PORT')
|
||||||
@ -216,10 +256,7 @@ if __name__ == '__main__':
|
|||||||
port = int(port)
|
port = int(port)
|
||||||
key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
|
key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
|
||||||
post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
|
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 sys.platform == 'win32':
|
||||||
if path is not None:
|
if path is not None:
|
||||||
path = FixupMsysPath(path)
|
path = FixupMsysPath(path)
|
||||||
@ -240,12 +277,16 @@ if __name__ == '__main__':
|
|||||||
if len(args) < 1:
|
if len(args) < 1:
|
||||||
print "You must specify at least one file to upload"
|
print "You must specify at least one file to upload"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
if not options.properties_file:
|
||||||
|
print "You must specify a --properties-file"
|
||||||
|
sys.exit(1)
|
||||||
try:
|
try:
|
||||||
UploadFiles(user, host, path, args, base_path=options.base_path,
|
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,
|
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
|
||||||
post_upload_command=post_upload_command,
|
post_upload_command=post_upload_command,
|
||||||
properties_file=options.properties_file, package=options.package,
|
package=options.package,
|
||||||
verbose=True)
|
verbose=True)
|
||||||
|
WriteProperties(args, options.properties_file, url_properties, options.package)
|
||||||
except IOError, (strerror):
|
except IOError, (strerror):
|
||||||
print strerror
|
print strerror
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -1595,6 +1595,7 @@ if test "$GNU_CXX"; then
|
|||||||
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
# -Woverloaded-virtual - function declaration hides virtual function from base class
|
||||||
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
||||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
# -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
|
# -Wreturn-type - catches missing returns, zero false positives
|
||||||
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
||||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
# -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"
|
_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=, 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)
|
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
|
||||||
fi
|
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*
|
nsIContent*
|
||||||
ExplicitChildIterator::Get()
|
ExplicitChildIterator::Get()
|
||||||
{
|
{
|
||||||
|
@ -60,16 +60,24 @@ public:
|
|||||||
|
|
||||||
nsIContent* GetNextChild();
|
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
|
// 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
|
// whether aChildToFind was found as an explicit child prior to encountering
|
||||||
// aBound.
|
// 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
|
// It would be nice to assert that we find aChildToFind, but bz thinks that
|
||||||
// we might not find aChildToFind when called from ContentInserted
|
// we might not find aChildToFind when called from ContentInserted
|
||||||
// if first-letter frames are about.
|
// 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;
|
nsIContent* child;
|
||||||
do {
|
do {
|
||||||
child = GetNextChild();
|
child = GetNextChild();
|
||||||
|
@ -316,7 +316,7 @@ ShadowRoot::DistributeSingleNode(nsIContent* aContent)
|
|||||||
if (!isIndexFound) {
|
if (!isIndexFound) {
|
||||||
// We have still not found an index in the insertion point,
|
// We have still not found an index in the insertion point,
|
||||||
// thus it must be at the end.
|
// 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");
|
"Trying to match a node that is not a candidate to be matched");
|
||||||
insertionPoint->AppendMatchedNode(aContent);
|
insertionPoint->AppendMatchedNode(aContent);
|
||||||
}
|
}
|
||||||
|
@ -42,3 +42,7 @@ method SVGSVGElement.getElementById
|
|||||||
attribute SVGSVGElement.currentScale
|
attribute SVGSVGElement.currentScale
|
||||||
property Fill
|
property Fill
|
||||||
property FillOpacity
|
property FillOpacity
|
||||||
|
|
||||||
|
// Push API
|
||||||
|
method PushManager.subscribe
|
||||||
|
method PushSubscription.unsubscribe
|
||||||
|
@ -631,8 +631,8 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
|||||||
*aActionTaken = false;
|
*aActionTaken = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(aEventMessage == NS_CUT || aEventMessage == NS_COPY ||
|
NS_ASSERTION(aEventMessage == eCut || aEventMessage == eCopy ||
|
||||||
aEventMessage == NS_PASTE,
|
aEventMessage == ePaste,
|
||||||
"Invalid clipboard event type");
|
"Invalid clipboard event type");
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> presShell = aPresShell;
|
nsCOMPtr<nsIPresShell> presShell = aPresShell;
|
||||||
@ -688,7 +688,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
|||||||
nsRefPtr<DataTransfer> clipboardData;
|
nsRefPtr<DataTransfer> clipboardData;
|
||||||
if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
|
if (chromeShell || Preferences::GetBool("dom.event.clipboardevents.enabled", true)) {
|
||||||
clipboardData =
|
clipboardData =
|
||||||
new DataTransfer(piWindow, aEventMessage, aEventMessage == NS_PASTE,
|
new DataTransfer(piWindow, aEventMessage, aEventMessage == ePaste,
|
||||||
aClipboardType);
|
aClipboardType);
|
||||||
|
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
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
|
// 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.
|
// took care of it and cancelled the event, or the caller will handle it.
|
||||||
// Return true to indicate that the event wasn't cancelled.
|
// 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
|
// Clear and mark the clipboardData as readonly. This prevents someone
|
||||||
// from reading the clipboard contents after the paste event has fired.
|
// from reading the clipboard contents after the paste event has fired.
|
||||||
if (clipboardData) {
|
if (clipboardData) {
|
||||||
@ -743,7 +743,7 @@ nsCopySupport::FireClipboardEvent(EventMessage aEventMessage,
|
|||||||
|
|
||||||
// when cutting non-editable content, do nothing
|
// when cutting non-editable content, do nothing
|
||||||
// XXX this is probably the wrong editable flag to check
|
// 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
|
// get the data from the selection if any
|
||||||
bool isCollapsed;
|
bool isCollapsed;
|
||||||
sel->GetIsCollapsed(&isCollapsed);
|
sel->GetIsCollapsed(&isCollapsed);
|
||||||
|
@ -64,8 +64,8 @@ class nsCopySupport
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires a cut, copy or paste event, on the given presshell, depending
|
* 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
|
* on the value of aEventMessage, which should be either eCut, eCopy or
|
||||||
* NS_PASTE, and perform the default copy action if the event was not
|
* ePaste, and perform the default copy action if the event was not
|
||||||
* cancelled.
|
* cancelled.
|
||||||
*
|
*
|
||||||
* If aSelection is specified, then this selection is used as the target
|
* 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;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
WidgetSelectionEvent selectionEvent(true, NS_SELECTION_SET, widget);
|
WidgetSelectionEvent selectionEvent(true, eSetSelection, widget);
|
||||||
InitEvent(selectionEvent);
|
InitEvent(selectionEvent);
|
||||||
|
|
||||||
selectionEvent.mOffset = aOffset;
|
selectionEvent.mOffset = aOffset;
|
||||||
|
@ -8593,9 +8593,6 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
|||||||
// The misspelled key 'referer' is as per the HTTP spec
|
// The misspelled key 'referer' is as per the HTTP spec
|
||||||
rv = httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("referer"),
|
rv = httpChannel->GetRequestHeader(NS_LITERAL_CSTRING("referer"),
|
||||||
mReferrer);
|
mReferrer);
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
mReferrer.Truncate();
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *const headers[] = {
|
static const char *const headers[] = {
|
||||||
"default-style",
|
"default-style",
|
||||||
|
@ -6918,7 +6918,9 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
|
|||||||
MOZ_ASSERT(IsOuterWindow());
|
MOZ_ASSERT(IsOuterWindow());
|
||||||
|
|
||||||
if (!AreDialogsEnabled()) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7058,7 +7060,7 @@ nsGlobalWindow::PromptOuter(const nsAString& aMessage, const nsAString& aInitial
|
|||||||
SetDOMStringToNull(aReturn);
|
SetDOMStringToNull(aReturn);
|
||||||
|
|
||||||
if (!AreDialogsEnabled()) {
|
if (!AreDialogsEnabled()) {
|
||||||
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
// Return null, as if the user just canceled the prompt.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7496,6 +7498,8 @@ nsGlobalWindow::PrintOuter(ErrorResult& aError)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!AreDialogsEnabled()) {
|
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);
|
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -9553,6 +9557,8 @@ nsGlobalWindow::ShowModalDialogOuter(const nsAString& aUrl, nsIVariant* aArgumen
|
|||||||
EnsureReflowFlushAndPaint();
|
EnsureReflowFlushAndPaint();
|
||||||
|
|
||||||
if (!AreDialogsEnabled()) {
|
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);
|
aError.Throw(NS_ERROR_NOT_AVAILABLE);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -520,9 +520,9 @@ nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
|
|||||||
nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
|
nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
|
||||||
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
EventMessage eventMessage = NS_COPY;
|
EventMessage eventMessage = eCopy;
|
||||||
if (strcmp(aCommandName, "cmd_cut") == 0) {
|
if (strcmp(aCommandName, "cmd_cut") == 0) {
|
||||||
eventMessage = NS_CUT;
|
eventMessage = eCut;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool actionTaken = false;
|
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
|
// 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
|
// support other types of events, make sure that read/write privileges are
|
||||||
// checked properly within DataTransfer.
|
// 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);
|
clipboardData->SetData(aParam.mDataType, aParam.mData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,11 +105,11 @@ ClipboardEvent::GetClipboardData()
|
|||||||
if (!event->clipboardData) {
|
if (!event->clipboardData) {
|
||||||
if (mEventIsInternal) {
|
if (mEventIsInternal) {
|
||||||
event->clipboardData =
|
event->clipboardData =
|
||||||
new DataTransfer(ToSupports(this), NS_COPY, false, -1);
|
new DataTransfer(ToSupports(this), eCopy, false, -1);
|
||||||
} else {
|
} else {
|
||||||
event->clipboardData =
|
event->clipboardData =
|
||||||
new DataTransfer(ToSupports(this), event->mMessage,
|
new DataTransfer(ToSupports(this), event->mMessage,
|
||||||
event->mMessage == NS_PASTE,
|
event->mMessage == ePaste,
|
||||||
nsIClipboard::kGlobalClipboard);
|
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
|
// 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
|
// clear the readonly state. Otherwise, the data is already present. For
|
||||||
// external usage, cache the data from the native clipboard or drag.
|
// external usage, cache the data from the native clipboard or drag.
|
||||||
if (aEventMessage == NS_CUT ||
|
if (aEventMessage == eCut ||
|
||||||
aEventMessage == NS_COPY ||
|
aEventMessage == eCopy ||
|
||||||
aEventMessage == eDragStart ||
|
aEventMessage == eDragStart ||
|
||||||
aEventMessage == eLegacyDragGesture) {
|
aEventMessage == eLegacyDragGesture) {
|
||||||
mReadOnly = false;
|
mReadOnly = false;
|
||||||
} else if (mIsExternal) {
|
} else if (mIsExternal) {
|
||||||
if (aEventMessage == NS_PASTE) {
|
if (aEventMessage == ePaste) {
|
||||||
CacheExternalClipboardFormats();
|
CacheExternalClipboardFormats();
|
||||||
} else if (aEventMessage >= eDragDropEventFirst &&
|
} else if (aEventMessage >= eDragDropEventFirst &&
|
||||||
aEventMessage <= eDragDropEventLast) {
|
aEventMessage <= eDragDropEventLast) {
|
||||||
@ -271,7 +271,7 @@ DataTransfer::GetFiles(ErrorResult& aRv)
|
|||||||
{
|
{
|
||||||
if (mEventMessage != eDrop &&
|
if (mEventMessage != eDrop &&
|
||||||
mEventMessage != eLegacyDragDrop &&
|
mEventMessage != eLegacyDragDrop &&
|
||||||
mEventMessage != NS_PASTE) {
|
mEventMessage != ePaste) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,8 +543,8 @@ DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv)
|
|||||||
{
|
{
|
||||||
// Only the first item is valid for clipboard events
|
// Only the first item is valid for clipboard events
|
||||||
if (aIndex > 0 &&
|
if (aIndex > 0 &&
|
||||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||||
mEventMessage == NS_PASTE)) {
|
mEventMessage == ePaste)) {
|
||||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -584,8 +584,8 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
|
|||||||
|
|
||||||
// Only the first item is valid for clipboard events
|
// Only the first item is valid for clipboard events
|
||||||
if (aIndex > 0 &&
|
if (aIndex > 0 &&
|
||||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||||
mEventMessage == NS_PASTE)) {
|
mEventMessage == ePaste)) {
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,7 +604,7 @@ DataTransfer::MozGetDataAt(const nsAString& aFormat, uint32_t aIndex,
|
|||||||
nsIPrincipal* principal = nullptr;
|
nsIPrincipal* principal = nullptr;
|
||||||
if (mIsCrossDomainSubFrameDrop ||
|
if (mIsCrossDomainSubFrameDrop ||
|
||||||
(mEventMessage != eDrop && mEventMessage != eLegacyDragDrop &&
|
(mEventMessage != eDrop && mEventMessage != eLegacyDragDrop &&
|
||||||
mEventMessage != NS_PASTE &&
|
mEventMessage != ePaste &&
|
||||||
!nsContentUtils::IsCallerChrome())) {
|
!nsContentUtils::IsCallerChrome())) {
|
||||||
principal = nsContentUtils::SubjectPrincipal();
|
principal = nsContentUtils::SubjectPrincipal();
|
||||||
}
|
}
|
||||||
@ -696,8 +696,8 @@ DataTransfer::MozSetDataAt(const nsAString& aFormat, nsIVariant* aData,
|
|||||||
|
|
||||||
// Only the first item is valid for clipboard events
|
// Only the first item is valid for clipboard events
|
||||||
if (aIndex > 0 &&
|
if (aIndex > 0 &&
|
||||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||||
mEventMessage == NS_PASTE)) {
|
mEventMessage == ePaste)) {
|
||||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
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
|
// Only the first item is valid for clipboard events
|
||||||
if (aIndex > 0 &&
|
if (aIndex > 0 &&
|
||||||
(mEventMessage == NS_CUT || mEventMessage == NS_COPY ||
|
(mEventMessage == eCut || mEventMessage == eCopy ||
|
||||||
mEventMessage == NS_PASTE)) {
|
mEventMessage == ePaste)) {
|
||||||
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -758,8 +758,8 @@ DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
|||||||
MOZ_ASSERT(!mReadOnly);
|
MOZ_ASSERT(!mReadOnly);
|
||||||
MOZ_ASSERT(aIndex < mItems.Length());
|
MOZ_ASSERT(aIndex < mItems.Length());
|
||||||
MOZ_ASSERT(aIndex == 0 ||
|
MOZ_ASSERT(aIndex == 0 ||
|
||||||
(mEventMessage != NS_CUT && mEventMessage != NS_COPY &&
|
(mEventMessage != eCut && mEventMessage != eCopy &&
|
||||||
mEventMessage != NS_PASTE));
|
mEventMessage != ePaste));
|
||||||
|
|
||||||
nsAutoString format;
|
nsAutoString format;
|
||||||
GetRealFormat(aFormat, format);
|
GetRealFormat(aFormat, format);
|
||||||
@ -1258,7 +1258,7 @@ DataTransfer::CacheExternalDragFormats()
|
|||||||
void
|
void
|
||||||
DataTransfer::CacheExternalClipboardFormats()
|
DataTransfer::CacheExternalClipboardFormats()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mEventMessage == NS_PASTE,
|
NS_ASSERTION(mEventMessage == ePaste,
|
||||||
"caching clipboard data for invalid event");
|
"caching clipboard data for invalid event");
|
||||||
|
|
||||||
// Called during the constructor for paste events to cache the formats
|
// 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
|
// 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");
|
"clipboard event with empty data");
|
||||||
|
|
||||||
NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat);
|
NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat);
|
||||||
@ -1318,7 +1318,7 @@ DataTransfer::FillInExternalData(TransferItem& aItem, uint32_t aIndex)
|
|||||||
trans->Init(nullptr);
|
trans->Init(nullptr);
|
||||||
trans->AddDataFlavor(format);
|
trans->AddDataFlavor(format);
|
||||||
|
|
||||||
if (mEventMessage == NS_PASTE) {
|
if (mEventMessage == ePaste) {
|
||||||
MOZ_ASSERT(aIndex == 0, "index in clipboard must be 0");
|
MOZ_ASSERT(aIndex == 0, "index in clipboard must be 0");
|
||||||
|
|
||||||
nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
|
nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1");
|
||||||
|
@ -153,11 +153,11 @@ EVENT(abort,
|
|||||||
EventNameType_All,
|
EventNameType_All,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(canplay,
|
EVENT(canplay,
|
||||||
NS_CANPLAY,
|
eCanPlay,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(canplaythrough,
|
EVENT(canplaythrough,
|
||||||
NS_CANPLAYTHROUGH,
|
eCanPlayThrough,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(change,
|
EVENT(change,
|
||||||
@ -207,15 +207,15 @@ EVENT(drop,
|
|||||||
EventNameType_HTMLXUL,
|
EventNameType_HTMLXUL,
|
||||||
eDragEventClass)
|
eDragEventClass)
|
||||||
EVENT(durationchange,
|
EVENT(durationchange,
|
||||||
NS_DURATIONCHANGE,
|
eDurationChange,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(emptied,
|
EVENT(emptied,
|
||||||
NS_EMPTIED,
|
eEmptied,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(ended,
|
EVENT(ended,
|
||||||
NS_ENDED,
|
eEnded,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(input,
|
EVENT(input,
|
||||||
@ -255,15 +255,15 @@ NON_IDL_EVENT(mozbrowserafterkeyup,
|
|||||||
EventNameType_None,
|
EventNameType_None,
|
||||||
eBeforeAfterKeyboardEventClass)
|
eBeforeAfterKeyboardEventClass)
|
||||||
EVENT(loadeddata,
|
EVENT(loadeddata,
|
||||||
NS_LOADEDDATA,
|
eLoadedData,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(loadedmetadata,
|
EVENT(loadedmetadata,
|
||||||
NS_LOADEDMETADATA,
|
eLoadedMetaData,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(loadstart,
|
EVENT(loadstart,
|
||||||
NS_LOADSTART,
|
eLoadStart,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(mousedown,
|
EVENT(mousedown,
|
||||||
@ -354,23 +354,23 @@ EVENT(lostpointercapture,
|
|||||||
// Not supported yet; probably never because "wheel" is a better idea.
|
// Not supported yet; probably never because "wheel" is a better idea.
|
||||||
// EVENT(mousewheel)
|
// EVENT(mousewheel)
|
||||||
EVENT(pause,
|
EVENT(pause,
|
||||||
NS_PAUSE,
|
ePause,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(play,
|
EVENT(play,
|
||||||
NS_PLAY,
|
ePlay,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(playing,
|
EVENT(playing,
|
||||||
NS_PLAYING,
|
ePlaying,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(progress,
|
EVENT(progress,
|
||||||
NS_PROGRESS,
|
eProgress,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(ratechange,
|
EVENT(ratechange,
|
||||||
NS_RATECHANGE,
|
eRateChange,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(reset,
|
EVENT(reset,
|
||||||
@ -378,11 +378,11 @@ EVENT(reset,
|
|||||||
EventNameType_HTMLXUL,
|
EventNameType_HTMLXUL,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(seeked,
|
EVENT(seeked,
|
||||||
NS_SEEKED,
|
eSeeked,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(seeking,
|
EVENT(seeking,
|
||||||
NS_SEEKING,
|
eSeeking,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(select,
|
EVENT(select,
|
||||||
@ -394,7 +394,7 @@ EVENT(show,
|
|||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(stalled,
|
EVENT(stalled,
|
||||||
NS_STALLED,
|
eStalled,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(submit,
|
EVENT(submit,
|
||||||
@ -402,19 +402,19 @@ EVENT(submit,
|
|||||||
EventNameType_HTMLXUL,
|
EventNameType_HTMLXUL,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(suspend,
|
EVENT(suspend,
|
||||||
NS_SUSPEND,
|
eSuspend,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(timeupdate,
|
EVENT(timeupdate,
|
||||||
NS_TIMEUPDATE,
|
eTimeUpdate,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(volumechange,
|
EVENT(volumechange,
|
||||||
NS_VOLUMECHANGE,
|
eVolumeChange,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(waiting,
|
EVENT(waiting,
|
||||||
NS_WAITING,
|
eWaiting,
|
||||||
EventNameType_HTML,
|
EventNameType_HTML,
|
||||||
eBasicEventClass)
|
eBasicEventClass)
|
||||||
EVENT(wheel,
|
EVENT(wheel,
|
||||||
@ -422,15 +422,15 @@ EVENT(wheel,
|
|||||||
EventNameType_All,
|
EventNameType_All,
|
||||||
eWheelEventClass)
|
eWheelEventClass)
|
||||||
EVENT(copy,
|
EVENT(copy,
|
||||||
NS_COPY,
|
eCopy,
|
||||||
EventNameType_HTMLXUL,
|
EventNameType_HTMLXUL,
|
||||||
eClipboardEventClass)
|
eClipboardEventClass)
|
||||||
EVENT(cut,
|
EVENT(cut,
|
||||||
NS_CUT,
|
eCut,
|
||||||
EventNameType_HTMLXUL,
|
EventNameType_HTMLXUL,
|
||||||
eClipboardEventClass)
|
eClipboardEventClass)
|
||||||
EVENT(paste,
|
EVENT(paste,
|
||||||
NS_PASTE,
|
ePaste,
|
||||||
EventNameType_HTMLXUL,
|
EventNameType_HTMLXUL,
|
||||||
eClipboardEventClass)
|
eClipboardEventClass)
|
||||||
// Gecko-specific extensions that apply to elements
|
// Gecko-specific extensions that apply to elements
|
||||||
|
@ -743,7 +743,7 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||||||
InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
|
InitLineOrPageDelta(aTargetFrame, this, wheelEvent);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NS_SELECTION_SET:
|
case eSetSelection:
|
||||||
IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
|
IMEStateManager::HandleSelectionEvent(aPresContext, GetFocusedContent(),
|
||||||
aEvent->AsSelectionEvent());
|
aEvent->AsSelectionEvent());
|
||||||
break;
|
break;
|
||||||
|
@ -149,8 +149,8 @@ GetEventMessageName(EventMessage aMessage)
|
|||||||
return "NS_COMPOSITION_COMMIT_AS_IS";
|
return "NS_COMPOSITION_COMMIT_AS_IS";
|
||||||
case NS_COMPOSITION_COMMIT:
|
case NS_COMPOSITION_COMMIT:
|
||||||
return "NS_COMPOSITION_COMMIT";
|
return "NS_COMPOSITION_COMMIT";
|
||||||
case NS_SELECTION_SET:
|
case eSetSelection:
|
||||||
return "NS_SELECTION_SET";
|
return "eSetSelection";
|
||||||
default:
|
default:
|
||||||
return "unacceptable event message";
|
return "unacceptable event message";
|
||||||
}
|
}
|
||||||
|
@ -291,14 +291,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder,
|
|||||||
|
|
||||||
mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread());
|
mMetadataManager.Connect(mReader->TimedMetadataEvent(), OwnerThread());
|
||||||
|
|
||||||
nsRefPtr<MediaDecoderStateMachine> self = this;
|
mMediaSink = CreateAudioSink();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaDecoderStateMachine::~MediaDecoderStateMachine()
|
MediaDecoderStateMachine::~MediaDecoderStateMachine()
|
||||||
@ -348,6 +341,19 @@ MediaDecoderStateMachine::InitializationTask()
|
|||||||
SameOriginMediaChanged();
|
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()
|
bool MediaDecoderStateMachine::HasFutureAudio()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
@ -377,7 +383,7 @@ int64_t MediaDecoderStateMachine::GetDecodedAudioDuration()
|
|||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
int64_t audioDecoded = AudioQueue().Duration();
|
int64_t audioDecoded = AudioQueue().Duration();
|
||||||
if (mAudioSink->IsStarted()) {
|
if (mMediaSink->IsStarted()) {
|
||||||
audioDecoded += AudioEndTime() - GetMediaTime();
|
audioDecoded += AudioEndTime() - GetMediaTime();
|
||||||
}
|
}
|
||||||
return audioDecoded;
|
return audioDecoded;
|
||||||
@ -387,7 +393,6 @@ void MediaDecoderStateMachine::DiscardStreamData()
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
MOZ_ASSERT(!mAudioSink->IsStarted(), "Should've been stopped in RunStateMachine()");
|
|
||||||
|
|
||||||
const auto clockTime = GetClock();
|
const auto clockTime = GetClock();
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -1077,8 +1082,7 @@ void MediaDecoderStateMachine::MaybeStartPlayback()
|
|||||||
SetPlayStartTime(TimeStamp::Now());
|
SetPlayStartTime(TimeStamp::Now());
|
||||||
MOZ_ASSERT(IsPlaying());
|
MOZ_ASSERT(IsPlaying());
|
||||||
|
|
||||||
StartAudioSink();
|
StartMediaSink();
|
||||||
StartDecodedStream();
|
|
||||||
|
|
||||||
DispatchDecodeTasksIfNeeded();
|
DispatchDecodeTasksIfNeeded();
|
||||||
}
|
}
|
||||||
@ -1152,8 +1156,7 @@ void MediaDecoderStateMachine::VolumeChanged()
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
mAudioSink->SetVolume(mVolume);
|
mMediaSink->SetVolume(mVolume);
|
||||||
mStreamSink->SetVolume(mVolume);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaDecoderStateMachine::RecomputeDuration()
|
void MediaDecoderStateMachine::RecomputeDuration()
|
||||||
@ -1273,7 +1276,7 @@ void MediaDecoderStateMachine::Shutdown()
|
|||||||
|
|
||||||
Reset();
|
Reset();
|
||||||
|
|
||||||
mAudioSink->Shutdown();
|
mMediaSink->Shutdown();
|
||||||
|
|
||||||
// Shut down our start time rendezvous.
|
// Shut down our start time rendezvous.
|
||||||
if (mStartTimeRendezvous) {
|
if (mStartTimeRendezvous) {
|
||||||
@ -1466,15 +1469,15 @@ MediaDecoderStateMachine::Seek(SeekTarget aTarget)
|
|||||||
return mPendingSeek.mPromise.Ensure(__func__);
|
return mPendingSeek.mPromise.Ensure(__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaDecoderStateMachine::StopAudioSink()
|
void MediaDecoderStateMachine::StopMediaSink()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
|
|
||||||
if (mAudioSink->IsStarted()) {
|
if (mMediaSink->IsStarted()) {
|
||||||
DECODER_LOG("Stop AudioSink");
|
DECODER_LOG("Stop MediaSink");
|
||||||
mAudioSink->Stop();
|
mMediaSink->Stop();
|
||||||
mAudioSinkPromise.DisconnectIfExists();
|
mMediaSinkPromise.DisconnectIfExists();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1752,59 +1755,25 @@ MediaDecoderStateMachine::RequestVideoData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaDecoderStateMachine::StartAudioSink()
|
MediaDecoderStateMachine::StartMediaSink()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
if (mAudioCaptured) {
|
|
||||||
MOZ_ASSERT(!mAudioSink->IsStarted());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mAudioSink->IsStarted()) {
|
if (!mMediaSink->IsStarted()) {
|
||||||
mAudioCompleted = false;
|
mAudioCompleted = false;
|
||||||
mAudioSink->Start(GetMediaTime(), mInfo);
|
mMediaSink->Start(GetMediaTime(), mInfo);
|
||||||
|
|
||||||
auto promise = mAudioSink->OnEnded(TrackInfo::kAudioTrack);
|
auto promise = mMediaSink->OnEnded(TrackInfo::kAudioTrack);
|
||||||
if (promise) {
|
if (promise) {
|
||||||
mAudioSinkPromise.Begin(promise->Then(
|
mMediaSinkPromise.Begin(promise->Then(
|
||||||
OwnerThread(), __func__, this,
|
OwnerThread(), __func__, this,
|
||||||
&MediaDecoderStateMachine::OnAudioSinkComplete,
|
&MediaDecoderStateMachine::OnMediaSinkComplete,
|
||||||
&MediaDecoderStateMachine::OnAudioSinkError));
|
&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()
|
int64_t MediaDecoderStateMachine::AudioDecodedUsecs()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
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
|
// 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
|
// already decoded and pushed to the hardware, plus the amount of audio
|
||||||
// data waiting to be pushed to the hardware.
|
// 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
|
// Currently for real time streams, AudioQueue().Duration() produce
|
||||||
// wrong values (Bug 1114434), so we use frame counts to calculate duration.
|
// wrong values (Bug 1114434), so we use frame counts to calculate duration.
|
||||||
@ -1842,7 +1811,7 @@ bool MediaDecoderStateMachine::OutOfDecodedAudio()
|
|||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
return IsAudioDecoding() && !AudioQueue().IsFinished() &&
|
return IsAudioDecoding() && !AudioQueue().IsFinished() &&
|
||||||
AudioQueue().GetSize() == 0 &&
|
AudioQueue().GetSize() == 0 &&
|
||||||
!mAudioSink->HasUnplayedFrames(TrackInfo::kAudioTrack);
|
!mMediaSink->HasUnplayedFrames(TrackInfo::kAudioTrack);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaDecoderStateMachine::HasLowUndecodedData()
|
bool MediaDecoderStateMachine::HasLowUndecodedData()
|
||||||
@ -2416,8 +2385,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine()
|
|||||||
mSentPlaybackEndedEvent = true;
|
mSentPlaybackEndedEvent = true;
|
||||||
|
|
||||||
// MediaSink::GetEndTime() must be called before stopping playback.
|
// MediaSink::GetEndTime() must be called before stopping playback.
|
||||||
StopAudioSink();
|
StopMediaSink();
|
||||||
StopDecodedStream();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@ -2443,11 +2411,10 @@ MediaDecoderStateMachine::Reset()
|
|||||||
mState == DECODER_STATE_DORMANT ||
|
mState == DECODER_STATE_DORMANT ||
|
||||||
mState == DECODER_STATE_DECODING_NONE);
|
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
|
// outside of the decoder monitor while we are clearing the queue and causes
|
||||||
// crash for no samples to be popped.
|
// crash for no samples to be popped.
|
||||||
StopAudioSink();
|
StopMediaSink();
|
||||||
StopDecodedStream();
|
|
||||||
|
|
||||||
mVideoFrameEndTime = -1;
|
mVideoFrameEndTime = -1;
|
||||||
mDecodedVideoEndTime = -1;
|
mDecodedVideoEndTime = -1;
|
||||||
@ -2585,11 +2552,7 @@ int64_t MediaDecoderStateMachine::GetClock(TimeStamp* aTimeStamp) const
|
|||||||
if (!IsPlaying()) {
|
if (!IsPlaying()) {
|
||||||
clock_time = mPlayDuration;
|
clock_time = mPlayDuration;
|
||||||
} else {
|
} else {
|
||||||
if (mAudioCaptured) {
|
clock_time = mMediaSink->GetPosition(&t);
|
||||||
clock_time = mStreamSink->GetPosition(&t);
|
|
||||||
} else {
|
|
||||||
clock_time = mAudioSink->GetPosition(&t);
|
|
||||||
}
|
|
||||||
NS_ASSERTION(GetMediaTime() <= clock_time, "Clock should go forwards.");
|
NS_ASSERTION(GetMediaTime() <= clock_time, "Clock should go forwards.");
|
||||||
}
|
}
|
||||||
if (aTimeStamp) {
|
if (aTimeStamp) {
|
||||||
@ -2879,9 +2842,7 @@ void MediaDecoderStateMachine::SetPlayStartTime(const TimeStamp& aTimeStamp)
|
|||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
mPlayStartTime = aTimeStamp;
|
mPlayStartTime = aTimeStamp;
|
||||||
|
mMediaSink->SetPlaying(!mPlayStartTime.IsNull());
|
||||||
mAudioSink->SetPlaying(!mPlayStartTime.IsNull());
|
|
||||||
mStreamSink->SetPlaying(!mPlayStartTime.IsNull());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder()
|
void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder()
|
||||||
@ -2959,7 +2920,7 @@ MediaDecoderStateMachine::LogicalPlaybackRateChanged()
|
|||||||
}
|
}
|
||||||
|
|
||||||
mPlaybackRate = mLogicalPlaybackRate;
|
mPlaybackRate = mLogicalPlaybackRate;
|
||||||
mAudioSink->SetPlaybackRate(mPlaybackRate);
|
mMediaSink->SetPlaybackRate(mPlaybackRate);
|
||||||
|
|
||||||
ScheduleStateMachine();
|
ScheduleStateMachine();
|
||||||
}
|
}
|
||||||
@ -2968,7 +2929,7 @@ void MediaDecoderStateMachine::PreservesPitchChanged()
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
mAudioSink->SetPreservesPitch(mPreservesPitch);
|
mMediaSink->SetPreservesPitch(mPreservesPitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaDecoderStateMachine::IsShutdown()
|
bool MediaDecoderStateMachine::IsShutdown()
|
||||||
@ -2982,33 +2943,33 @@ MediaDecoderStateMachine::AudioEndTime() const
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
AssertCurrentThreadInMonitor();
|
AssertCurrentThreadInMonitor();
|
||||||
if (mAudioSink->IsStarted()) {
|
if (mMediaSink->IsStarted()) {
|
||||||
return mAudioSink->GetEndTime(TrackInfo::kAudioTrack);
|
return mMediaSink->GetEndTime(TrackInfo::kAudioTrack);
|
||||||
} else if (mAudioCaptured) {
|
|
||||||
return mStreamSink->GetEndTime(TrackInfo::kAudioTrack);
|
|
||||||
}
|
}
|
||||||
MOZ_ASSERT(!HasAudio());
|
MOZ_ASSERT(!HasAudio());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaDecoderStateMachine::OnAudioSinkComplete()
|
void MediaDecoderStateMachine::OnMediaSinkComplete()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
|
|
||||||
|
|
||||||
mAudioSinkPromise.Complete();
|
mMediaSinkPromise.Complete();
|
||||||
mAudioCompleted = true;
|
// 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());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
MOZ_ASSERT(!mAudioCaptured, "Should be disconnected when capturing audio.");
|
|
||||||
|
|
||||||
mAudioSinkPromise.Complete();
|
mMediaSinkPromise.Complete();
|
||||||
mAudioCompleted = true;
|
// Set true only when we have audio.
|
||||||
|
mAudioCompleted = mInfo.HasAudio();
|
||||||
|
|
||||||
// Make the best effort to continue playback when there is video.
|
// Make the best effort to continue playback when there is video.
|
||||||
if (HasVideo()) {
|
if (HasVideo()) {
|
||||||
@ -3021,31 +2982,41 @@ void MediaDecoderStateMachine::OnAudioSinkError()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MediaDecoderStateMachine::OnDecodedStreamFinish()
|
MediaDecoderStateMachine::SetAudioCaptured(bool aCaptured)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||||
MOZ_ASSERT(mAudioCaptured, "Audio should be captured.");
|
|
||||||
|
|
||||||
mDecodedStreamPromise.Complete();
|
if (aCaptured == mAudioCaptured) {
|
||||||
if (mInfo.HasAudio()) {
|
return;
|
||||||
mAudioCompleted = true;
|
|
||||||
}
|
}
|
||||||
// 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();
|
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
|
uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(OnTaskQueue());
|
MOZ_ASSERT(OnTaskQueue());
|
||||||
@ -3055,55 +3026,15 @@ uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const
|
|||||||
: std::max<uint32_t>(sVideoQueueDefaultSize, MIN_VIDEO_QUEUE_SIZE);
|
: 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,
|
void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream,
|
||||||
bool aFinishWhenEnded)
|
bool aFinishWhenEnded)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
|
DECODER_LOG("AddOutputStream aStream=%p!", aStream);
|
||||||
mStreamSink->AddOutput(aStream, aFinishWhenEnded);
|
mStreamSink->AddOutput(aStream, aFinishWhenEnded);
|
||||||
DispatchAudioCaptured();
|
nsCOMPtr<nsIRunnable> r = NS_NewRunnableMethodWithArg<bool>(
|
||||||
|
this, &MediaDecoderStateMachine::SetAudioCaptured, true);
|
||||||
|
OwnerThread()->Dispatch(r.forget());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
|
void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
|
||||||
@ -3112,7 +3043,9 @@ void MediaDecoderStateMachine::RemoveOutputStream(MediaStream* aStream)
|
|||||||
DECODER_LOG("RemoveOutputStream=%p!", aStream);
|
DECODER_LOG("RemoveOutputStream=%p!", aStream);
|
||||||
mStreamSink->RemoveOutput(aStream);
|
mStreamSink->RemoveOutput(aStream);
|
||||||
if (!mStreamSink->HasConsumers()) {
|
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.
|
// constructor immediately after the task queue is created.
|
||||||
void InitializationTask();
|
void InitializationTask();
|
||||||
|
|
||||||
void DispatchAudioCaptured();
|
void SetAudioCaptured(bool aCaptured);
|
||||||
void DispatchAudioUncaptured();
|
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
public:
|
public:
|
||||||
@ -489,19 +488,17 @@ protected:
|
|||||||
// state machine thread.
|
// state machine thread.
|
||||||
void UpdateRenderedVideoFrames();
|
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.
|
// The decoder monitor must be held with exactly one lock count.
|
||||||
// Called on the state machine thread.
|
// 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.
|
// The decoder monitor must be held with exactly one lock count.
|
||||||
// Called on the state machine thread.
|
// Called on the state machine thread.
|
||||||
void StartAudioSink();
|
void StartMediaSink();
|
||||||
|
|
||||||
void StopDecodedStream();
|
|
||||||
|
|
||||||
void StartDecodedStream();
|
|
||||||
|
|
||||||
// Notification method invoked when mPlayState changes.
|
// Notification method invoked when mPlayState changes.
|
||||||
void PlayStateChanged();
|
void PlayStateChanged();
|
||||||
@ -648,16 +645,12 @@ protected:
|
|||||||
void SetPlayStartTime(const TimeStamp& aTimeStamp);
|
void SetPlayStartTime(const TimeStamp& aTimeStamp);
|
||||||
|
|
||||||
private:
|
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.
|
// and the sink is shutting down.
|
||||||
void OnAudioSinkComplete();
|
void OnMediaSinkComplete();
|
||||||
|
|
||||||
// Rejected by the AudioSink to signal errors.
|
// Rejected by the MediaSink to signal errors.
|
||||||
void OnAudioSinkError();
|
void OnMediaSinkError();
|
||||||
|
|
||||||
void OnDecodedStreamFinish();
|
|
||||||
|
|
||||||
void OnDecodedStreamError();
|
|
||||||
|
|
||||||
// Return true if the video decoder's decode speed can not catch up the
|
// Return true if the video decoder's decode speed can not catch up the
|
||||||
// play time.
|
// play time.
|
||||||
@ -977,15 +970,15 @@ private:
|
|||||||
// Media Fragment end time in microseconds. Access controlled by decoder monitor.
|
// Media Fragment end time in microseconds. Access controlled by decoder monitor.
|
||||||
int64_t mFragmentEndTime;
|
int64_t mFragmentEndTime;
|
||||||
|
|
||||||
// The audio sink resource. Used on the state machine thread.
|
// The media sink resource. Used on the state machine thread.
|
||||||
nsRefPtr<media::MediaSink> mAudioSink;
|
nsRefPtr<media::MediaSink> mMediaSink;
|
||||||
|
|
||||||
// The reader, don't call its methods with the decoder monitor held.
|
// The reader, don't call its methods with the decoder monitor held.
|
||||||
// This is created in the state machine's constructor.
|
// This is created in the state machine's constructor.
|
||||||
nsRefPtr<MediaDecoderReader> mReader;
|
nsRefPtr<MediaDecoderReader> mReader;
|
||||||
|
|
||||||
// The end time of the last audio frame that's been pushed onto the audio sink
|
// The end time of the last audio frame that's been pushed onto the media sink
|
||||||
// or DecodedStream in microseconds. This will approximately be the end time
|
// in microseconds. This will approximately be the end time
|
||||||
// of the audio stream, unless another frame is pushed to the hardware.
|
// of the audio stream, unless another frame is pushed to the hardware.
|
||||||
int64_t AudioEndTime() const;
|
int64_t AudioEndTime() const;
|
||||||
|
|
||||||
@ -1270,8 +1263,7 @@ private:
|
|||||||
// Media data resource from the decoder.
|
// Media data resource from the decoder.
|
||||||
nsRefPtr<MediaResource> mResource;
|
nsRefPtr<MediaResource> mResource;
|
||||||
|
|
||||||
MozPromiseRequestHolder<GenericPromise> mAudioSinkPromise;
|
MozPromiseRequestHolder<GenericPromise> mMediaSinkPromise;
|
||||||
MozPromiseRequestHolder<GenericPromise> mDecodedStreamPromise;
|
|
||||||
|
|
||||||
MediaEventListener mAudioQueueListener;
|
MediaEventListener mAudioQueueListener;
|
||||||
MediaEventListener mVideoQueueListener;
|
MediaEventListener mVideoQueueListener;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
SimpleTest.waitForExplicitFinish();
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
// Turn off the authentication dialog blocking for this test.
|
// 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 = [
|
var tests = [
|
||||||
// Not the same origin no CORS asked for, should have silence
|
// Not the same origin no CORS asked for, should have silence
|
||||||
|
@ -36,6 +36,9 @@
|
|||||||
#include "WorkerPrivate.h"
|
#include "WorkerPrivate.h"
|
||||||
#include "WorkerRunnable.h"
|
#include "WorkerRunnable.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
|
#ifdef MOZ_CRASHREPORTER
|
||||||
|
#include "nsExceptionHandler.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
@ -536,10 +539,10 @@ Promise::JSCallback(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
|
|||||||
PromiseCallback::Task task = static_cast<PromiseCallback::Task>(v.toInt32());
|
PromiseCallback::Task task = static_cast<PromiseCallback::Task>(v.toInt32());
|
||||||
|
|
||||||
if (task == PromiseCallback::Resolve) {
|
if (task == PromiseCallback::Resolve) {
|
||||||
promise->MaybeResolveInternal(aCx, args.get(0));
|
|
||||||
if (!promise->CaptureStack(aCx, promise->mFullfillmentStack)) {
|
if (!promise->CaptureStack(aCx, promise->mFullfillmentStack)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
promise->MaybeResolveInternal(aCx, args.get(0));
|
||||||
} else {
|
} else {
|
||||||
promise->MaybeRejectInternal(aCx, args.get(0));
|
promise->MaybeRejectInternal(aCx, args.get(0));
|
||||||
if (!promise->CaptureStack(aCx, promise->mRejectionStack)) {
|
if (!promise->CaptureStack(aCx, promise->mRejectionStack)) {
|
||||||
@ -1342,6 +1345,29 @@ Promise::RejectInternal(JSContext* aCx,
|
|||||||
void
|
void
|
||||||
Promise::Settle(JS::Handle<JS::Value> aValue, PromiseState aState)
|
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()) {
|
if (mGlobal->IsDying()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -628,7 +628,6 @@ nsCORSListenerProxy::CheckRequestApproved(nsIRequest* aRequest)
|
|||||||
|
|
||||||
// The "Access-Control-Allow-Headers" header contains a comma separated
|
// The "Access-Control-Allow-Headers" header contains a comma separated
|
||||||
// list of header names.
|
// list of header names.
|
||||||
headerVal.Truncate();
|
|
||||||
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
|
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
|
||||||
headerVal);
|
headerVal);
|
||||||
nsTArray<nsCString> headers;
|
nsTArray<nsCString> headers;
|
||||||
@ -1130,7 +1129,6 @@ nsCORSPreflightListener::AddResultToCache(nsIRequest *aRequest)
|
|||||||
|
|
||||||
// The "Access-Control-Allow-Methods" header contains a comma separated
|
// The "Access-Control-Allow-Methods" header contains a comma separated
|
||||||
// list of method names.
|
// list of method names.
|
||||||
headerVal.Truncate();
|
|
||||||
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
|
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Methods"),
|
||||||
headerVal);
|
headerVal);
|
||||||
|
|
||||||
@ -1161,7 +1159,6 @@ nsCORSPreflightListener::AddResultToCache(nsIRequest *aRequest)
|
|||||||
|
|
||||||
// The "Access-Control-Allow-Headers" header contains a comma separated
|
// The "Access-Control-Allow-Headers" header contains a comma separated
|
||||||
// list of method names.
|
// list of method names.
|
||||||
headerVal.Truncate();
|
|
||||||
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
|
http->GetResponseHeader(NS_LITERAL_CSTRING("Access-Control-Allow-Headers"),
|
||||||
headerVal);
|
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 <pthread.h>
|
||||||
#include <hardware/gps.h>
|
#include <hardware/gps.h>
|
||||||
|
|
||||||
|
#include "GeolocationUtil.h"
|
||||||
|
#include "mozstumbler/MozStumbler.h"
|
||||||
#include "mozilla/Constants.h"
|
#include "mozilla/Constants.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
@ -88,71 +90,6 @@ AGpsCallbacks GonkGPSGeolocationProvider::mAGPSCallbacks;
|
|||||||
AGpsRilCallbacks GonkGPSGeolocationProvider::mAGPSRILCallbacks;
|
AGpsRilCallbacks GonkGPSGeolocationProvider::mAGPSRILCallbacks;
|
||||||
#endif // MOZ_B2G_RIL
|
#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
|
void
|
||||||
GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
|
GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
|
||||||
@ -211,35 +148,7 @@ GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
|
|||||||
nsRefPtr<UpdateLocationEvent> event = new UpdateLocationEvent(somewhere);
|
nsRefPtr<UpdateLocationEvent> event = new UpdateLocationEvent(somewhere);
|
||||||
NS_DispatchToMainThread(event);
|
NS_DispatchToMainThread(event);
|
||||||
|
|
||||||
const double kMinChangeInMeters = 30;
|
MozStumble(somewhere);
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -33,6 +33,7 @@ XPIDL_SOURCES += [
|
|||||||
XPIDL_MODULE = 'dom_system_gonk'
|
XPIDL_MODULE = 'dom_system_gonk'
|
||||||
|
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
|
'GeolocationUtil.h',
|
||||||
'GonkGPSGeolocationProvider.h',
|
'GonkGPSGeolocationProvider.h',
|
||||||
'mozstumbler/MozStumbler.h',
|
'mozstumbler/MozStumbler.h',
|
||||||
'nsVolume.h',
|
'nsVolume.h',
|
||||||
@ -43,6 +44,7 @@ UNIFIED_SOURCES += [
|
|||||||
'AudioManager.cpp',
|
'AudioManager.cpp',
|
||||||
'AutoMounter.cpp',
|
'AutoMounter.cpp',
|
||||||
'AutoMounterSetting.cpp',
|
'AutoMounterSetting.cpp',
|
||||||
|
'GeolocationUtil.cpp',
|
||||||
'GonkGPSGeolocationProvider.cpp',
|
'GonkGPSGeolocationProvider.cpp',
|
||||||
'MozMtpDatabase.cpp',
|
'MozMtpDatabase.cpp',
|
||||||
'MozMtpServer.cpp',
|
'MozMtpServer.cpp',
|
||||||
|
@ -5,12 +5,22 @@
|
|||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "MozStumbler.h"
|
#include "MozStumbler.h"
|
||||||
|
#include "nsDataHashtable.h"
|
||||||
#include "nsGeoPosition.h"
|
#include "nsGeoPosition.h"
|
||||||
|
#include "nsNetCID.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "StumblerLogging.h"
|
#include "StumblerLogging.h"
|
||||||
#include "WriteStumbleOnThread.h"
|
#include "WriteStumbleOnThread.h"
|
||||||
#include "nsNetCID.h"
|
#include "../GeolocationUtil.h"
|
||||||
#include "nsDataHashtable.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;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
@ -18,6 +28,101 @@ using namespace mozilla::dom;
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(StumblerInfo, nsICellInfoListCallback, nsIWifiScanResultsReady)
|
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
|
void
|
||||||
StumblerInfo::SetWifiInfoResponseReceived()
|
StumblerInfo::SetWifiInfoResponseReceived()
|
||||||
{
|
{
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
class nsGeoPosition;
|
class nsGeoPosition;
|
||||||
|
|
||||||
|
void MozStumble(nsGeoPosition* position);
|
||||||
|
|
||||||
class StumblerInfo final : public nsICellInfoListCallback,
|
class StumblerInfo final : public nsICellInfoListCallback,
|
||||||
public nsIWifiScanResultsReady
|
public nsIWifiScanResultsReady
|
||||||
{
|
{
|
||||||
|
@ -7,14 +7,15 @@
|
|||||||
#include "UploadStumbleRunnable.h"
|
#include "UploadStumbleRunnable.h"
|
||||||
#include "StumblerLogging.h"
|
#include "StumblerLogging.h"
|
||||||
#include "mozilla/dom/Event.h"
|
#include "mozilla/dom/Event.h"
|
||||||
|
#include "nsIInputStream.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIURLFormatter.h"
|
#include "nsIURLFormatter.h"
|
||||||
#include "nsIVariant.h"
|
#include "nsIVariant.h"
|
||||||
#include "nsIXMLHttpRequest.h"
|
#include "nsIXMLHttpRequest.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
UploadStumbleRunnable::UploadStumbleRunnable(const nsACString& aUploadData)
|
UploadStumbleRunnable::UploadStumbleRunnable(nsIInputStream* aUploadData)
|
||||||
: mUploadData(aUploadData)
|
: mUploadInputStream(aUploadData)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ UploadStumbleRunnable::Upload()
|
|||||||
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance("@mozilla.org/variant;1", &rv);
|
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance("@mozilla.org/variant;1", &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
rv = variant->SetAsACString(mUploadData);
|
rv = variant->SetAsISupports(mUploadInputStream);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIXMLHttpRequest> xhr = do_CreateInstance(NS_XMLHTTPREQUEST_CONTRACTID, &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());
|
rv = xhr->Open(NS_LITERAL_CSTRING("POST"), NS_ConvertUTF16toUTF8(url), false, EmptyString(), EmptyString());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
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);
|
xhr->SetMozBackgroundRequest(true);
|
||||||
// 60s timeout
|
// 60s timeout
|
||||||
xhr->SetTimeout(60 * 1000);
|
xhr->SetTimeout(60 * 1000);
|
||||||
|
|
||||||
nsCOMPtr<EventTarget> target(do_QueryInterface(xhr));
|
nsCOMPtr<EventTarget> target(do_QueryInterface(xhr));
|
||||||
nsRefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr, mUploadData.Length());
|
nsRefPtr<nsIDOMEventListener> listener = new UploadEventListener(xhr);
|
||||||
|
|
||||||
const char* const sEventStrings[] = {
|
const char* const sEventStrings[] = {
|
||||||
// nsIXMLHttpRequestEventTarget event types
|
// nsIXMLHttpRequestEventTarget event types
|
||||||
@ -93,8 +94,8 @@ UploadStumbleRunnable::Upload()
|
|||||||
|
|
||||||
NS_IMPL_ISUPPORTS(UploadEventListener, nsIDOMEventListener)
|
NS_IMPL_ISUPPORTS(UploadEventListener, nsIDOMEventListener)
|
||||||
|
|
||||||
UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR, int64_t aFileSize)
|
UploadEventListener::UploadEventListener(nsIXMLHttpRequest* aXHR)
|
||||||
: mXHR(aXHR), mFileSize(aFileSize)
|
: mXHR(aXHR)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +110,7 @@ UploadEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type.EqualsLiteral("load")) {
|
if (type.EqualsLiteral("load")) {
|
||||||
STUMBLER_DBG("Got load Event : size %lld", mFileSize);
|
STUMBLER_DBG("Got load Event\n");
|
||||||
} else if (type.EqualsLiteral("error") && mXHR) {
|
} else if (type.EqualsLiteral("error") && mXHR) {
|
||||||
STUMBLER_ERR("Upload Error");
|
STUMBLER_ERR("Upload Error");
|
||||||
} else {
|
} else {
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "nsIDOMEventListener.h"
|
#include "nsIDOMEventListener.h"
|
||||||
|
|
||||||
class nsIXMLHttpRequest;
|
class nsIXMLHttpRequest;
|
||||||
|
class nsIInputStream;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This runnable is managed by WriteStumbleOnThread only, see that class
|
This runnable is managed by WriteStumbleOnThread only, see that class
|
||||||
@ -19,12 +20,12 @@ class nsIXMLHttpRequest;
|
|||||||
class UploadStumbleRunnable final : public nsRunnable
|
class UploadStumbleRunnable final : public nsRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit UploadStumbleRunnable(const nsACString& aUploadData);
|
explicit UploadStumbleRunnable(nsIInputStream* aUploadInputStream);
|
||||||
|
|
||||||
NS_IMETHOD Run() override;
|
NS_IMETHOD Run() override;
|
||||||
private:
|
private:
|
||||||
virtual ~UploadStumbleRunnable() {}
|
virtual ~UploadStumbleRunnable() {}
|
||||||
const nsCString mUploadData;
|
nsCOMPtr<nsIInputStream> mUploadInputStream;
|
||||||
nsresult Upload();
|
nsresult Upload();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ private:
|
|||||||
class UploadEventListener : public nsIDOMEventListener
|
class UploadEventListener : public nsIDOMEventListener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UploadEventListener(nsIXMLHttpRequest* aXHR, int64_t aFileSize);
|
UploadEventListener(nsIXMLHttpRequest* aXHR);
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIDOMEVENTLISTENER
|
NS_DECL_NSIDOMEVENTLISTENER
|
||||||
@ -40,7 +41,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual ~UploadEventListener() {}
|
virtual ~UploadEventListener() {}
|
||||||
nsCOMPtr<nsIXMLHttpRequest> mXHR;
|
nsCOMPtr<nsIXMLHttpRequest> mXHR;
|
||||||
int64_t mFileSize;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
#define ONEDAY_IN_MSEC (24 * 60 * 60 * 1000)
|
#define ONEDAY_IN_MSEC (24 * 60 * 60 * 1000)
|
||||||
#define MAX_UPLOAD_ATTEMPTS 20
|
#define MAX_UPLOAD_ATTEMPTS 20
|
||||||
|
|
||||||
mozilla::Atomic<bool> WriteStumbleOnThread::sIsUploading(false);
|
mozilla::Atomic<bool> WriteStumbleOnThread::sIsFileWaitingForUpload(false);
|
||||||
mozilla::Atomic<bool> WriteStumbleOnThread::sIsAlreadyRunning(false);
|
mozilla::Atomic<bool> WriteStumbleOnThread::sIsAlreadyRunning(false);
|
||||||
WriteStumbleOnThread::UploadFreqGuard WriteStumbleOnThread::sUploadFreqGuard = {0};
|
WriteStumbleOnThread::UploadFreqGuard WriteStumbleOnThread::sUploadFreqGuard = {0};
|
||||||
|
|
||||||
#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json")
|
#define FILENAME_INPROGRESS NS_LITERAL_CSTRING("stumbles.json.gz")
|
||||||
#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json")
|
#define FILENAME_COMPLETED NS_LITERAL_CSTRING("stumbles.done.json.gz")
|
||||||
#define OUTPUT_DIR NS_LITERAL_CSTRING("mozstumbler")
|
#define OUTPUT_DIR NS_LITERAL_CSTRING("mozstumbler")
|
||||||
|
|
||||||
class DeleteRunnable : public nsRunnable
|
class DeleteRunnable : public nsRunnable
|
||||||
@ -42,7 +42,8 @@ class DeleteRunnable : public nsRunnable
|
|||||||
tmpFile->Remove(true);
|
tmpFile->Remove(true);
|
||||||
}
|
}
|
||||||
// critically, this sets this flag to false so writing can happen again
|
// critically, this sets this flag to false so writing can happen again
|
||||||
WriteStumbleOnThread::sIsUploading = false;
|
WriteStumbleOnThread::sIsAlreadyRunning = false;
|
||||||
|
WriteStumbleOnThread::sIsFileWaitingForUpload = false;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,11 +51,17 @@ class DeleteRunnable : public nsRunnable
|
|||||||
~DeleteRunnable() {}
|
~DeleteRunnable() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
WriteStumbleOnThread::IsFileWaitingForUpload()
|
||||||
|
{
|
||||||
|
return sIsFileWaitingForUpload;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
|
WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
|
||||||
{
|
{
|
||||||
if (!deleteUploadFile) {
|
if (!deleteUploadFile) {
|
||||||
sIsUploading = false;
|
sIsAlreadyRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,15 +71,6 @@ WriteStumbleOnThread::UploadEnded(bool deleteUploadFile)
|
|||||||
target->Dispatch(event, NS_DISPATCH_NORMAL);
|
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
|
void
|
||||||
WriteStumbleOnThread::WriteJSON(Partition aPart)
|
WriteStumbleOnThread::WriteJSON(Partition aPart)
|
||||||
{
|
{
|
||||||
@ -87,10 +85,10 @@ WriteStumbleOnThread::WriteJSON(Partition aPart)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIFileOutputStream> ostream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
|
nsRefPtr<nsGZFileWriter> gzWriter = new nsGZFileWriter(nsGZFileWriter::Append);
|
||||||
rv = ostream->Init(tmpFile, PR_WRONLY | PR_APPEND, 0666, 0);
|
rv = gzWriter->Init(tmpFile);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
STUMBLER_ERR("Open a file for stumble failed");
|
STUMBLER_ERR("gzWriter init failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,8 +103,8 @@ WriteStumbleOnThread::WriteJSON(Partition aPart)
|
|||||||
|
|
||||||
// Need to add "]}" after the last item
|
// Need to add "]}" after the last item
|
||||||
if (aPart == Partition::End) {
|
if (aPart == Partition::End) {
|
||||||
DUMP(ostream, "]}");
|
gzWriter->Write("]}");
|
||||||
rv = ostream->Close();
|
rv = gzWriter->Finish();
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
STUMBLER_ERR("ostream finish failed");
|
STUMBLER_ERR("ostream finish failed");
|
||||||
}
|
}
|
||||||
@ -136,14 +134,14 @@ WriteStumbleOnThread::WriteJSON(Partition aPart)
|
|||||||
|
|
||||||
// Need to add "{items:[" before the first item
|
// Need to add "{items:[" before the first item
|
||||||
if (aPart == Partition::Begining) {
|
if (aPart == Partition::Begining) {
|
||||||
DUMP(ostream, "{\"items\":[{");
|
gzWriter->Write("{\"items\":[{");
|
||||||
} else if (aPart == Partition::Middle) {
|
} 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})
|
// one item is ended with '}' (e.g. {item})
|
||||||
DUMP(ostream, "}");
|
gzWriter->Write("}");
|
||||||
rv = ostream->Close();
|
rv = gzWriter->Finish();
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
STUMBLER_ERR("ostream finish failed");
|
STUMBLER_ERR("ostream finish failed");
|
||||||
}
|
}
|
||||||
@ -204,7 +202,9 @@ WriteStumbleOnThread::Run()
|
|||||||
|
|
||||||
if (UploadFileStatus::NoFile != status) {
|
if (UploadFileStatus::NoFile != status) {
|
||||||
if (UploadFileStatus::ExistsAndReadyToUpload == status) {
|
if (UploadFileStatus::ExistsAndReadyToUpload == status) {
|
||||||
|
sIsFileWaitingForUpload = true;
|
||||||
Upload();
|
Upload();
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Partition partition = GetWritePosition();
|
Partition partition = GetWritePosition();
|
||||||
@ -215,6 +215,7 @@ WriteStumbleOnThread::Run()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sIsFileWaitingForUpload = false;
|
||||||
sIsAlreadyRunning = false;
|
sIsAlreadyRunning = false;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
@ -259,11 +260,6 @@ WriteStumbleOnThread::Upload()
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
MOZ_ASSERT(!NS_IsMainThread());
|
||||||
|
|
||||||
bool b = sIsUploading.exchange(true);
|
|
||||||
if (b) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t seconds = time(0);
|
time_t seconds = time(0);
|
||||||
int day = seconds / (60 * 60 * 24);
|
int day = seconds / (60 * 60 * 24);
|
||||||
|
|
||||||
@ -275,7 +271,7 @@ WriteStumbleOnThread::Upload()
|
|||||||
sUploadFreqGuard.attempts++;
|
sUploadFreqGuard.attempts++;
|
||||||
if (sUploadFreqGuard.attempts > MAX_UPLOAD_ATTEMPTS) {
|
if (sUploadFreqGuard.attempts > MAX_UPLOAD_ATTEMPTS) {
|
||||||
STUMBLER_ERR("Too many upload attempts today");
|
STUMBLER_ERR("Too many upload attempts today");
|
||||||
sIsUploading = false;
|
sIsAlreadyRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,32 +282,23 @@ WriteStumbleOnThread::Upload()
|
|||||||
rv = tmpFile->GetFileSize(&fileSize);
|
rv = tmpFile->GetFileSize(&fileSize);
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
STUMBLER_ERR("GetFileSize failed");
|
STUMBLER_ERR("GetFileSize failed");
|
||||||
sIsUploading = false;
|
sIsAlreadyRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileSize <= 0) {
|
if (fileSize <= 0) {
|
||||||
sIsUploading = false;
|
sIsAlreadyRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare json into nsIInputStream
|
// prepare json into nsIInputStream
|
||||||
nsCOMPtr<nsIInputStream> inStream;
|
nsCOMPtr<nsIInputStream> inStream;
|
||||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile, -1, -1,
|
rv = NS_NewLocalFileInputStream(getter_AddRefs(inStream), tmpFile);
|
||||||
nsIFileInputStream::DEFER_OPEN);
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
sIsUploading = false;
|
sIsAlreadyRunning = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCString bufStr;
|
nsRefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(inStream);
|
||||||
rv = NS_ReadInputStreamToString(inStream, bufStr, fileSize);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
sIsUploading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<nsIRunnable> uploader = new UploadStumbleRunnable(bufStr);
|
|
||||||
NS_DispatchToMainThread(uploader);
|
NS_DispatchToMainThread(uploader);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include "mozilla/Atomics.h"
|
#include "mozilla/Atomics.h"
|
||||||
|
|
||||||
|
class DeleteRunnable;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This class is the entry point to stumbling, in that it
|
This class is the entry point to stumbling, in that it
|
||||||
receives the location+cell+wifi string and writes it
|
receives the location+cell+wifi string and writes it
|
||||||
@ -43,10 +45,13 @@ public:
|
|||||||
NS_IMETHODIMP Run() override;
|
NS_IMETHODIMP Run() override;
|
||||||
|
|
||||||
static void UploadEnded(bool deleteUploadFile);
|
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:
|
private:
|
||||||
|
friend class DeleteRunnable;
|
||||||
|
|
||||||
enum class Partition {
|
enum class Partition {
|
||||||
Begining,
|
Begining,
|
||||||
@ -71,6 +76,8 @@ private:
|
|||||||
// Only run one instance of this
|
// Only run one instance of this
|
||||||
static mozilla::Atomic<bool> sIsAlreadyRunning;
|
static mozilla::Atomic<bool> sIsAlreadyRunning;
|
||||||
|
|
||||||
|
static mozilla::Atomic<bool> sIsFileWaitingForUpload;
|
||||||
|
|
||||||
// Limit the upload attempts per day. If the device is rebooted
|
// Limit the upload attempts per day. If the device is rebooted
|
||||||
// this resets the allowed attempts, which is acceptable.
|
// this resets the allowed attempts, which is acceptable.
|
||||||
struct UploadFreqGuard {
|
struct UploadFreqGuard {
|
||||||
|
@ -27,7 +27,7 @@ interface PushManager {
|
|||||||
[ChromeOnly, Throws, Exposed=Window]
|
[ChromeOnly, Throws, Exposed=Window]
|
||||||
void setPushManagerImpl(PushManagerImpl store);
|
void setPushManagerImpl(PushManagerImpl store);
|
||||||
|
|
||||||
[Throws]
|
[Throws, UseCounter]
|
||||||
Promise<PushSubscription> subscribe();
|
Promise<PushSubscription> subscribe();
|
||||||
[Throws]
|
[Throws]
|
||||||
Promise<PushSubscription?> getSubscription();
|
Promise<PushSubscription?> getSubscription();
|
||||||
|
@ -14,7 +14,7 @@ interface Principal;
|
|||||||
interface PushSubscription
|
interface PushSubscription
|
||||||
{
|
{
|
||||||
readonly attribute USVString endpoint;
|
readonly attribute USVString endpoint;
|
||||||
[Throws]
|
[Throws, UseCounter]
|
||||||
Promise<boolean> unsubscribe();
|
Promise<boolean> unsubscribe();
|
||||||
jsonifier;
|
jsonifier;
|
||||||
|
|
||||||
|
@ -1323,8 +1323,9 @@ bool nsHTMLEditor::HavePrivateHTMLFlavor(nsIClipboard *aClipboard)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsHTMLEditor::Paste(int32_t aSelectionType)
|
NS_IMETHODIMP nsHTMLEditor::Paste(int32_t aSelectionType)
|
||||||
{
|
{
|
||||||
if (!FireClipboardEvent(NS_PASTE, aSelectionType))
|
if (!FireClipboardEvent(ePaste, aSelectionType)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Get Clipboard Service
|
// Get Clipboard Service
|
||||||
nsresult rv;
|
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
|
// 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.
|
// 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;
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// handle transferable hooks
|
// handle transferable hooks
|
||||||
nsCOMPtr<nsIDOMDocument> domdoc = GetDOMDocument();
|
nsCOMPtr<nsIDOMDocument> domdoc = GetDOMDocument();
|
||||||
@ -1424,8 +1426,9 @@ NS_IMETHODIMP nsHTMLEditor::PasteTransferable(nsITransferable *aTransferable)
|
|||||||
//
|
//
|
||||||
NS_IMETHODIMP nsHTMLEditor::PasteNoFormatting(int32_t aSelectionType)
|
NS_IMETHODIMP nsHTMLEditor::PasteNoFormatting(int32_t aSelectionType)
|
||||||
{
|
{
|
||||||
if (!FireClipboardEvent(NS_PASTE, aSelectionType))
|
if (!FireClipboardEvent(ePaste, aSelectionType)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
ForceCompositionEnd();
|
ForceCompositionEnd();
|
||||||
|
|
||||||
|
@ -322,8 +322,9 @@ nsresult nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
|
|||||||
|
|
||||||
NS_IMETHODIMP nsPlaintextEditor::Paste(int32_t aSelectionType)
|
NS_IMETHODIMP nsPlaintextEditor::Paste(int32_t aSelectionType)
|
||||||
{
|
{
|
||||||
if (!FireClipboardEvent(NS_PASTE, aSelectionType))
|
if (!FireClipboardEvent(ePaste, aSelectionType)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Get Clipboard Service
|
// Get Clipboard Service
|
||||||
nsresult rv;
|
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
|
// 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.
|
// 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;
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (!IsModifiable())
|
if (!IsModifiable())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -1173,7 +1173,7 @@ nsPlaintextEditor::FireClipboardEvent(EventMessage aEventMessage,
|
|||||||
int32_t aSelectionType,
|
int32_t aSelectionType,
|
||||||
bool* aActionTaken)
|
bool* aActionTaken)
|
||||||
{
|
{
|
||||||
if (aEventMessage == NS_PASTE) {
|
if (aEventMessage == ePaste) {
|
||||||
ForceCompositionEnd();
|
ForceCompositionEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1198,7 +1198,7 @@ nsPlaintextEditor::FireClipboardEvent(EventMessage aEventMessage,
|
|||||||
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
NS_IMETHODIMP nsPlaintextEditor::Cut()
|
||||||
{
|
{
|
||||||
bool actionTaken = false;
|
bool actionTaken = false;
|
||||||
if (FireClipboardEvent(NS_CUT, nsIClipboard::kGlobalClipboard, &actionTaken)) {
|
if (FireClipboardEvent(eCut, nsIClipboard::kGlobalClipboard, &actionTaken)) {
|
||||||
DeleteSelection(eNone, eStrip);
|
DeleteSelection(eNone, eStrip);
|
||||||
}
|
}
|
||||||
return actionTaken ? NS_OK : NS_ERROR_FAILURE;
|
return actionTaken ? NS_OK : NS_ERROR_FAILURE;
|
||||||
@ -1217,7 +1217,7 @@ NS_IMETHODIMP nsPlaintextEditor::CanCut(bool *aCanCut)
|
|||||||
NS_IMETHODIMP nsPlaintextEditor::Copy()
|
NS_IMETHODIMP nsPlaintextEditor::Copy()
|
||||||
{
|
{
|
||||||
bool actionTaken = false;
|
bool actionTaken = false;
|
||||||
FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, &actionTaken);
|
FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard, &actionTaken);
|
||||||
|
|
||||||
return actionTaken ? NS_OK : NS_ERROR_FAILURE;
|
return actionTaken ? NS_OK : NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -629,6 +629,12 @@ FilterNodeSoftware::GetOutput(const IntRect &aRect)
|
|||||||
void
|
void
|
||||||
FilterNodeSoftware::RequestRect(const IntRect &aRect)
|
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);
|
mRequestedRect = mRequestedRect.Union(aRect);
|
||||||
RequestFromInputsForRect(aRect);
|
RequestFromInputsForRect(aRect);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
#ifndef gfx_src_DriverCrashGuard_h__
|
#ifndef gfx_src_DriverCrashGuard_h__
|
||||||
#define gfx_src_DriverCrashGuard_h__
|
#define gfx_src_DriverCrashGuard_h__
|
||||||
|
|
||||||
#include "gfxCore.h"
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIGfxInfo.h"
|
#include "nsIGfxInfo.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
|
@ -347,6 +347,12 @@ FilterCachedColorModels::WrapForColorModel(ColorModel aColorModel)
|
|||||||
return FilterWrappers::LinearRGBToSRGB(mDT, unpremultipliedOriginal);
|
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 == 0, the identity matrix is returned.
|
||||||
// When aAmount == 1, aToMatrix is returned.
|
// When aAmount == 1, aToMatrix is returned.
|
||||||
// When aAmount > 1, an exaggerated version of aToMatrix is returned. This can
|
// 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,
|
InterpolateFromIdentityMatrix(const float aToMatrix[20], float aAmount,
|
||||||
float aOutMatrix[20])
|
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);
|
PodCopy(aOutMatrix, identityMatrix, 20);
|
||||||
|
|
||||||
float oneMinusAmount = 1 - aAmount;
|
float oneMinusAmount = 1 - aAmount;
|
||||||
@ -392,12 +392,6 @@ static nsresult
|
|||||||
ComputeColorMatrix(uint32_t aColorMatrixType, const nsTArray<float>& aValues,
|
ComputeColorMatrix(uint32_t aColorMatrixType, const nsTArray<float>& aValues,
|
||||||
float aOutMatrix[20])
|
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.
|
// Luminance coefficients.
|
||||||
static const float lumR = 0.2126f;
|
static const float lumR = 0.2126f;
|
||||||
static const float lumG = 0.7152f;
|
static const float lumG = 0.7152f;
|
||||||
@ -760,7 +754,8 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
|||||||
float colorMatrix[20];
|
float colorMatrix[20];
|
||||||
uint32_t type = atts.GetUint(eColorMatrixType);
|
uint32_t type = atts.GetUint(eColorMatrixType);
|
||||||
const nsTArray<float>& values = atts.GetFloats(eColorMatrixValues);
|
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]);
|
RefPtr<FilterNode> filter(aSources[0]);
|
||||||
return filter.forget();
|
return filter.forget();
|
||||||
}
|
}
|
||||||
@ -954,11 +949,15 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
|||||||
RefPtr<FilterNode> filter;
|
RefPtr<FilterNode> filter;
|
||||||
uint32_t op = atts.GetUint(eCompositeOperator);
|
uint32_t op = atts.GetUint(eCompositeOperator);
|
||||||
if (op == SVG_FECOMPOSITE_OPERATOR_ARITHMETIC) {
|
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);
|
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;
|
return nullptr;
|
||||||
}
|
}
|
||||||
const nsTArray<float>& coefficients = atts.GetFloats(eCompositeCoefficients);
|
|
||||||
filter->SetAttribute(ATT_ARITHMETIC_COMBINE_COEFFICIENTS,
|
filter->SetAttribute(ATT_ARITHMETIC_COMBINE_COEFFICIENTS,
|
||||||
coefficients.Elements(), coefficients.Length());
|
coefficients.Elements(), coefficients.Length());
|
||||||
filter->SetInput(IN_ARITHMETIC_COMBINE_IN, aSources[0]);
|
filter->SetInput(IN_ARITHMETIC_COMBINE_IN, aSources[0]);
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h> // for memset
|
#include <string.h> // for memset
|
||||||
#include "gfxCore.h" // for NS_GFX
|
|
||||||
#include "mozilla/Scoped.h" // for SCOPED_TEMPLATE
|
#include "mozilla/Scoped.h" // for SCOPED_TEMPLATE
|
||||||
|
|
||||||
namespace mozilla {
|
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
|
* 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.
|
* 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:
|
public:
|
||||||
// trivial wrapper around XErrorEvent, just adding ctor initializing by zero.
|
// 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__
|
#ifndef gfxCrashReporterUtils_h__
|
||||||
#define gfxCrashReporterUtils_h__
|
#define gfxCrashReporterUtils_h__
|
||||||
|
|
||||||
#include "gfxCore.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
@ -21,7 +20,7 @@ namespace mozilla {
|
|||||||
* have many exit points. We don't want to encourage having function with many exit points.
|
* 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.
|
* It just happens that our graphics features initialization functions are like that.
|
||||||
*/
|
*/
|
||||||
class NS_GFX ScopedGfxFeatureReporter
|
class ScopedGfxFeatureReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ScopedGfxFeatureReporter(const char *aFeature, bool force = false)
|
explicit ScopedGfxFeatureReporter(const char *aFeature, bool force = false)
|
||||||
|
@ -16,7 +16,6 @@ DEFINES['MOZ_APP_VERSION'] = '"%s"' % CONFIG['MOZ_APP_VERSION']
|
|||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'DriverCrashGuard.h',
|
'DriverCrashGuard.h',
|
||||||
'FilterSupport.h',
|
'FilterSupport.h',
|
||||||
'gfxCore.h',
|
|
||||||
'gfxCrashReporterUtils.h',
|
'gfxCrashReporterUtils.h',
|
||||||
'gfxTelemetry.h',
|
'gfxTelemetry.h',
|
||||||
'nsBoundingMetrics.h',
|
'nsBoundingMetrics.h',
|
||||||
|
@ -75,8 +75,7 @@ static int ComponentValue(const char16_t* aColorSpec, int aLen, int color, int d
|
|||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_GFX_(bool) NS_HexToRGB(const nsAString& aColorSpec,
|
bool NS_HexToRGB(const nsAString& aColorSpec, nscolor* aResult)
|
||||||
nscolor* aResult)
|
|
||||||
{
|
{
|
||||||
const char16_t* buffer = aColorSpec.BeginReading();
|
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
|
// 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
|
// 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")) {
|
if (aColorSpec.EqualsLiteral("transparent")) {
|
||||||
return false;
|
return false;
|
||||||
@ -185,7 +184,7 @@ NS_GFX_(bool) NS_LooseHexToRGB(const nsString& aColorSpec, nscolor* aResult)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_GFX_(bool) NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
|
bool NS_ColorNameToRGB(const nsAString& aColorName, nscolor* aResult)
|
||||||
{
|
{
|
||||||
if (!gColorTable) return false;
|
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
|
// 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.
|
// *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);
|
*aSizeArray = ArrayLength(kColorNames);
|
||||||
return kColorNames;
|
return kColorNames;
|
||||||
@ -215,7 +214,7 @@ NS_GFX_(const char * const *) NS_AllColorNames(size_t *aSizeArray)
|
|||||||
#define MOZ_BLEND(target, bg, fg, fgalpha) \
|
#define MOZ_BLEND(target, bg, fg, fgalpha) \
|
||||||
FAST_DIVIDE_BY_255(target, (bg)*(255-fgalpha) + (fg)*(fgalpha))
|
FAST_DIVIDE_BY_255(target, (bg)*(255-fgalpha) + (fg)*(fgalpha))
|
||||||
|
|
||||||
NS_GFX_(nscolor)
|
nscolor
|
||||||
NS_ComposeColors(nscolor aBG, nscolor aFG)
|
NS_ComposeColors(nscolor aBG, nscolor aFG)
|
||||||
{
|
{
|
||||||
// This function uses colors that are non premultiplied alpha.
|
// 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
|
// 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)
|
NS_HSL2RGB(float h, float s, float l)
|
||||||
{
|
{
|
||||||
uint8_t r, g, b;
|
uint8_t r, g, b;
|
||||||
@ -281,7 +280,7 @@ NS_HSL2RGB(float h, float s, float l)
|
|||||||
return NS_RGB(r, g, b);
|
return NS_RGB(r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_GFX_(const char*)
|
const char*
|
||||||
NS_RGBToColorName(nscolor aColor)
|
NS_RGBToColorName(nscolor aColor)
|
||||||
{
|
{
|
||||||
for (size_t idx = 0; idx < ArrayLength(kColors); ++idx) {
|
for (size_t idx = 0; idx < ArrayLength(kColors); ++idx) {
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <stddef.h> // for size_t
|
#include <stddef.h> // for size_t
|
||||||
#include <stdint.h> // for uint8_t, uint32_t
|
#include <stdint.h> // for uint8_t, uint32_t
|
||||||
#include "gfxCore.h" // for NS_GFX_
|
|
||||||
#include "nscore.h" // for nsAString
|
#include "nscore.h" // for nsAString
|
||||||
|
|
||||||
class nsAString;
|
class nsAString;
|
||||||
@ -53,37 +52,37 @@ typedef uint32_t nscolor;
|
|||||||
// Translate a hex string to a color. Return true if it parses ok,
|
// Translate a hex string to a color. Return true if it parses ok,
|
||||||
// otherwise return false.
|
// otherwise return false.
|
||||||
// This accepts only 3 or 6 digits
|
// 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
|
// Compose one NS_RGB color onto another. The result is what
|
||||||
// you get if you draw aFG on top of aBG with operator OVER.
|
// 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,
|
// Translate a hex string to a color. Return true if it parses ok,
|
||||||
// otherwise return false.
|
// otherwise return false.
|
||||||
// This version accepts 1 to 9 digits (missing digits are 0)
|
// 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
|
// There is no function to translate a color to a hex string, because
|
||||||
// the hex-string syntax does not support transparency.
|
// the hex-string syntax does not support transparency.
|
||||||
|
|
||||||
// Translate a color name to a color. Return true if it parses ok,
|
// Translate a color name to a color. Return true if it parses ok,
|
||||||
// otherwise return false.
|
// 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
|
// Returns an array of all possible color names, and sets
|
||||||
// *aSizeArray to the size of that array. Do NOT call |free()| on this array.
|
// *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
|
// function to convert from HSL color space to RGB color space
|
||||||
// the float parameters are all expected to be in the range 0-1
|
// 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
|
// Return a color name for the given nscolor. If there is no color
|
||||||
// name for it, returns null. If there are multiple possible color
|
// name for it, returns null. If there are multiple possible color
|
||||||
// names for the given color, the first one in nsColorNameList.h
|
// names for the given color, the first one in nsColorNameList.h
|
||||||
// (which is generally the first one in alphabetical order) will be
|
// (which is generally the first one in alphabetical order) will be
|
||||||
// returned.
|
// returned.
|
||||||
NS_GFX_(const char*) NS_RGBToColorName(nscolor aColor);
|
const char* NS_RGBToColorName(nscolor aColor);
|
||||||
|
|
||||||
#endif /* nsColor_h___ */
|
#endif /* nsColor_h___ */
|
||||||
|
@ -6,9 +6,8 @@
|
|||||||
#ifndef nsColorNames_h___
|
#ifndef nsColorNames_h___
|
||||||
#define nsColorNames_h___
|
#define nsColorNames_h___
|
||||||
|
|
||||||
#include "gfxCore.h"
|
|
||||||
|
|
||||||
class NS_GFX nsColorNames {
|
class nsColorNames {
|
||||||
public:
|
public:
|
||||||
static void AddRefTable(void);
|
static void AddRefTable(void);
|
||||||
static void ReleaseTable(void);
|
static void ReleaseTable(void);
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <stdint.h> // for uint8_t, uint16_t
|
#include <stdint.h> // for uint8_t, uint16_t
|
||||||
#include <sys/types.h> // for int16_t
|
#include <sys/types.h> // for int16_t
|
||||||
#include "gfxCore.h" // for NS_GFX
|
|
||||||
#include "gfxFontFamilyList.h"
|
#include "gfxFontFamilyList.h"
|
||||||
#include "gfxFontFeatures.h"
|
#include "gfxFontFeatures.h"
|
||||||
#include "nsAutoPtr.h" // for nsRefPtr
|
#include "nsAutoPtr.h" // for nsRefPtr
|
||||||
@ -40,7 +39,7 @@ const uint8_t kGenericFont_cursive = 0x10;
|
|||||||
const uint8_t kGenericFont_fantasy = 0x20;
|
const uint8_t kGenericFont_fantasy = 0x20;
|
||||||
|
|
||||||
// Font structure.
|
// Font structure.
|
||||||
struct NS_GFX nsFont {
|
struct nsFont {
|
||||||
|
|
||||||
// list of font families, either named or generic
|
// list of font families, either named or generic
|
||||||
mozilla::FontFamilyList fontlist;
|
mozilla::FontFamilyList fontlist;
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include "nsCoord.h"
|
#include "nsCoord.h"
|
||||||
#include "nsPoint.h"
|
#include "nsPoint.h"
|
||||||
#include "gfxCore.h"
|
|
||||||
#include "mozilla/gfx/BaseMargin.h"
|
#include "mozilla/gfx/BaseMargin.h"
|
||||||
|
|
||||||
struct nsMargin : public mozilla::gfx::BaseMargin<nscoord, nsMargin> {
|
struct nsMargin : public mozilla::gfx::BaseMargin<nscoord, nsMargin> {
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <stdio.h> // for FILE
|
#include <stdio.h> // for FILE
|
||||||
#include <stdint.h> // for int32_t, int64_t
|
#include <stdint.h> // for int32_t, int64_t
|
||||||
#include <algorithm> // for min/max
|
#include <algorithm> // for min/max
|
||||||
#include "gfxCore.h" // for NS_GFX
|
|
||||||
#include "mozilla/Likely.h" // for MOZ_UNLIKELY
|
#include "mozilla/Likely.h" // for MOZ_UNLIKELY
|
||||||
#include "mozilla/gfx/Rect.h"
|
#include "mozilla/gfx/Rect.h"
|
||||||
#include "nsCoord.h" // for nscoord, etc
|
#include "nsCoord.h" // for nscoord, etc
|
||||||
@ -24,7 +23,7 @@ struct nsIntMargin;
|
|||||||
|
|
||||||
typedef mozilla::gfx::IntRect nsIntRect;
|
typedef mozilla::gfx::IntRect nsIntRect;
|
||||||
|
|
||||||
struct NS_GFX nsRect :
|
struct nsRect :
|
||||||
public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
|
public mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> {
|
||||||
typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
|
typedef mozilla::gfx::BaseRect<nscoord, nsRect, nsPoint, nsSize, nsMargin> Super;
|
||||||
|
|
||||||
@ -290,7 +289,7 @@ ToAppUnits(const mozilla::gfx::IntRect& aRect, nscoord aAppUnitsPerPixel);
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Diagnostics
|
// Diagnostics
|
||||||
extern NS_GFX FILE* operator<<(FILE* out, const nsRect& rect);
|
extern FILE* operator<<(FILE* out, const nsRect& rect);
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
#endif /* NSRECT_H */
|
#endif /* NSRECT_H */
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <stddef.h> // for size_t
|
#include <stddef.h> // for size_t
|
||||||
#include <stdint.h> // for uint32_t, uint64_t
|
#include <stdint.h> // for uint32_t, uint64_t
|
||||||
#include <sys/types.h> // for int32_t
|
#include <sys/types.h> // for int32_t
|
||||||
#include "gfxCore.h" // for NS_GFX
|
|
||||||
#include "mozilla/ToString.h" // for mozilla::ToString
|
#include "mozilla/ToString.h" // for mozilla::ToString
|
||||||
#include "nsCoord.h" // for nscoord
|
#include "nsCoord.h" // for nscoord
|
||||||
#include "nsError.h" // for nsresult
|
#include "nsError.h" // for nsresult
|
||||||
@ -420,7 +419,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class NS_GFX nsRegionRectIterator
|
class nsRegionRectIterator
|
||||||
{
|
{
|
||||||
const nsRegion* mRegion;
|
const nsRegion* mRegion;
|
||||||
int i;
|
int i;
|
||||||
@ -474,7 +473,7 @@ namespace gfx {
|
|||||||
* BaseIntRegions use int32_t coordinates.
|
* BaseIntRegions use int32_t coordinates.
|
||||||
*/
|
*/
|
||||||
template <typename Derived, typename Rect, typename Point, typename Margin>
|
template <typename Derived, typename Rect, typename Point, typename Margin>
|
||||||
class NS_GFX BaseIntRegion
|
class BaseIntRegion
|
||||||
{
|
{
|
||||||
friend class ::nsRegion;
|
friend class ::nsRegion;
|
||||||
|
|
||||||
@ -763,7 +762,7 @@ public:
|
|||||||
|
|
||||||
nsCString ToString() const { return mImpl.ToString(); }
|
nsCString ToString() const { return mImpl.ToString(); }
|
||||||
|
|
||||||
class NS_GFX RectIterator
|
class RectIterator
|
||||||
{
|
{
|
||||||
nsRegionRectIterator mImpl;
|
nsRegionRectIterator mImpl;
|
||||||
Rect mTmp;
|
Rect mTmp;
|
||||||
@ -825,7 +824,7 @@ private:
|
|||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // 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:
|
public:
|
||||||
// Forward constructors.
|
// Forward constructors.
|
||||||
|
@ -8,12 +8,11 @@
|
|||||||
#define nsScriptableRegion_h
|
#define nsScriptableRegion_h
|
||||||
|
|
||||||
#include "nsIScriptableRegion.h"
|
#include "nsIScriptableRegion.h"
|
||||||
#include "gfxCore.h"
|
|
||||||
#include "nsISupports.h"
|
#include "nsISupports.h"
|
||||||
#include "nsRegion.h"
|
#include "nsRegion.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
|
||||||
class NS_GFX nsScriptableRegion final : public nsIScriptableRegion {
|
class nsScriptableRegion final : public nsIScriptableRegion {
|
||||||
public:
|
public:
|
||||||
nsScriptableRegion();
|
nsScriptableRegion();
|
||||||
|
|
||||||
|
@ -6,10 +6,9 @@
|
|||||||
#ifndef nsTransform2D_h___
|
#ifndef nsTransform2D_h___
|
||||||
#define nsTransform2D_h___
|
#define nsTransform2D_h___
|
||||||
|
|
||||||
#include "gfxCore.h"
|
|
||||||
#include "nsCoord.h"
|
#include "nsCoord.h"
|
||||||
|
|
||||||
class NS_GFX nsTransform2D
|
class nsTransform2D
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
||||||
--- a/gfx/ycbcr/yuv_convert.cpp
|
--- a/gfx/ycbcr/yuv_convert.cpp
|
||||||
+++ b/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);
|
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 kFractionMax = 1 << kFractionBits;
|
||||||
const int kFractionMask = ((1 << kFractionBits) - 1);
|
const int kFractionMask = ((1 << kFractionBits) - 1);
|
||||||
|
|
||||||
+NS_GFX_(YUVType) TypeFromSize(int ywidth,
|
+YUVType TypeFromSize(int ywidth,
|
||||||
+ int yheight,
|
+ int yheight,
|
||||||
+ int cbcrwidth,
|
+ int cbcrwidth,
|
||||||
+ int cbcrheight)
|
+ int cbcrheight)
|
||||||
+{
|
+{
|
||||||
+ if (ywidth == cbcrwidth && yheight == cbcrheight) {
|
+ if (ywidth == cbcrwidth && yheight == cbcrheight) {
|
||||||
+ return YV24;
|
+ 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.
|
// Convert a frame of YUV to 32 bit ARGB.
|
||||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
|
void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||||
const uint8* u_buf,
|
const uint8* u_buf,
|
||||||
const uint8* v_buf,
|
const uint8* v_buf,
|
||||||
uint8* rgb_buf,
|
uint8* rgb_buf,
|
||||||
int pic_x,
|
int pic_x,
|
||||||
int pic_y,
|
int pic_y,
|
||||||
int pic_width,
|
int pic_width,
|
||||||
diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
||||||
--- a/gfx/ycbcr/yuv_convert.h
|
--- a/gfx/ycbcr/yuv_convert.h
|
||||||
+++ b/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.
|
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.
|
// Convert a frame of YUV to 32 bit ARGB.
|
||||||
// Pass in YV16/YV12 depending on source format
|
// Pass in YV16/YV12 depending on source format
|
||||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
|
void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||||
const uint8* uplane,
|
const uint8* uplane,
|
||||||
const uint8* vplane,
|
const uint8* vplane,
|
||||||
uint8* rgbframe,
|
uint8* rgbframe,
|
||||||
int pic_x,
|
int pic_x,
|
||||||
int pic_y,
|
int pic_y,
|
||||||
|
@ -71,18 +71,18 @@ diff --git a/gfx/ycbcr/yuv_convert.cpp b/gfx/ycbcr/yuv_convert.cpp
|
|||||||
- rgb_row,
|
- rgb_row,
|
||||||
- width);
|
- width);
|
||||||
- }
|
- }
|
||||||
+NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
|
+void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||||
+ const uint8* u_buf,
|
+ const uint8* u_buf,
|
||||||
+ const uint8* v_buf,
|
+ const uint8* v_buf,
|
||||||
+ uint8* rgb_buf,
|
+ uint8* rgb_buf,
|
||||||
+ int pic_x,
|
+ int pic_x,
|
||||||
+ int pic_y,
|
+ int pic_y,
|
||||||
+ int pic_width,
|
+ int pic_width,
|
||||||
+ int pic_height,
|
+ int pic_height,
|
||||||
+ int y_pitch,
|
+ int y_pitch,
|
||||||
+ int uv_pitch,
|
+ int uv_pitch,
|
||||||
+ int rgb_pitch,
|
+ int rgb_pitch,
|
||||||
+ YUVType yuv_type) {
|
+ YUVType yuv_type) {
|
||||||
+ unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
|
+ unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
|
||||||
+ unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
|
+ unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
|
||||||
+ // Test for SSE because the optimized code uses movntq, which is not part of MMX.
|
+ // 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,
|
- YUVType yuv_type,
|
||||||
- Rotate view_rotate,
|
- Rotate view_rotate,
|
||||||
- ScaleFilter filter) {
|
- ScaleFilter filter) {
|
||||||
+NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf,
|
+void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||||
+ const uint8* u_buf,
|
+ const uint8* u_buf,
|
||||||
+ const uint8* v_buf,
|
+ const uint8* v_buf,
|
||||||
+ uint8* rgb_buf,
|
+ uint8* rgb_buf,
|
||||||
+ int source_width,
|
+ int source_width,
|
||||||
+ int source_height,
|
+ int source_height,
|
||||||
+ int width,
|
+ int width,
|
||||||
+ int height,
|
+ int height,
|
||||||
+ int y_pitch,
|
+ int y_pitch,
|
||||||
+ int uv_pitch,
|
+ int uv_pitch,
|
||||||
+ int rgb_pitch,
|
+ int rgb_pitch,
|
||||||
+ YUVType yuv_type,
|
+ YUVType yuv_type,
|
||||||
+ Rotate view_rotate,
|
+ Rotate view_rotate,
|
||||||
+ ScaleFilter filter) {
|
+ ScaleFilter filter) {
|
||||||
+ bool has_mmx = supports_mmx();
|
+ bool has_mmx = supports_mmx();
|
||||||
+
|
+
|
||||||
// 4096 allows 3 buffers to fit in 12k.
|
// 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 uvstride,
|
||||||
- int rgbstride,
|
- int rgbstride,
|
||||||
- YUVType yuv_type);
|
- YUVType yuv_type);
|
||||||
+NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
|
+void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||||
+ const uint8* uplane,
|
+ const uint8* uplane,
|
||||||
+ const uint8* vplane,
|
+ const uint8* vplane,
|
||||||
+ uint8* rgbframe,
|
+ uint8* rgbframe,
|
||||||
+ int pic_x,
|
+ int pic_x,
|
||||||
+ int pic_y,
|
+ int pic_y,
|
||||||
+ int pic_width,
|
+ int pic_width,
|
||||||
+ int pic_height,
|
+ int pic_height,
|
||||||
+ int ystride,
|
+ int ystride,
|
||||||
+ int uvstride,
|
+ int uvstride,
|
||||||
+ int rgbstride,
|
+ int rgbstride,
|
||||||
+ YUVType yuv_type);
|
+ YUVType yuv_type);
|
||||||
|
|
||||||
// Scale a frame of YUV to 32 bit ARGB.
|
// Scale a frame of YUV to 32 bit ARGB.
|
||||||
// Supports rotation and mirroring.
|
// Supports rotation and mirroring.
|
||||||
@ -501,20 +501,20 @@ diff --git a/gfx/ycbcr/yuv_convert.h b/gfx/ycbcr/yuv_convert.h
|
|||||||
-
|
-
|
||||||
-} // namespace media
|
-} // namespace media
|
||||||
-
|
-
|
||||||
+NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane,
|
+void ScaleYCbCrToRGB32(const uint8* yplane,
|
||||||
+ const uint8* uplane,
|
+ const uint8* uplane,
|
||||||
+ const uint8* vplane,
|
+ const uint8* vplane,
|
||||||
+ uint8* rgbframe,
|
+ uint8* rgbframe,
|
||||||
+ int source_width,
|
+ int source_width,
|
||||||
+ int source_height,
|
+ int source_height,
|
||||||
+ int width,
|
+ int width,
|
||||||
+ int height,
|
+ int height,
|
||||||
+ int ystride,
|
+ int ystride,
|
||||||
+ int uvstride,
|
+ int uvstride,
|
||||||
+ int rgbstride,
|
+ int rgbstride,
|
||||||
+ YUVType yuv_type,
|
+ YUVType yuv_type,
|
||||||
+ Rotate view_rotate,
|
+ Rotate view_rotate,
|
||||||
+ ScaleFilter filter);
|
+ ScaleFilter filter);
|
||||||
+
|
+
|
||||||
+} // namespace gfx
|
+} // namespace gfx
|
||||||
+} // namespace mozilla
|
+} // 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 *u_buf,
|
||||||
const uint8_t *v_buf,
|
const uint8_t *v_buf,
|
||||||
uint8_t *rgb_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_y0,
|
||||||
int source_width,
|
int source_width,
|
||||||
int source_height,
|
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* u_buf,
|
||||||
const uint8* v_buf,
|
const uint8* v_buf,
|
||||||
uint8* rgb_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_y,
|
||||||
int pic_width,
|
int pic_width,
|
||||||
int pic_height,
|
int pic_height,
|
||||||
|
@ -17,7 +17,7 @@ namespace gfx {
|
|||||||
|
|
||||||
#ifdef HAVE_YCBCR_TO_RGB565
|
#ifdef HAVE_YCBCR_TO_RGB565
|
||||||
// Convert a frame of YUV to 16 bit 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* uplane,
|
||||||
const uint8* vplane,
|
const uint8* vplane,
|
||||||
uint8* rgbframe,
|
uint8* rgbframe,
|
||||||
@ -31,14 +31,14 @@ NS_GFX_(void) ConvertYCbCrToRGB565(const uint8* yplane,
|
|||||||
YUVType yuv_type);
|
YUVType yuv_type);
|
||||||
|
|
||||||
// Used to test if we have an accelerated version.
|
// 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_y,
|
||||||
int pic_width,
|
int pic_width,
|
||||||
int pic_height,
|
int pic_height,
|
||||||
YUVType yuv_type);
|
YUVType yuv_type);
|
||||||
|
|
||||||
// Scale a frame of YUV to 16 bit RGB565.
|
// 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 *uplane,
|
||||||
const uint8_t *vplane,
|
const uint8_t *vplane,
|
||||||
uint8_t *rgbframe,
|
uint8_t *rgbframe,
|
||||||
@ -55,7 +55,7 @@ NS_GFX_(void) ScaleYCbCrToRGB565(const uint8_t *yplane,
|
|||||||
ScaleFilter filter);
|
ScaleFilter filter);
|
||||||
|
|
||||||
// Used to test if we have an accelerated version.
|
// 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_y0,
|
||||||
int source_width,
|
int source_width,
|
||||||
int source_height,
|
int source_height,
|
||||||
|
@ -31,7 +31,7 @@ const int kFractionBits = 16;
|
|||||||
const int kFractionMax = 1 << kFractionBits;
|
const int kFractionMax = 1 << kFractionBits;
|
||||||
const int kFractionMask = ((1 << kFractionBits) - 1);
|
const int kFractionMask = ((1 << kFractionBits) - 1);
|
||||||
|
|
||||||
NS_GFX_(YUVType) TypeFromSize(int ywidth,
|
YUVType TypeFromSize(int ywidth,
|
||||||
int yheight,
|
int yheight,
|
||||||
int cbcrwidth,
|
int cbcrwidth,
|
||||||
int cbcrheight)
|
int cbcrheight)
|
||||||
@ -48,18 +48,18 @@ NS_GFX_(YUVType) TypeFromSize(int ywidth,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert a frame of YUV to 32 bit ARGB.
|
// Convert a frame of YUV to 32 bit ARGB.
|
||||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* y_buf,
|
void ConvertYCbCrToRGB32(const uint8* y_buf,
|
||||||
const uint8* u_buf,
|
const uint8* u_buf,
|
||||||
const uint8* v_buf,
|
const uint8* v_buf,
|
||||||
uint8* rgb_buf,
|
uint8* rgb_buf,
|
||||||
int pic_x,
|
int pic_x,
|
||||||
int pic_y,
|
int pic_y,
|
||||||
int pic_width,
|
int pic_width,
|
||||||
int pic_height,
|
int pic_height,
|
||||||
int y_pitch,
|
int y_pitch,
|
||||||
int uv_pitch,
|
int uv_pitch,
|
||||||
int rgb_pitch,
|
int rgb_pitch,
|
||||||
YUVType yuv_type) {
|
YUVType yuv_type) {
|
||||||
unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
|
unsigned int y_shift = yuv_type == YV12 ? 1 : 0;
|
||||||
unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
|
unsigned int x_shift = yuv_type == YV24 ? 0 : 1;
|
||||||
// Test for SSE because the optimized code uses movntq, which is not part of MMX.
|
// 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.
|
// Scale a frame of YUV to 32 bit ARGB.
|
||||||
NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* y_buf,
|
void ScaleYCbCrToRGB32(const uint8* y_buf,
|
||||||
const uint8* u_buf,
|
const uint8* u_buf,
|
||||||
const uint8* v_buf,
|
const uint8* v_buf,
|
||||||
uint8* rgb_buf,
|
uint8* rgb_buf,
|
||||||
int source_width,
|
int source_width,
|
||||||
int source_height,
|
int source_height,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int y_pitch,
|
int y_pitch,
|
||||||
int uv_pitch,
|
int uv_pitch,
|
||||||
int rgb_pitch,
|
int rgb_pitch,
|
||||||
YUVType yuv_type,
|
YUVType yuv_type,
|
||||||
Rotate view_rotate,
|
Rotate view_rotate,
|
||||||
ScaleFilter filter) {
|
ScaleFilter filter) {
|
||||||
bool has_mmx = supports_mmx();
|
bool has_mmx = supports_mmx();
|
||||||
|
|
||||||
// 4096 allows 3 buffers to fit in 12k.
|
// 4096 allows 3 buffers to fit in 12k.
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#define MEDIA_BASE_YUV_CONVERT_H_
|
#define MEDIA_BASE_YUV_CONVERT_H_
|
||||||
|
|
||||||
#include "chromium_types.h"
|
#include "chromium_types.h"
|
||||||
#include "gfxCore.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
@ -41,39 +40,39 @@ enum ScaleFilter {
|
|||||||
FILTER_BILINEAR = 3 // Bilinear filter.
|
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.
|
// Convert a frame of YUV to 32 bit ARGB.
|
||||||
// Pass in YV16/YV12 depending on source format
|
// Pass in YV16/YV12 depending on source format
|
||||||
NS_GFX_(void) ConvertYCbCrToRGB32(const uint8* yplane,
|
void ConvertYCbCrToRGB32(const uint8* yplane,
|
||||||
const uint8* uplane,
|
const uint8* uplane,
|
||||||
const uint8* vplane,
|
const uint8* vplane,
|
||||||
uint8* rgbframe,
|
uint8* rgbframe,
|
||||||
int pic_x,
|
int pic_x,
|
||||||
int pic_y,
|
int pic_y,
|
||||||
int pic_width,
|
int pic_width,
|
||||||
int pic_height,
|
int pic_height,
|
||||||
int ystride,
|
int ystride,
|
||||||
int uvstride,
|
int uvstride,
|
||||||
int rgbstride,
|
int rgbstride,
|
||||||
YUVType yuv_type);
|
YUVType yuv_type);
|
||||||
|
|
||||||
// Scale a frame of YUV to 32 bit ARGB.
|
// Scale a frame of YUV to 32 bit ARGB.
|
||||||
// Supports rotation and mirroring.
|
// Supports rotation and mirroring.
|
||||||
NS_GFX_(void) ScaleYCbCrToRGB32(const uint8* yplane,
|
void ScaleYCbCrToRGB32(const uint8* yplane,
|
||||||
const uint8* uplane,
|
const uint8* uplane,
|
||||||
const uint8* vplane,
|
const uint8* vplane,
|
||||||
uint8* rgbframe,
|
uint8* rgbframe,
|
||||||
int source_width,
|
int source_width,
|
||||||
int source_height,
|
int source_height,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int ystride,
|
int ystride,
|
||||||
int uvstride,
|
int uvstride,
|
||||||
int rgbstride,
|
int rgbstride,
|
||||||
YUVType yuv_type,
|
YUVType yuv_type,
|
||||||
Rotate view_rotate,
|
Rotate view_rotate,
|
||||||
ScaleFilter filter);
|
ScaleFilter filter);
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -418,9 +418,10 @@ Decoder::PostIsAnimated(int32_t aFirstFrameTimeout)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Decoder::PostFrameStop(Opacity aFrameOpacity /* = Opacity::TRANSPARENT */,
|
Decoder::PostFrameStop(Opacity aFrameOpacity
|
||||||
|
/* = Opacity::SOME_TRANSPARENCY */,
|
||||||
DisposalMethod aDisposalMethod
|
DisposalMethod aDisposalMethod
|
||||||
/* = DisposalMethod::KEEP */,
|
/* = DisposalMethod::KEEP */,
|
||||||
int32_t aTimeout /* = 0 */,
|
int32_t aTimeout /* = 0 */,
|
||||||
BlendMethod aBlendMethod /* = BlendMethod::OVER */)
|
BlendMethod aBlendMethod /* = BlendMethod::OVER */)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@ Downscaler::Downscaler(const nsIntSize& aTargetSize)
|
|||||||
, mYFilter(MakeUnique<skia::ConvolutionFilter1D>())
|
, mYFilter(MakeUnique<skia::ConvolutionFilter1D>())
|
||||||
, mWindowCapacity(0)
|
, mWindowCapacity(0)
|
||||||
, mHasAlpha(true)
|
, mHasAlpha(true)
|
||||||
|
, mFlipVertically(false)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(gfxPrefs::ImageDownscaleDuringDecodeEnabled(),
|
MOZ_ASSERT(gfxPrefs::ImageDownscaleDuringDecodeEnabled(),
|
||||||
"Downscaling even though downscale-during-decode is disabled?");
|
"Downscaling even though downscale-during-decode is disabled?");
|
||||||
@ -57,7 +58,8 @@ Downscaler::ReleaseWindow()
|
|||||||
nsresult
|
nsresult
|
||||||
Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
uint8_t* aOutputBuffer,
|
uint8_t* aOutputBuffer,
|
||||||
bool aHasAlpha)
|
bool aHasAlpha,
|
||||||
|
bool aFlipVertically /* = false */)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aOutputBuffer);
|
MOZ_ASSERT(aOutputBuffer);
|
||||||
MOZ_ASSERT(mTargetSize != aOriginalSize,
|
MOZ_ASSERT(mTargetSize != aOriginalSize,
|
||||||
@ -74,6 +76,7 @@ Downscaler::BeginFrame(const nsIntSize& aOriginalSize,
|
|||||||
double(mOriginalSize.height) / mTargetSize.height);
|
double(mOriginalSize.height) / mTargetSize.height);
|
||||||
mOutputBuffer = aOutputBuffer;
|
mOutputBuffer = aOutputBuffer;
|
||||||
mHasAlpha = aHasAlpha;
|
mHasAlpha = aHasAlpha;
|
||||||
|
mFlipVertically = aFlipVertically;
|
||||||
|
|
||||||
ResetForNextProgressivePass();
|
ResetForNextProgressivePass();
|
||||||
ReleaseWindow();
|
ReleaseWindow();
|
||||||
@ -145,6 +148,16 @@ GetFilterOffsetAndLength(UniquePtr<skia::ConvolutionFilter1D>& aFilter,
|
|||||||
aFilterLengthOut);
|
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
|
void
|
||||||
Downscaler::CommitRow()
|
Downscaler::CommitRow()
|
||||||
{
|
{
|
||||||
@ -198,9 +211,18 @@ Downscaler::TakeInvalidRect()
|
|||||||
DownscalerInvalidRect invalidRect;
|
DownscalerInvalidRect invalidRect;
|
||||||
|
|
||||||
// Compute the target size invalid rect.
|
// Compute the target size invalid rect.
|
||||||
invalidRect.mTargetSizeRect =
|
if (mFlipVertically) {
|
||||||
nsIntRect(0, mPrevInvalidatedLine,
|
// 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);
|
mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
|
||||||
|
} else {
|
||||||
|
invalidRect.mTargetSizeRect =
|
||||||
|
IntRect(0, mPrevInvalidatedLine,
|
||||||
|
mTargetSize.width, mCurrentOutLine - mPrevInvalidatedLine);
|
||||||
|
}
|
||||||
|
|
||||||
mPrevInvalidatedLine = mCurrentOutLine;
|
mPrevInvalidatedLine = mCurrentOutLine;
|
||||||
|
|
||||||
// Compute the original size invalid rect.
|
// Compute the original size invalid rect.
|
||||||
@ -225,8 +247,13 @@ Downscaler::DownscaleInputLine()
|
|||||||
auto filterValues =
|
auto filterValues =
|
||||||
mYFilter->FilterForValue(mCurrentOutLine, &filterOffset, &filterLength);
|
mYFilter->FilterForValue(mCurrentOutLine, &filterOffset, &filterLength);
|
||||||
|
|
||||||
|
int32_t currentOutLine = mFlipVertically
|
||||||
|
? mTargetSize.height - (mCurrentOutLine + 1)
|
||||||
|
: mCurrentOutLine;
|
||||||
|
MOZ_ASSERT(currentOutLine >= 0);
|
||||||
|
|
||||||
uint8_t* outputLine =
|
uint8_t* outputLine =
|
||||||
&mOutputBuffer[mCurrentOutLine * mTargetSize.width * sizeof(uint32_t)];
|
&mOutputBuffer[currentOutLine * mTargetSize.width * sizeof(uint32_t)];
|
||||||
skia::ConvolveVertically(static_cast<const FilterValue*>(filterValues),
|
skia::ConvolveVertically(static_cast<const FilterValue*>(filterValues),
|
||||||
filterLength, mWindow.get(), mXFilter->num_values(),
|
filterLength, mWindow.get(), mXFilter->num_values(),
|
||||||
outputLine, mHasAlpha, supports_sse2());
|
outputLine, mHasAlpha, supports_sse2());
|
||||||
|
@ -70,14 +70,21 @@ public:
|
|||||||
* decode.
|
* decode.
|
||||||
* @param aHasAlpha Whether or not this frame has an alpha channel.
|
* @param aHasAlpha Whether or not this frame has an alpha channel.
|
||||||
* Performance is a little better if it doesn't have one.
|
* 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,
|
nsresult BeginFrame(const nsIntSize& aOriginalSize,
|
||||||
uint8_t* aOutputBuffer,
|
uint8_t* aOutputBuffer,
|
||||||
bool aHasAlpha);
|
bool aHasAlpha,
|
||||||
|
bool aFlipVertically = false);
|
||||||
|
|
||||||
/// Retrieves the buffer into which the Decoder should write each row.
|
/// Retrieves the buffer into which the Decoder should write each row.
|
||||||
uint8_t* RowBuffer() { return mRowBuffer.get(); }
|
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.
|
/// Signals that the decoder has finished writing a row into the row buffer.
|
||||||
void CommitRow();
|
void CommitRow();
|
||||||
|
|
||||||
@ -117,7 +124,8 @@ private:
|
|||||||
int32_t mCurrentOutLine;
|
int32_t mCurrentOutLine;
|
||||||
int32_t mCurrentInLine;
|
int32_t mCurrentInLine;
|
||||||
|
|
||||||
bool mHasAlpha;
|
bool mHasAlpha : 1;
|
||||||
|
bool mFlipVertically : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -139,12 +147,13 @@ public:
|
|||||||
const nsIntSize& TargetSize() const { return nsIntSize(); }
|
const nsIntSize& TargetSize() const { return nsIntSize(); }
|
||||||
const gfxSize& Scale() const { return gfxSize(1.0, 1.0); }
|
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;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* RowBuffer() { return nullptr; }
|
uint8_t* RowBuffer() { return nullptr; }
|
||||||
|
void ClearRow(uint32_t = 0);
|
||||||
void CommitRow() { }
|
void CommitRow() { }
|
||||||
bool HasInvalidation() const { return false; }
|
bool HasInvalidation() const { return false; }
|
||||||
DownscalerInvalidRect TakeInvalidRect() { return DownscalerInvalidRect(); }
|
DownscalerInvalidRect TakeInvalidRect() { return DownscalerInvalidRect(); }
|
||||||
|
@ -36,7 +36,10 @@ static bool
|
|||||||
ShouldDownscaleDuringDecode(const nsCString& aMimeType)
|
ShouldDownscaleDuringDecode(const nsCString& aMimeType)
|
||||||
{
|
{
|
||||||
DecoderType type = DecoderFactory::GetDecoderType(aMimeType.get());
|
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
|
static uint32_t
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include "RasterImage.h"
|
#include "RasterImage.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
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
|
// Sets whether or not the BMP will use alpha data
|
||||||
void
|
void
|
||||||
nsBMPDecoder::SetUseAlphaData(bool useAlphaData)
|
nsBMPDecoder::SetUseAlphaData(bool useAlphaData)
|
||||||
@ -122,15 +138,6 @@ nsBMPDecoder::GetCompressedImageSize() const
|
|||||||
return pixelArraySize;
|
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
|
void
|
||||||
nsBMPDecoder::FinishInternal()
|
nsBMPDecoder::FinishInternal()
|
||||||
{
|
{
|
||||||
@ -147,7 +154,7 @@ nsBMPDecoder::FinishInternal()
|
|||||||
nsIntRect r(0, 0, mBIH.width, GetHeight());
|
nsIntRect r(0, 0, mBIH.width, GetHeight());
|
||||||
PostInvalidation(r);
|
PostInvalidation(r);
|
||||||
|
|
||||||
if (mUseAlphaData) {
|
if (mUseAlphaData && mHaveAlphaData) {
|
||||||
PostFrameStop(Opacity::SOME_TRANSPARENCY);
|
PostFrameStop(Opacity::SOME_TRANSPARENCY);
|
||||||
} else {
|
} else {
|
||||||
PostFrameStop(Opacity::OPAQUE);
|
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
|
// 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
|
// also if they use RLE encoding, because the 'delta' mode can skip pixels
|
||||||
// and cause implicit transparency.
|
// and cause implicit transparency.
|
||||||
if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
|
bool hasTransparency = (mBIH.compression == BMPINFOHEADER::RLE8) ||
|
||||||
(mBIH.compression == BMPINFOHEADER::RLE4) ||
|
(mBIH.compression == BMPINFOHEADER::RLE4) ||
|
||||||
(mBIH.bpp == 32 && mUseAlphaData)) {
|
(mBIH.bpp == 32 && mUseAlphaData);
|
||||||
|
if (hasTransparency) {
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,18 +461,25 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(!mImageData, "Already have a buffer allocated?");
|
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)) {
|
if (NS_FAILED(rv)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
||||||
|
|
||||||
// Prepare for transparency
|
if (mDownscaler) {
|
||||||
if ((mBIH.compression == BMPINFOHEADER::RLE8) ||
|
// BMPs store their rows in reverse order, so the downscaler needs to
|
||||||
(mBIH.compression == BMPINFOHEADER::RLE4)) {
|
// reverse them again when writing its output.
|
||||||
// Clear the image, as the RLE may jump over areas
|
rv = mDownscaler->BeginFrame(GetSize(), mImageData, hasTransparency,
|
||||||
memset(mImageData, 0, mImageDataLength);
|
/* aFlipVertically = */ true);
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -606,8 +621,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
if (rowSize == mRowBytes) {
|
if (rowSize == mRowBytes) {
|
||||||
// Collected a whole row into mRow, process it
|
// Collected a whole row into mRow, process it
|
||||||
uint8_t* p = mRow;
|
uint8_t* p = mRow;
|
||||||
uint32_t* d = reinterpret_cast<uint32_t*>(mImageData) +
|
uint32_t* d = mDownscaler
|
||||||
PIXEL_OFFSET(mCurLine, 0);
|
? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
|
||||||
|
: reinterpret_cast<uint32_t*>(mImageData)
|
||||||
|
+ PIXEL_OFFSET(mCurLine, 0);
|
||||||
uint32_t lpos = mBIH.width;
|
uint32_t lpos = mBIH.width;
|
||||||
switch (mBIH.bpp) {
|
switch (mBIH.bpp) {
|
||||||
case 1:
|
case 1:
|
||||||
@ -664,28 +681,11 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
case 32:
|
case 32:
|
||||||
while (lpos > 0) {
|
while (lpos > 0) {
|
||||||
if (mUseAlphaData) {
|
if (mUseAlphaData) {
|
||||||
if (!mHaveAlphaData && p[3]) {
|
if (MOZ_UNLIKELY(!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));
|
|
||||||
|
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
mHaveAlphaData = true;
|
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 {
|
} else {
|
||||||
SetPixel(d, p[2], p[1], p[0]);
|
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,"
|
NS_NOTREACHED("Unsupported color depth,"
|
||||||
" but earlier check didn't catch it");
|
" but earlier check didn't catch it");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mDownscaler) {
|
||||||
|
mDownscaler->CommitRow();
|
||||||
|
}
|
||||||
|
|
||||||
mCurLine --;
|
mCurLine --;
|
||||||
if (mCurLine == 0) { // Finished last line
|
if (mCurLine == 0) { // Finished last line
|
||||||
break;
|
break;
|
||||||
@ -741,8 +746,12 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
uint32_t pixelsNeeded = std::min<uint32_t>(mBIH.width - mCurPos,
|
uint32_t pixelsNeeded = std::min<uint32_t>(mBIH.width - mCurPos,
|
||||||
mStateData);
|
mStateData);
|
||||||
if (pixelsNeeded) {
|
if (pixelsNeeded) {
|
||||||
uint32_t* d = reinterpret_cast<uint32_t*>
|
uint32_t* d = mDownscaler
|
||||||
(mImageData) + PIXEL_OFFSET(mCurLine, mCurPos);
|
? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
|
||||||
|
+ mCurPos
|
||||||
|
: reinterpret_cast<uint32_t*>(mImageData)
|
||||||
|
+ PIXEL_OFFSET(mCurLine, mCurPos);
|
||||||
|
|
||||||
mCurPos += pixelsNeeded;
|
mCurPos += pixelsNeeded;
|
||||||
if (mBIH.compression == BMPINFOHEADER::RLE8) {
|
if (mBIH.compression == BMPINFOHEADER::RLE8) {
|
||||||
do {
|
do {
|
||||||
@ -761,6 +770,10 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
switch(byte) {
|
switch(byte) {
|
||||||
case RLE::ESCAPE_EOL:
|
case RLE::ESCAPE_EOL:
|
||||||
// End of Line: Go to next row
|
// End of Line: Go to next row
|
||||||
|
if (mDownscaler) {
|
||||||
|
mDownscaler->CommitRow();
|
||||||
|
}
|
||||||
|
|
||||||
mCurLine --;
|
mCurLine --;
|
||||||
mCurPos = 0;
|
mCurPos = 0;
|
||||||
mState = eRLEStateInitial;
|
mState = eRLEStateInitial;
|
||||||
@ -810,11 +823,20 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
// Handle the XDelta and proceed to get Y Delta
|
// Handle the XDelta and proceed to get Y Delta
|
||||||
byte = *aBuffer++;
|
byte = *aBuffer++;
|
||||||
aCount--;
|
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;
|
mCurPos += byte;
|
||||||
|
|
||||||
// Delta encoding makes it possible to skip pixels
|
// Delta encoding makes it possible to skip pixels
|
||||||
// making the image transparent.
|
// making the image transparent.
|
||||||
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
|
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
|
mHaveAlphaData = true;
|
||||||
}
|
}
|
||||||
mUseAlphaData = mHaveAlphaData = true;
|
mUseAlphaData = mHaveAlphaData = true;
|
||||||
if (mCurPos > mBIH.width) {
|
if (mCurPos > mBIH.width) {
|
||||||
@ -824,7 +846,7 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
mState = eRLEStateNeedYDelta;
|
mState = eRLEStateNeedYDelta;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case eRLEStateNeedYDelta:
|
case eRLEStateNeedYDelta: {
|
||||||
// Get the Y Delta and then "handle" the move
|
// Get the Y Delta and then "handle" the move
|
||||||
byte = *aBuffer++;
|
byte = *aBuffer++;
|
||||||
aCount--;
|
aCount--;
|
||||||
@ -833,10 +855,26 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
// making the image transparent.
|
// making the image transparent.
|
||||||
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
|
if (MOZ_UNLIKELY(!mHaveAlphaData)) {
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
|
mHaveAlphaData = true;
|
||||||
}
|
}
|
||||||
mUseAlphaData = 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;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case eRLEStateAbsoluteMode: // Absolute Mode
|
case eRLEStateAbsoluteMode: // Absolute Mode
|
||||||
case eRLEStateAbsoluteModePadded:
|
case eRLEStateAbsoluteModePadded:
|
||||||
@ -845,9 +883,12 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
// represents the number of pixels
|
// represents the number of pixels
|
||||||
// that follow, each of which contains
|
// that follow, each of which contains
|
||||||
// the color index of a single pixel.
|
// the color index of a single pixel.
|
||||||
uint32_t* d = reinterpret_cast<uint32_t*>
|
uint32_t* d = mDownscaler
|
||||||
(mImageData) +
|
? reinterpret_cast<uint32_t*>(mDownscaler->RowBuffer())
|
||||||
PIXEL_OFFSET(mCurLine, mCurPos);
|
+ mCurPos
|
||||||
|
: reinterpret_cast<uint32_t*>(mImageData)
|
||||||
|
+ PIXEL_OFFSET(mCurLine, mCurPos);
|
||||||
|
|
||||||
uint32_t* oldPos = d;
|
uint32_t* oldPos = d;
|
||||||
if (mBIH.compression == BMPINFOHEADER::RLE8) {
|
if (mBIH.compression == BMPINFOHEADER::RLE8) {
|
||||||
while (aCount > 0 && mStateData > 0) {
|
while (aCount > 0 && mStateData > 0) {
|
||||||
@ -903,9 +944,15 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
const uint32_t rows = mOldLine - mCurLine;
|
const uint32_t rows = mOldLine - mCurLine;
|
||||||
if (rows) {
|
if (rows) {
|
||||||
// Invalidate
|
// Invalidate
|
||||||
nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
|
if (!mDownscaler) {
|
||||||
mBIH.width, rows);
|
nsIntRect r(0, mBIH.height < 0 ? -mBIH.height - mOldLine : mCurLine,
|
||||||
PostInvalidation(r);
|
mBIH.width, rows);
|
||||||
|
PostInvalidation(r);
|
||||||
|
} else if (mDownscaler->HasInvalidation()) {
|
||||||
|
DownscalerInvalidRect invalidRect = mDownscaler->TakeInvalidRect();
|
||||||
|
PostInvalidation(invalidRect.mOriginalSizeRect,
|
||||||
|
Some(invalidRect.mTargetSizeRect));
|
||||||
|
}
|
||||||
|
|
||||||
mOldLine = mCurLine;
|
mOldLine = mCurLine;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "BMPFileHeaders.h"
|
#include "BMPFileHeaders.h"
|
||||||
#include "Decoder.h"
|
#include "Decoder.h"
|
||||||
|
#include "Downscaler.h"
|
||||||
#include "gfxColor.h"
|
#include "gfxColor.h"
|
||||||
#include "nsAutoPtr.h"
|
#include "nsAutoPtr.h"
|
||||||
|
|
||||||
@ -24,6 +25,8 @@ class nsBMPDecoder : public Decoder
|
|||||||
public:
|
public:
|
||||||
~nsBMPDecoder();
|
~nsBMPDecoder();
|
||||||
|
|
||||||
|
nsresult SetTargetSize(const nsIntSize& aSize) override;
|
||||||
|
|
||||||
// Specifies whether or not the BMP file will contain alpha data
|
// 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
|
// If set to true and the BMP is 32BPP, the alpha data will be
|
||||||
// retrieved from the 4th byte of image data per pixel
|
// 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
|
// 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.
|
// 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,
|
virtual void WriteInternal(const char* aBuffer,
|
||||||
uint32_t aCount) override;
|
uint32_t aCount) override;
|
||||||
@ -71,6 +77,8 @@ private:
|
|||||||
char mRawBuf[BIH_INTERNAL_LENGTH::WIN_V3]; //< If this is changed,
|
char mRawBuf[BIH_INTERNAL_LENGTH::WIN_V3]; //< If this is changed,
|
||||||
// WriteInternal() MUST be updated
|
// WriteInternal() MUST be updated
|
||||||
|
|
||||||
|
Maybe<Downscaler> mDownscaler;
|
||||||
|
|
||||||
uint32_t mLOH; //< Length of the header
|
uint32_t mLOH; //< Length of the header
|
||||||
|
|
||||||
uint32_t mNumColors; //< The number of used colors, i.e. the number of
|
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
|
// If the bitmap is fully processed, treat any left over data as the ICO's
|
||||||
// 'AND buffer mask' which appears after the bitmap resource.
|
// 'AND buffer mask' which appears after the bitmap resource.
|
||||||
if (!mIsPNG && mPos >= bmpDataEnd) {
|
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
|
// 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
|
// 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
|
// is used for 32bpp bitmaps as per the comment in ICODecoder.h
|
||||||
// The alpha mask should be checked in all other cases.
|
// The alpha mask should be checked in all other cases.
|
||||||
if (static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
if (bmpDecoder->GetBitsPerPixel() != 32 || !bmpDecoder->HasAlphaData()) {
|
||||||
GetBitsPerPixel() != 32 ||
|
|
||||||
!static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
|
||||||
HasAlphaData()) {
|
|
||||||
uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
|
uint32_t rowSize = ((GetRealWidth() + 31) / 32) * 4; // + 31 to round up
|
||||||
if (mPos == bmpDataEnd) {
|
if (mPos == bmpDataEnd) {
|
||||||
mPos++;
|
mPos++;
|
||||||
@ -573,9 +573,7 @@ nsICODecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
mCurLine--;
|
mCurLine--;
|
||||||
mRowBytes = 0;
|
mRowBytes = 0;
|
||||||
|
|
||||||
uint32_t* imageData =
|
uint32_t* imageData = bmpDecoder->GetImageData();
|
||||||
static_cast<nsBMPDecoder*>(mContainedDecoder.get())->
|
|
||||||
GetImageData();
|
|
||||||
if (!imageData) {
|
if (!imageData) {
|
||||||
PostDataError();
|
PostDataError();
|
||||||
return;
|
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
|
// If any bits are set in sawTransparency, then we know at least one
|
||||||
// pixel was transparent.
|
// pixel was transparent.
|
||||||
if (sawTransparency) {
|
if (sawTransparency) {
|
||||||
PostHasTransparency();
|
PostHasTransparency();
|
||||||
|
bmpDecoder->SetHasAlphaData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,20 @@
|
|||||||
#include "RasterImage.h"
|
#include "RasterImage.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
|
using std::min;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace image {
|
namespace image {
|
||||||
|
|
||||||
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
||||||
: Decoder(aImage),
|
: Decoder(aImage)
|
||||||
mWidth(-1),
|
, mExpectedDataLength(0)
|
||||||
mHeight(-1),
|
, mPixBytesRead(0)
|
||||||
mPixBytesRead(0),
|
, mState(iconStateStart)
|
||||||
mState(iconStateStart)
|
, mWidth(-1)
|
||||||
|
, mHeight(-1)
|
||||||
{
|
{
|
||||||
// Nothing to do
|
// Nothing to do
|
||||||
}
|
}
|
||||||
@ -28,15 +33,25 @@ nsIconDecoder::nsIconDecoder(RasterImage* aImage)
|
|||||||
nsIconDecoder::~nsIconDecoder()
|
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
|
void
|
||||||
nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(!HasError(), "Shouldn't call WriteInternal after error!");
|
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
|
// Loop until the input data is gone
|
||||||
while (aCount > 0) {
|
while (aCount > 0) {
|
||||||
switch (mState) {
|
switch (mState) {
|
||||||
@ -73,9 +88,16 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
break;
|
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?");
|
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)) {
|
if (NS_FAILED(rv)) {
|
||||||
mState = iconStateFinished;
|
mState = iconStateFinished;
|
||||||
return;
|
return;
|
||||||
@ -84,6 +106,16 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
|
|
||||||
MOZ_ASSERT(mImageData, "Should have a buffer now");
|
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
|
// Book Keeping
|
||||||
aBuffer++;
|
aBuffer++;
|
||||||
aCount--;
|
aCount--;
|
||||||
@ -93,25 +125,60 @@ nsIconDecoder::WriteInternal(const char* aBuffer, uint32_t aCount)
|
|||||||
case iconStateReadPixels: {
|
case iconStateReadPixels: {
|
||||||
|
|
||||||
// How many bytes are we reading?
|
// How many bytes are we reading?
|
||||||
bytesToRead = std::min(aCount, mImageDataLength - mPixBytesRead);
|
uint32_t bytesToRead = min(aCount, mExpectedDataLength - mPixBytesRead);
|
||||||
|
|
||||||
// Copy the bytes
|
if (mDownscaler) {
|
||||||
memcpy(mImageData + mPixBytesRead, aBuffer, bytesToRead);
|
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
|
// Update global state; we're about to read |bytesToRead| bytes.
|
||||||
// always the full icon
|
aCount -= bytesToRead;
|
||||||
nsIntRect r(0, 0, mWidth, mHeight);
|
mPixBytesRead += bytesToRead;
|
||||||
|
|
||||||
// Invalidate
|
if (rowOffset > 0) {
|
||||||
PostInvalidation(r);
|
// Finish the current row.
|
||||||
|
const uint32_t remaining = bytesPerRow - rowOffset;
|
||||||
|
memcpy(row + rowOffset, aBuffer, remaining);
|
||||||
|
aBuffer += remaining;
|
||||||
|
bytesToRead -= remaining;
|
||||||
|
mDownscaler->CommitRow();
|
||||||
|
}
|
||||||
|
|
||||||
// Book Keeping
|
// Copy the bytes a row at a time.
|
||||||
aBuffer += bytesToRead;
|
while (bytesToRead > bytesPerRow) {
|
||||||
aCount -= bytesToRead;
|
memcpy(row, aBuffer, bytesPerRow);
|
||||||
mPixBytesRead += bytesToRead;
|
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 we've got all the pixel bytes, we're finished
|
||||||
if (mPixBytesRead == mImageDataLength) {
|
if (mPixBytesRead == mExpectedDataLength) {
|
||||||
PostFrameStop();
|
PostFrameStop();
|
||||||
PostDecodeDone();
|
PostDecodeDone();
|
||||||
mState = iconStateFinished;
|
mState = iconStateFinished;
|
||||||
|
@ -39,6 +39,8 @@ class nsIconDecoder : public Decoder
|
|||||||
public:
|
public:
|
||||||
virtual ~nsIconDecoder();
|
virtual ~nsIconDecoder();
|
||||||
|
|
||||||
|
virtual nsresult SetTargetSize(const nsIntSize& aSize) override;
|
||||||
|
|
||||||
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
|
virtual void WriteInternal(const char* aBuffer, uint32_t aCount) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -47,11 +49,13 @@ private:
|
|||||||
// Decoders should only be instantiated via DecoderFactory.
|
// Decoders should only be instantiated via DecoderFactory.
|
||||||
explicit nsIconDecoder(RasterImage* aImage);
|
explicit nsIconDecoder(RasterImage* aImage);
|
||||||
|
|
||||||
public:
|
Maybe<Downscaler> mDownscaler;
|
||||||
uint8_t mWidth;
|
|
||||||
uint8_t mHeight;
|
uint32_t mExpectedDataLength;
|
||||||
uint32_t mPixBytesRead;
|
uint32_t mPixBytesRead;
|
||||||
uint32_t mState;
|
uint32_t mState;
|
||||||
|
uint8_t mWidth;
|
||||||
|
uint8_t mHeight;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -1314,6 +1314,7 @@ if test "$GNU_CXX"; then
|
|||||||
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
|
||||||
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
|
||||||
# -Wpointer-to-int-cast - catches casts from pointer to different sized int
|
# -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
|
# -Wreorder - catches ctor initializer list not matching class definition order
|
||||||
# -Wreturn-type - catches missing returns, zero false positives
|
# -Wreturn-type - catches missing returns, zero false positives
|
||||||
# -Wsequence-point - catches undefined order behavior like `a = a++`
|
# -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=, 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=, 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)
|
MOZ_CXX_SUPPORTS_WARNING(-Werror=, sometimes-uninitialized, ac_cxx_has_sometimes_uninitialized)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -2620,7 +2620,8 @@ NS_IMETHODIMP nsDocumentViewer::SelectAll()
|
|||||||
|
|
||||||
NS_IMETHODIMP nsDocumentViewer::CopySelection()
|
NS_IMETHODIMP nsDocumentViewer::CopySelection()
|
||||||
{
|
{
|
||||||
nsCopySupport::FireClipboardEvent(NS_COPY, nsIClipboard::kGlobalClipboard, mPresShell, nullptr);
|
nsCopySupport::FireClipboardEvent(eCopy, nsIClipboard::kGlobalClipboard,
|
||||||
|
mPresShell, nullptr);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5320,7 +5320,7 @@ bool PresShell::AsyncPanZoomEnabled()
|
|||||||
return widget->AsyncPanZoomEnabled();
|
return widget->AsyncPanZoomEnabled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return gfxPlatform::AsyncPanZoomEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PresShell::SetIgnoreViewportScrolling(bool aIgnore)
|
void PresShell::SetIgnoreViewportScrolling(bool aIgnore)
|
||||||
|
@ -371,6 +371,11 @@ CommonAnimationManager::FlushAnimations()
|
|||||||
continue;
|
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);
|
collection->RequestRestyle(AnimationCollection::RestyleType::Standard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -883,10 +888,6 @@ AnimationCollection::RequestRestyle(RestyleType aRestyleType)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_ASSERT(mElement->GetCrossShadowCurrentDoc() == presContext->Document(),
|
|
||||||
"Element::UnbindFromTree should have destroyed the element "
|
|
||||||
"transition/animations object");
|
|
||||||
|
|
||||||
// Steps for Restyle::Layer:
|
// Steps for Restyle::Layer:
|
||||||
|
|
||||||
if (aRestyleType == RestyleType::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 1163446-1.html
|
||||||
load 1164813-1.html
|
load 1164813-1.html
|
||||||
load 1167782-1.html
|
load 1167782-1.html
|
||||||
|
load 1200568-1.html
|
||||||
load large_border_image_width.html
|
load large_border_image_width.html
|
||||||
load border-image-visited-link.html
|
load border-image-visited-link.html
|
||||||
|
@ -371,8 +371,9 @@ nsIStyleRule*
|
|||||||
nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
||||||
mozilla::dom::Element* aElement)
|
mozilla::dom::Element* aElement)
|
||||||
{
|
{
|
||||||
if (!mPresContext->IsDynamic()) {
|
// Ignore animations for print or print preview, and for elements
|
||||||
// For print or print preview, ignore animations.
|
// that are not attached to the document tree.
|
||||||
|
if (!mPresContext->IsDynamic() || !aElement->IsInComposedDoc()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +180,17 @@ PodEqual(const T* one, const T* two, size_t len)
|
|||||||
return !memcmp(one, two, len * sizeof(T));
|
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
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif /* mozilla_PodOperations_h */
|
#endif /* mozilla_PodOperations_h */
|
||||||
|
@ -1,84 +1 @@
|
|||||||
[testAboutPage]
|
[testAdobeFlash]
|
||||||
|
|
||||||
#[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]
|
|
||||||
|
@ -1786,7 +1786,7 @@ pref("network.generic-ntlm-auth.workstation", "WORKSTATION");
|
|||||||
// 1 - allow sub-resources to open HTTP authentication credentials dialogs,
|
// 1 - allow sub-resources to open HTTP authentication credentials dialogs,
|
||||||
// but don't allow it for cross-origin sub-resources
|
// but don't allow it for cross-origin sub-resources
|
||||||
// 2 - allow the cross-origin authentication as well.
|
// 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
|
pref("permissions.default.image", 1); // 1-Accept, 2-Deny, 3-dontAcceptForeign
|
||||||
|
|
||||||
|
@ -1288,6 +1288,8 @@ NS_IMETHODIMP
|
|||||||
HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
|
HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
|
||||||
nsACString& aValue)
|
nsACString& aValue)
|
||||||
{
|
{
|
||||||
|
aValue.Truncate();
|
||||||
|
|
||||||
// XXX might be better to search the header list directly instead of
|
// XXX might be better to search the header list directly instead of
|
||||||
// hitting the http atom hash table.
|
// hitting the http atom hash table.
|
||||||
nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
|
nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
|
||||||
@ -1333,6 +1335,8 @@ HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *visitor)
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
HttpBaseChannel::GetResponseHeader(const nsACString &header, nsACString &value)
|
HttpBaseChannel::GetResponseHeader(const nsACString &header, nsACString &value)
|
||||||
{
|
{
|
||||||
|
value.Truncate();
|
||||||
|
|
||||||
if (!mResponseHead)
|
if (!mResponseHead)
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ NullHttpChannel::SetReferrerWithPolicy(nsIURI *referrer, uint32_t referrerPolicy
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
NullHttpChannel::GetRequestHeader(const nsACString & aHeader, nsACString & _retval)
|
NullHttpChannel::GetRequestHeader(const nsACString & aHeader, nsACString & _retval)
|
||||||
{
|
{
|
||||||
|
_retval.Truncate();
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +168,7 @@ NullHttpChannel::GetRequestSucceeded(bool *aRequestSucceeded)
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
NullHttpChannel::GetResponseHeader(const nsACString & header, nsACString & _retval)
|
NullHttpChannel::GetResponseHeader(const nsACString & header, nsACString & _retval)
|
||||||
{
|
{
|
||||||
|
_retval.Truncate();
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,15 +75,15 @@ nsHttpChannelAuthProvider::~nsHttpChannelAuthProvider()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t nsHttpChannelAuthProvider::sAuthAllowPref =
|
uint32_t nsHttpChannelAuthProvider::sAuthAllowPref =
|
||||||
SUBRESOURCE_AUTH_DIALOG_DISALLOW_CROSS_ORIGIN;
|
SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL;
|
||||||
|
|
||||||
void
|
void
|
||||||
nsHttpChannelAuthProvider::InitializePrefs()
|
nsHttpChannelAuthProvider::InitializePrefs()
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
mozilla::Preferences::AddUintVarCache(&sAuthAllowPref,
|
mozilla::Preferences::AddUintVarCache(&sAuthAllowPref,
|
||||||
"network.auth.allow-subresource-auth",
|
"network.auth.subresource-http-auth-allow",
|
||||||
SUBRESOURCE_AUTH_DIALOG_DISALLOW_CROSS_ORIGIN);
|
SUBRESOURCE_AUTH_DIALOG_ALLOW_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
#include "nsHttpNTLMAuth.h"
|
#include "nsHttpNTLMAuth.h"
|
||||||
#include "nsIAuthModule.h"
|
#include "nsIAuthModule.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "plbase64.h"
|
#include "plbase64.h"
|
||||||
|
#include "plstr.h"
|
||||||
#include "prnetdb.h"
|
#include "prnetdb.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -733,6 +733,7 @@ NS_IMETHODIMP
|
|||||||
nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
|
nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
|
||||||
nsACString & aValue)
|
nsACString & aValue)
|
||||||
{
|
{
|
||||||
|
aValue.Truncate();
|
||||||
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
|
||||||
mHttpChannel->GetRequestHeader(aHeader, aValue);
|
mHttpChannel->GetRequestHeader(aHeader, aValue);
|
||||||
}
|
}
|
||||||
@ -820,6 +821,7 @@ NS_IMETHODIMP
|
|||||||
nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
|
nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
|
||||||
nsACString & aValue)
|
nsACString & aValue)
|
||||||
{
|
{
|
||||||
|
aValue.Truncate();
|
||||||
if (!mHttpChannel)
|
if (!mHttpChannel)
|
||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
@ -831,10 +833,9 @@ nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
|
|||||||
nsCaseInsensitiveCStringComparator()) &&
|
nsCaseInsensitiveCStringComparator()) &&
|
||||||
!aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
|
!aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
|
||||||
nsCaseInsensitiveCStringComparator())) {
|
nsCaseInsensitiveCStringComparator())) {
|
||||||
aValue.Truncate();
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mHttpChannel->GetResponseHeader(aHeader, aValue);
|
return mHttpChannel->GetResponseHeader(aHeader, aValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// This file tests authentication prompt depending on pref
|
// 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
|
// 0 - don't allow sub-resources to open HTTP authentication credentials
|
||||||
// dialogs
|
// dialogs
|
||||||
// 1 - 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;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Test(allow_subresource_auth_pref, loadingUri, uri, contentPolicy,
|
function Test(subresource_http_auth_allow_pref, loadingUri, uri, contentPolicy,
|
||||||
expectedCode) {
|
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._loadingUri = loadingUri;
|
||||||
this._uri = uri;
|
this._uri = uri;
|
||||||
this._contentPolicy = contentPolicy;
|
this._contentPolicy = contentPolicy;
|
||||||
@ -140,7 +140,7 @@ function Test(allow_subresource_auth_pref, loadingUri, uri, contentPolicy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Test.prototype = {
|
Test.prototype = {
|
||||||
_allow_subresource_auth_pref: 1,
|
_subresource_http_auth_allow_pref: 1,
|
||||||
_loadingUri: null,
|
_loadingUri: null,
|
||||||
_uri: null,
|
_uri: null,
|
||||||
_contentPolicy: Ci.nsIContentPolicy.TYPE_OTHER,
|
_contentPolicy: Ci.nsIContentPolicy.TYPE_OTHER,
|
||||||
@ -183,14 +183,14 @@ Test.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
run: function() {
|
run: function() {
|
||||||
dump("Run test: " + this._allow_subresource_auth_pref
|
dump("Run test: " + this._subresource_http_auth_allow_pref
|
||||||
+ this._loadingUri
|
+ this._loadingUri
|
||||||
+ this._uri
|
+ this._uri
|
||||||
+ this._contentPolicy
|
+ this._contentPolicy
|
||||||
+ this._expectedCode + " \n");
|
+ this._expectedCode + " \n");
|
||||||
|
|
||||||
prefs.setIntPref("network.auth.allow-subresource-auth",
|
prefs.setIntPref("network.auth.subresource-http-auth-allow",
|
||||||
this._allow_subresource_auth_pref);
|
this._subresource_http_auth_allow_pref);
|
||||||
let chan = makeChan(this._loadingUri, this._uri, this._contentPolicy);
|
let chan = makeChan(this._loadingUri, this._uri, this._contentPolicy);
|
||||||
chan.notificationCallbacks = new Requestor(this._expectedCode == 200);
|
chan.notificationCallbacks = new Requestor(this._expectedCode == 200);
|
||||||
chan.asyncOpen(this, null);
|
chan.asyncOpen(this, null);
|
||||||
|
@ -245,7 +245,7 @@ function run_test() {
|
|||||||
prefs.setIntPref("network.proxy.type", 1);
|
prefs.setIntPref("network.proxy.type", 1);
|
||||||
|
|
||||||
// Turn off the authentication dialog blocking for this test.
|
// 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]();
|
tests[current_test]();
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
|||||||
// Turn off the authentication dialog blocking for this test.
|
// Turn off the authentication dialog blocking for this test.
|
||||||
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||||
getService(Ci.nsIPrefBranch);
|
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() {
|
XPCOMUtils.defineLazyGetter(this, "URL", function() {
|
||||||
return "http://localhost:" + httpserv.identity.primaryPort;
|
return "http://localhost:" + httpserv.identity.primaryPort;
|
||||||
|
@ -79,10 +79,10 @@ class HgtoolVCS(ScriptMixin, LogMixin, TransferMixin):
|
|||||||
if self._is_windows():
|
if self._is_windows():
|
||||||
# SYSTEMROOT is needed for 'import random'
|
# SYSTEMROOT is needed for 'import random'
|
||||||
if 'SYSTEMROOT' not in env:
|
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
|
# HOME is needed for the 'hg help share' check
|
||||||
if 'HOME' not in env:
|
if 'HOME' not in env:
|
||||||
env['HOME'] = os.environ.get('HOME')
|
env['HOME'] = os.environ.get('HOME', '')
|
||||||
|
|
||||||
cmd = self.hgtool[:]
|
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):
|
def _query_props_set_by_mach(self, console_output=True, error_level=FATAL):
|
||||||
mach_properties_path = os.path.join(
|
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"
|
self.info("setting properties set by mach build. Looking in path: %s"
|
||||||
% mach_properties_path)
|
% mach_properties_path)
|
||||||
@ -1262,9 +1262,7 @@ or run without that action (ie: --no-{action})"
|
|||||||
if prop != 'UNKNOWN':
|
if prop != 'UNKNOWN':
|
||||||
self.set_buildbot_property(key, prop, write_to_file=True)
|
self.set_buildbot_property(key, prop, write_to_file=True)
|
||||||
else:
|
else:
|
||||||
self.log("Could not determine path for build properties. "
|
self.info("No mach_build_properties.json found - not importing properties.")
|
||||||
"Does this exist: `%s` ?" % mach_properties_path,
|
|
||||||
level=error_level)
|
|
||||||
|
|
||||||
def generate_build_props(self, console_output=True, halt_on_failure=False):
|
def generate_build_props(self, console_output=True, halt_on_failure=False):
|
||||||
"""sets props found from mach build and, in addition, buildid,
|
"""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._run_tooltool()
|
||||||
self._create_mozbuild_dir()
|
self._create_mozbuild_dir()
|
||||||
mach_props = os.path.join(
|
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):
|
if os.path.exists(mach_props):
|
||||||
self.info("Removing previous mach property file: %s" % mach_props)
|
self.info("Removing previous mach property file: %s" % mach_props)
|
||||||
|
@ -165,6 +165,13 @@ class FirefoxUITests(VCSToolsScript, VirtualenvMixin):
|
|||||||
else:
|
else:
|
||||||
self.fatal('Can\'t find symbols_url from installer_url: {}!'.format(installer_url))
|
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):
|
def checkout(self):
|
||||||
"""
|
"""
|
||||||
We checkout firefox_ui_tests and update to the right branch
|
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."""
|
"""All required steps for running the tests against an installer."""
|
||||||
dirs = self.query_abs_dirs()
|
dirs = self.query_abs_dirs()
|
||||||
|
|
||||||
bin_dir = os.path.dirname(self.query_python_path())
|
venv_python_path = self.query_python_path()
|
||||||
fx_ui_tests_bin = os.path.join(bin_dir, script_name)
|
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')
|
gecko_log = os.path.join(dirs['abs_log_dir'], 'gecko.log')
|
||||||
|
|
||||||
# Build the command
|
# Build the command
|
||||||
cmd = [
|
cmd = [
|
||||||
fx_ui_tests_bin,
|
venv_python_path,
|
||||||
|
update_script,
|
||||||
'--installer', installer_path,
|
'--installer', installer_path,
|
||||||
# Log to stdout until tests are stable.
|
# Log to stdout until tests are stable.
|
||||||
'--gecko-log=-',
|
'--gecko-log=-',
|
||||||
|
@ -214,8 +214,9 @@ class ReleaseFirefoxUIUpdateTests(FirefoxUIUpdateTests):
|
|||||||
|
|
||||||
@PreScriptAction('run-tests')
|
@PreScriptAction('run-tests')
|
||||||
def _pre_run_tests(self, action):
|
def _pre_run_tests(self, action):
|
||||||
assert 'release_update_config' in self.config, \
|
assert ('release_update_config' in self.config or
|
||||||
'You have to specify --release-update-config.'
|
self.installer_url or self.installer_path),
|
||||||
|
'Either specify --update-verify-config, --installer-url or --installer-path.'
|
||||||
|
|
||||||
def run_tests(self):
|
def run_tests(self):
|
||||||
dirs = self.query_abs_dirs()
|
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