зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team. a=merge
This commit is contained in:
Коммит
e1727505c9
|
@ -104,7 +104,7 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
|
|||
// or has a flat subtree.
|
||||
function isSingleLineage(acc) {
|
||||
for (let child = acc; child; child = child.firstChild) {
|
||||
if (child.childCount > 1) {
|
||||
if (Utils.visibleChildCount(child) > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
|
|||
if ([Roles.TEXT_LEAF, Roles.STATICTEXT].indexOf(child.role) >= 0) {
|
||||
continue;
|
||||
}
|
||||
if (child.childCount > 0 || child.actionCount > 0) {
|
||||
if (Utils.visibleChildCount(child) > 0 || child.actionCount > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,6 +360,16 @@ this.Utils = { // jshint ignore:line
|
|||
return hidden && hidden === 'true';
|
||||
},
|
||||
|
||||
visibleChildCount: function visibleChildCount(aAccessible) {
|
||||
let count = 0;
|
||||
for (let child = aAccessible.firstChild; child; child = child.nextSibling) {
|
||||
if (!this.isHidden(child)) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
inHiddenSubtree: function inHiddenSubtree(aAccessible) {
|
||||
for (let acc=aAccessible; acc; acc=acc.parent) {
|
||||
if (this.isHidden(acc)) {
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
<head>
|
||||
<title>Traversal Rule test document</title>
|
||||
<meta charset="utf-8" />
|
||||
<style>
|
||||
.content:before {
|
||||
content: "Content";
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h3 id="heading-1">A small first heading</h3>
|
||||
|
@ -96,6 +101,25 @@
|
|||
<td>1</td>
|
||||
</tr>
|
||||
</table>
|
||||
<section id="grid" role="grid">
|
||||
<ol role="row">
|
||||
<li role="presentation"></li>
|
||||
<li role="columnheader" aria-label="Sunday">S</li>
|
||||
<li role="columnheader">M</li>
|
||||
</ol>
|
||||
<ol role="row">
|
||||
<li role="rowheader" aria-label="Week 1">1</li>
|
||||
<li role="gridcell"><span>3</span><div></div></li>
|
||||
<li role="gridcell"><span>4</span><div>7</div></li>
|
||||
</ol>
|
||||
<ol role="row">
|
||||
<li role="rowheader">2</li>
|
||||
<li role="gridcell"><span>5</span><div role="presentation">8</div></li>
|
||||
<li id="gridcell4" role="gridcell">
|
||||
<span>6</span><div aria-hidden="true"><div class="content"></div></div>
|
||||
</li>
|
||||
</ol>
|
||||
</section>
|
||||
<div id="separator-2" role="separator">Just an innocuous separator</div>
|
||||
<table id="table-2">
|
||||
<thead>
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
['separator-1', 'separator-2']);
|
||||
|
||||
queueTraversalSequence(gQueue, docAcc, TraversalRules.Table, null,
|
||||
['table-1', 'table-2']);
|
||||
['table-1', 'grid', 'table-2']);
|
||||
|
||||
queueTraversalSequence(gQueue, docAcc, TraversalRules.Simple, null,
|
||||
['heading-1', 'Name:', 'input-1-1', 'label-1-2',
|
||||
|
@ -114,13 +114,15 @@
|
|||
' power is unfathomable.',
|
||||
'• Lists of Programming Languages', 'Lisp ',
|
||||
'1. Scheme', '2. Racket', '3. Clojure',
|
||||
'4. Standard Lisp', 'link-0', ' Lisp', 'checkbox-1-5',
|
||||
' LeLisp', '• JavaScript', 'heading-5',
|
||||
'image-2', 'image-3', 'Not actually an image',
|
||||
'link-1', 'anchor-1', 'link-2', 'anchor-2', 'link-3',
|
||||
'3', '1', '4', '1', 'Just an innocuous separator',
|
||||
'Dirty Words', 'Meaning', 'Mud', 'Wet Dirt',
|
||||
'Dirt', 'Messy Stuff']);
|
||||
'4. Standard Lisp', 'link-0', ' Lisp',
|
||||
'checkbox-1-5', ' LeLisp', '• JavaScript',
|
||||
'heading-5', 'image-2', 'image-3',
|
||||
'Not actually an image', 'link-1', 'anchor-1',
|
||||
'link-2', 'anchor-2', 'link-3', '3', '1', '4',
|
||||
'1', 'S', 'M', '1', '3', '4', '7', '2', '5', '8',
|
||||
'6', 'Just an innocuous separator', 'Dirty Words',
|
||||
'Meaning', 'Mud', 'Wet Dirt', 'Dirt',
|
||||
'Messy Stuff']);
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="20a1521efdac44c8219f00c2414de031891fb464"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="20a1521efdac44c8219f00c2414de031891fb464"/>
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "15291949ab37f96d1d1e30bb890a2604b4454894",
|
||||
"revision": "253fcdd727387f6ad023de9aed30a20e7b8bd72d",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="20a1521efdac44c8219f00c2414de031891fb464"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
|
||||
|
|
|
@ -207,6 +207,7 @@
|
|||
@BINPATH@/components/dom_xpath.xpt
|
||||
@BINPATH@/components/dom_xul.xpt
|
||||
@BINPATH@/components/dom_time.xpt
|
||||
@BINPATH@/components/dom_engineeringmode.xpt
|
||||
@BINPATH@/components/downloads.xpt
|
||||
@BINPATH@/components/editor.xpt
|
||||
@BINPATH@/components/embed_base.xpt
|
||||
|
@ -595,6 +596,10 @@
|
|||
@BINPATH@/components/MozKeyboard.js
|
||||
@BINPATH@/components/InputMethod.manifest
|
||||
|
||||
@BINPATH@/components/EngineeringMode.manifest
|
||||
@BINPATH@/components/EngineeringModeAPI.js
|
||||
@BINPATH@/components/EngineeringModeService.js
|
||||
|
||||
#ifdef MOZ_DEBUG
|
||||
@BINPATH@/components/TestInterfaceJS.js
|
||||
@BINPATH@/components/TestInterfaceJS.manifest
|
||||
|
|
|
@ -105,7 +105,7 @@ function test() {
|
|||
function test1(aCallback) {
|
||||
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
|
||||
checkWatchExpressions(26, {
|
||||
a: "ReferenceError: a is not defined, did you mean 'z'?",
|
||||
a: "ReferenceError: a is not defined",
|
||||
this: { type: "object", class: "Object" },
|
||||
prop: { type: "object", class: "String" },
|
||||
args: { type: "undefined" }
|
||||
|
|
|
@ -173,6 +173,9 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
|
|||
if (!mPolicies[p]->permits(aContentType,
|
||||
aContentLocation,
|
||||
nonce,
|
||||
// aExtra is only non-null if
|
||||
// the channel got redirected.
|
||||
(aExtra != nullptr),
|
||||
violatedDirective)) {
|
||||
// If the policy is violated and not report-only, reject the load and
|
||||
// report to the console
|
||||
|
@ -792,7 +795,8 @@ class CSPReportSenderRunnable MOZ_FINAL : public nsRunnable
|
|||
uint64_t aInnerWindowID,
|
||||
nsCSPContext* aCSPContext)
|
||||
: mBlockedContentSource(aBlockedContentSource)
|
||||
, mOriginalURI(aOriginalURI) , mViolatedPolicyIndex(aViolatedPolicyIndex)
|
||||
, mOriginalURI(aOriginalURI)
|
||||
, mViolatedPolicyIndex(aViolatedPolicyIndex)
|
||||
, mReportOnlyFlag(aReportOnlyFlag)
|
||||
, mViolatedDirective(aViolatedDirective)
|
||||
, mSourceFile(aSourceFile)
|
||||
|
@ -1024,6 +1028,7 @@ nsCSPContext::PermitsAncestry(nsIDocShell* aDocShell, bool* outPermitsAncestry)
|
|||
if (!mPolicies[i]->permits(nsIContentPolicy::TYPE_DOCUMENT,
|
||||
ancestorsArray[a],
|
||||
EmptyString(), // no nonce
|
||||
false, // no redirect
|
||||
violatedDirective)) {
|
||||
// Policy is violated
|
||||
// Send reports, but omit the ancestor URI if cross-origin as per spec
|
||||
|
|
|
@ -30,18 +30,21 @@ GetCspParserLog()
|
|||
|
||||
#define CSPPARSERLOG(args) PR_LOG(GetCspParserLog(), 4, args)
|
||||
|
||||
static const char16_t COLON = ':';
|
||||
static const char16_t SEMICOLON = ';';
|
||||
static const char16_t SLASH = '/';
|
||||
static const char16_t PLUS = '+';
|
||||
static const char16_t DASH = '-';
|
||||
static const char16_t DOT = '.';
|
||||
static const char16_t UNDERLINE = '_';
|
||||
static const char16_t WILDCARD = '*';
|
||||
static const char16_t WHITESPACE = ' ';
|
||||
static const char16_t SINGLEQUOTE = '\'';
|
||||
static const char16_t OPEN_CURL = '{';
|
||||
static const char16_t CLOSE_CURL = '}';
|
||||
static const char16_t COLON = ':';
|
||||
static const char16_t SEMICOLON = ';';
|
||||
static const char16_t SLASH = '/';
|
||||
static const char16_t PLUS = '+';
|
||||
static const char16_t DASH = '-';
|
||||
static const char16_t DOT = '.';
|
||||
static const char16_t UNDERLINE = '_';
|
||||
static const char16_t TILDE = '~';
|
||||
static const char16_t WILDCARD = '*';
|
||||
static const char16_t WHITESPACE = ' ';
|
||||
static const char16_t SINGLEQUOTE = '\'';
|
||||
static const char16_t OPEN_CURL = '{';
|
||||
static const char16_t CLOSE_CURL = '}';
|
||||
static const char16_t NUMBER_SIGN = '#';
|
||||
static const char16_t QUESTIONMARK = '?';
|
||||
|
||||
static uint32_t kSubHostPathCharacterCutoff = 512;
|
||||
|
||||
|
@ -145,6 +148,23 @@ nsCSPParser::resetCurChar(const nsAString& aToken)
|
|||
resetCurValue();
|
||||
}
|
||||
|
||||
// The path is terminated by the first question mark ("?") or
|
||||
// number sign ("#") character, or by the end of the URI.
|
||||
// http://tools.ietf.org/html/rfc3986#section-3.3
|
||||
bool
|
||||
nsCSPParser::atEndOfPath()
|
||||
{
|
||||
return (atEnd() || peek(QUESTIONMARK) || peek(NUMBER_SIGN));
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSPParser::atValidPathChar()
|
||||
{
|
||||
return (peek(isCharacterToken) || peek(isNumberToken) ||
|
||||
peek(DASH) || peek(DOT) ||
|
||||
peek(UNDERLINE) || peek(TILDE));
|
||||
}
|
||||
|
||||
void
|
||||
nsCSPParser::logWarningErrorToConsole(uint32_t aSeverityFlag,
|
||||
const char* aProperty,
|
||||
|
@ -189,25 +209,6 @@ nsCSPParser::schemeChar()
|
|||
accept(DOT);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCSPParser::fileAndArguments()
|
||||
{
|
||||
CSPPARSERLOG(("nsCSPParser::fileAndArguments, mCurToken: %s, mCurValue: %s",
|
||||
NS_ConvertUTF16toUTF8(mCurToken).get(),
|
||||
NS_ConvertUTF16toUTF8(mCurValue).get()));
|
||||
|
||||
// Possibly we already parsed part of the file in path(), therefore accepting "."
|
||||
if (accept(DOT) && !accept(isCharacterToken)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// From now on, accept pretty much anything to avoid unnecessary errors
|
||||
while (!atEnd()) {
|
||||
advance();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// port = ":" ( 1*DIGIT / "*" )
|
||||
bool
|
||||
nsCSPParser::port()
|
||||
|
@ -253,24 +254,23 @@ nsCSPParser::subPath(nsCSPHostSrc* aCspHost)
|
|||
// in case we are parsing unrecognized characters in the following loop.
|
||||
uint32_t charCounter = 0;
|
||||
|
||||
while (!atEnd() && !peek(DOT)) {
|
||||
++charCounter;
|
||||
while (hostChar() || accept(UNDERLINE)) {
|
||||
/* consume */
|
||||
++charCounter;
|
||||
}
|
||||
if (accept(SLASH)) {
|
||||
++charCounter;
|
||||
while (!atEndOfPath()) {
|
||||
if (peek(SLASH)) {
|
||||
aCspHost->appendPath(mCurValue);
|
||||
// Resetting current value since we are appending parts of the path
|
||||
// to aCspHost, e.g; "http://www.example.com/path1/path2" then the
|
||||
// first part is "/path1", second part "/path2"
|
||||
resetCurValue();
|
||||
}
|
||||
if (atEnd()) {
|
||||
return true;
|
||||
else if (!atValidPathChar()) {
|
||||
const char16_t* params[] = { mCurToken.get() };
|
||||
logWarningErrorToConsole(nsIScriptError::warningFlag,
|
||||
"couldntParseInvalidSource",
|
||||
params, ArrayLength(params));
|
||||
return false;
|
||||
}
|
||||
if (charCounter > kSubHostPathCharacterCutoff) {
|
||||
advance();
|
||||
if (++charCounter > kSubHostPathCharacterCutoff) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -298,7 +298,10 @@ nsCSPParser::path(nsCSPHostSrc* aCspHost)
|
|||
params, ArrayLength(params));
|
||||
return false;
|
||||
}
|
||||
if (atEnd()) {
|
||||
if (atEndOfPath()) {
|
||||
// one slash right after host [port] is also considered a path, e.g.
|
||||
// www.example.com/ should result in www.example.com/
|
||||
aCspHost->appendPath(mCurValue);
|
||||
return true;
|
||||
}
|
||||
// path can begin with "/" but not "//"
|
||||
|
@ -324,7 +327,7 @@ nsCSPParser::subHost()
|
|||
// in case we are parsing unrecognized characters in the following loop.
|
||||
uint32_t charCounter = 0;
|
||||
|
||||
while (!atEnd() && !peek(COLON) && !peek(SLASH)) {
|
||||
while (!atEndOfPath() && !peek(COLON) && !peek(SLASH)) {
|
||||
++charCounter;
|
||||
while (hostChar()) {
|
||||
/* consume */
|
||||
|
@ -468,7 +471,7 @@ nsCSPParser::hostSource()
|
|||
cspHost->setPort(mCurValue);
|
||||
}
|
||||
|
||||
if (atEnd()) {
|
||||
if (atEndOfPath()) {
|
||||
return cspHost;
|
||||
}
|
||||
|
||||
|
@ -482,14 +485,6 @@ nsCSPParser::hostSource()
|
|||
delete cspHost;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Calling fileAndArguments to see if there are any files to parse;
|
||||
// if an error occurs, fileAndArguments() reports the error; if
|
||||
// fileAndArguments returns true, we have a valid file, so we add it.
|
||||
if (fileAndArguments()) {
|
||||
cspHost->setFileAndArguments(mCurValue);
|
||||
}
|
||||
|
||||
return cspHost;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,7 +126,6 @@ class nsCSPParser {
|
|||
bool schemeChar();
|
||||
bool port();
|
||||
bool path(nsCSPHostSrc* aCspHost);
|
||||
bool fileAndArguments();
|
||||
|
||||
bool subHost(); // helper function to parse subDomains
|
||||
bool subPath(nsCSPHostSrc* aCspHost); // helper function to parse paths
|
||||
|
@ -173,6 +172,9 @@ class nsCSPParser {
|
|||
mCurValue.Truncate();
|
||||
}
|
||||
|
||||
bool atEndOfPath();
|
||||
bool atValidPathChar();
|
||||
|
||||
void resetCurChar(const nsAString& aToken);
|
||||
|
||||
void logWarningErrorToConsole(uint32_t aSeverityFlag,
|
||||
|
|
|
@ -214,7 +214,7 @@ nsCSPBaseSrc::~nsCSPBaseSrc()
|
|||
// nsCSPKeywordSrc and nsCSPHashSource fall back to this base class
|
||||
// implementation which will never allow the load.
|
||||
bool
|
||||
nsCSPBaseSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
|
||||
nsCSPBaseSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
|
@ -251,7 +251,7 @@ nsCSPSchemeSrc::~nsCSPSchemeSrc()
|
|||
}
|
||||
|
||||
bool
|
||||
nsCSPSchemeSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
|
||||
nsCSPSchemeSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
|
@ -288,7 +288,7 @@ nsCSPHostSrc::~nsCSPHostSrc()
|
|||
}
|
||||
|
||||
bool
|
||||
nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
|
||||
nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
|
@ -342,6 +342,34 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
|
|||
return false;
|
||||
}
|
||||
|
||||
// If there is a path, we have to enforce path-level matching,
|
||||
// unless the channel got redirected, see:
|
||||
// http://www.w3.org/TR/CSP11/#source-list-paths-and-redirects
|
||||
if (!aWasRedirected && !mPath.IsEmpty()) {
|
||||
// cloning uri so we can ignore the ref
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
aUri->CloneIgnoringRef(getter_AddRefs(uri));
|
||||
|
||||
nsAutoCString uriPath;
|
||||
rv = uri->GetPath(uriPath);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
// check if the last character of mPath is '/'; if so
|
||||
// we just have to check loading resource is within
|
||||
// the allowed path.
|
||||
if (mPath.Last() == '/') {
|
||||
if (!StringBeginsWith(NS_ConvertUTF8toUTF16(uriPath), mPath)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// otherwise mPath whitelists a specific file, and we have to
|
||||
// check if the loading resource matches that whitelisted file.
|
||||
else {
|
||||
if (!mPath.Equals(NS_ConvertUTF8toUTF16(uriPath))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If port uses wildcard, allow the load.
|
||||
if (mPort.EqualsASCII("*")) {
|
||||
return true;
|
||||
|
@ -369,7 +397,7 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
|
|||
}
|
||||
}
|
||||
|
||||
// At the end: scheme, host, port, match; allow the load.
|
||||
// At the end: scheme, host, path, and port match -> allow the load.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -397,9 +425,8 @@ nsCSPHostSrc::toString(nsAString& outStr) const
|
|||
outStr.Append(mPort);
|
||||
}
|
||||
|
||||
// in CSP 1.1, paths are ignoed
|
||||
// outStr.Append(mPath);
|
||||
// outStr.Append(mFileAndArguments);
|
||||
// append path
|
||||
outStr.Append(mPath);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -423,13 +450,6 @@ nsCSPHostSrc::appendPath(const nsAString& aPath)
|
|||
ToLowerCase(mPath);
|
||||
}
|
||||
|
||||
void
|
||||
nsCSPHostSrc::setFileAndArguments(const nsAString& aFile)
|
||||
{
|
||||
mFileAndArguments = aFile;
|
||||
ToLowerCase(mFileAndArguments);
|
||||
}
|
||||
|
||||
/* ===== nsCSPKeywordSrc ===================== */
|
||||
|
||||
nsCSPKeywordSrc::nsCSPKeywordSrc(CSPKeyword aKeyword)
|
||||
|
@ -469,7 +489,7 @@ nsCSPNonceSrc::~nsCSPNonceSrc()
|
|||
}
|
||||
|
||||
bool
|
||||
nsCSPNonceSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
|
||||
nsCSPNonceSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
|
@ -599,7 +619,7 @@ nsCSPDirective::~nsCSPDirective()
|
|||
}
|
||||
|
||||
bool
|
||||
nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce) const
|
||||
nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
|
@ -610,7 +630,7 @@ nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce) const
|
|||
#endif
|
||||
|
||||
for (uint32_t i = 0; i < mSrcs.Length(); i++) {
|
||||
if (mSrcs[i]->permits(aUri, aNonce)) {
|
||||
if (mSrcs[i]->permits(aUri, aNonce, aWasRedirected)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -621,7 +641,7 @@ bool
|
|||
nsCSPDirective::permits(nsIURI* aUri) const
|
||||
{
|
||||
nsString dummyNonce;
|
||||
return permits(aUri, dummyNonce);
|
||||
return permits(aUri, dummyNonce, false);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -754,6 +774,7 @@ bool
|
|||
nsCSPPolicy::permits(nsContentPolicyType aContentType,
|
||||
nsIURI* aUri,
|
||||
const nsAString& aNonce,
|
||||
bool aWasRedirected,
|
||||
nsAString& outViolatedDirective) const
|
||||
{
|
||||
#ifdef PR_LOGGING
|
||||
|
@ -774,7 +795,7 @@ nsCSPPolicy::permits(nsContentPolicyType aContentType,
|
|||
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
|
||||
// Check if the directive name matches
|
||||
if (mDirectives[i]->restrictsContentType(aContentType)) {
|
||||
if (!mDirectives[i]->permits(aUri, aNonce)) {
|
||||
if (!mDirectives[i]->permits(aUri, aNonce, aWasRedirected)) {
|
||||
mDirectives[i]->toString(outViolatedDirective);
|
||||
return false;
|
||||
}
|
||||
|
@ -795,7 +816,7 @@ nsCSPPolicy::permits(nsContentPolicyType aContentType,
|
|||
// If the above loop runs through, we haven't found a matching directive.
|
||||
// Avoid relooping, just store the result of default-src while looping.
|
||||
if (defaultDir) {
|
||||
if (!defaultDir->permits(aUri, aNonce)) {
|
||||
if (!defaultDir->permits(aUri, aNonce, aWasRedirected)) {
|
||||
defaultDir->toString(outViolatedDirective);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ class nsCSPBaseSrc {
|
|||
nsCSPBaseSrc();
|
||||
virtual ~nsCSPBaseSrc();
|
||||
|
||||
virtual bool permits(nsIURI* aUri, const nsAString& aNonce) const;
|
||||
virtual bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
|
||||
virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
|
||||
virtual void toString(nsAString& outStr) const = 0;
|
||||
};
|
||||
|
@ -203,7 +203,7 @@ class nsCSPSchemeSrc : public nsCSPBaseSrc {
|
|||
explicit nsCSPSchemeSrc(const nsAString& aScheme);
|
||||
virtual ~nsCSPSchemeSrc();
|
||||
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
|
||||
void toString(nsAString& outStr) const;
|
||||
|
||||
private:
|
||||
|
@ -217,20 +217,18 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
|
|||
explicit nsCSPHostSrc(const nsAString& aHost);
|
||||
virtual ~nsCSPHostSrc();
|
||||
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
|
||||
void toString(nsAString& outStr) const;
|
||||
|
||||
void setScheme(const nsAString& aScheme);
|
||||
void setPort(const nsAString& aPort);
|
||||
void appendPath(const nsAString &aPath);
|
||||
void setFileAndArguments(const nsAString& aFile);
|
||||
|
||||
private:
|
||||
nsString mScheme;
|
||||
nsString mHost;
|
||||
nsString mPort;
|
||||
nsString mPath;
|
||||
nsString mFileAndArguments;
|
||||
};
|
||||
|
||||
/* =============== nsCSPKeywordSrc ============ */
|
||||
|
@ -254,7 +252,7 @@ class nsCSPNonceSrc : public nsCSPBaseSrc {
|
|||
explicit nsCSPNonceSrc(const nsAString& aNonce);
|
||||
virtual ~nsCSPNonceSrc();
|
||||
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
|
||||
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
|
||||
void toString(nsAString& outStr) const;
|
||||
|
||||
|
@ -298,7 +296,7 @@ class nsCSPDirective {
|
|||
explicit nsCSPDirective(enum CSPDirective aDirective);
|
||||
virtual ~nsCSPDirective();
|
||||
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
|
||||
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
|
||||
bool permits(nsIURI* aUri) const;
|
||||
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
|
||||
void toString(nsAString& outStr) const;
|
||||
|
@ -331,6 +329,7 @@ class nsCSPPolicy {
|
|||
bool permits(nsContentPolicyType aContentType,
|
||||
nsIURI* aUri,
|
||||
const nsAString& aNonce,
|
||||
bool aWasRedirected,
|
||||
nsAString& outViolatedDirective) const;
|
||||
bool permitsBaseURI(nsIURI* aUri) const;
|
||||
bool allows(nsContentPolicyType aContentType,
|
||||
|
|
|
@ -1033,7 +1033,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
JS::Rooted<JS::Value> thisValue(cx, JS::UndefinedValue());
|
||||
|
||||
JS::Rooted<JS::Value> funval(cx);
|
||||
if (JS_ObjectIsCallable(cx, object)) {
|
||||
if (JS::IsCallable(object)) {
|
||||
// If the listener is a JS function:
|
||||
funval.setObject(*object);
|
||||
|
||||
|
@ -1055,7 +1055,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
// Check if the object is even callable.
|
||||
NS_ENSURE_STATE(JS_ObjectIsCallable(cx, &funval.toObject()));
|
||||
NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
|
||||
thisValue.setObject(*object);
|
||||
}
|
||||
|
||||
|
|
|
@ -3980,7 +3980,7 @@ ArrayBufferBuilder::setCapacity(uint32_t aNewCap)
|
|||
{
|
||||
MOZ_ASSERT(!mMapPtr);
|
||||
|
||||
uint8_t *newdata = (uint8_t *) realloc(mDataPtr, aNewCap);
|
||||
uint8_t *newdata = (uint8_t *) js_realloc(mDataPtr, aNewCap);
|
||||
if (!newdata) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -287,52 +287,70 @@ nsresult TestIgnorePaths() {
|
|||
{ "script-src http://www.example.com",
|
||||
"script-src http://www.example.com" },
|
||||
{ "script-src http://www.example.com/",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/" },
|
||||
{ "script-src http://www.example.com/path-1",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1" },
|
||||
{ "script-src http://www.example.com/path-1/",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/" },
|
||||
{ "script-src http://www.example.com/path-1/path_2",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/path_2" },
|
||||
{ "script-src http://www.example.com/path-1/path_2/",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/path_2/" },
|
||||
{ "script-src http://www.example.com/path-1/path_2/file.js",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/path_2/file.js" },
|
||||
{ "script-src http://www.example.com/path-1/path_2/file_1.js",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/path_2/file_1.js" },
|
||||
{ "script-src http://www.example.com/path-1/path_2/file-2.js",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/path_2/file-2.js" },
|
||||
{ "script-src http://www.example.com/path-1/path_2/f.js",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1/path_2/f.js" },
|
||||
{ "script-src http://www.example.com:88",
|
||||
"script-src http://www.example.com:88" },
|
||||
{ "script-src http://www.example.com:88/",
|
||||
"script-src http://www.example.com:88" },
|
||||
"script-src http://www.example.com:88/" },
|
||||
{ "script-src http://www.example.com:88/path-1",
|
||||
"script-src http://www.example.com:88" },
|
||||
"script-src http://www.example.com:88/path-1" },
|
||||
{ "script-src http://www.example.com:88/path-1/",
|
||||
"script-src http://www.example.com:88" },
|
||||
"script-src http://www.example.com:88/path-1/" },
|
||||
{ "script-src http://www.example.com:88/path-1/path_2",
|
||||
"script-src http://www.example.com:88" },
|
||||
"script-src http://www.example.com:88/path-1/path_2" },
|
||||
{ "script-src http://www.example.com:88/path-1/path_2/",
|
||||
"script-src http://www.example.com:88" },
|
||||
"script-src http://www.example.com:88/path-1/path_2/" },
|
||||
{ "script-src http://www.example.com:88/path-1/path_2/file.js",
|
||||
"script-src http://www.example.com:88" },
|
||||
"script-src http://www.example.com:88/path-1/path_2/file.js" },
|
||||
{ "script-src http://www.example.com:*",
|
||||
"script-src http://www.example.com:*" },
|
||||
{ "script-src http://www.example.com:*/",
|
||||
"script-src http://www.example.com:*" },
|
||||
"script-src http://www.example.com:*/" },
|
||||
{ "script-src http://www.example.com:*/path-1",
|
||||
"script-src http://www.example.com:*" },
|
||||
"script-src http://www.example.com:*/path-1" },
|
||||
{ "script-src http://www.example.com:*/path-1/",
|
||||
"script-src http://www.example.com:*" },
|
||||
"script-src http://www.example.com:*/path-1/" },
|
||||
{ "script-src http://www.example.com:*/path-1/path_2",
|
||||
"script-src http://www.example.com:*" },
|
||||
"script-src http://www.example.com:*/path-1/path_2" },
|
||||
{ "script-src http://www.example.com:*/path-1/path_2/",
|
||||
"script-src http://www.example.com:*" },
|
||||
"script-src http://www.example.com:*/path-1/path_2/" },
|
||||
{ "script-src http://www.example.com:*/path-1/path_2/file.js",
|
||||
"script-src http://www.example.com:*" },
|
||||
{ "report-uri http://www.example.com",
|
||||
"script-src http://www.example.com:*/path-1/path_2/file.js" },
|
||||
{ "script-src http://www.example.com#foo",
|
||||
"script-src http://www.example.com" },
|
||||
{ "script-src http://www.example.com?foo=bar",
|
||||
"script-src http://www.example.com" },
|
||||
{ "script-src http://www.example.com:8888#foo",
|
||||
"script-src http://www.example.com:8888" },
|
||||
{ "script-src http://www.example.com:8888?foo",
|
||||
"script-src http://www.example.com:8888" },
|
||||
{ "script-src http://www.example.com/#foo",
|
||||
"script-src http://www.example.com/" },
|
||||
{ "script-src http://www.example.com/?foo",
|
||||
"script-src http://www.example.com/" },
|
||||
{ "script-src http://www.example.com/path-1/file.js#foo",
|
||||
"script-src http://www.example.com/path-1/file.js" },
|
||||
{ "script-src http://www.example.com/path-1/file.js?foo",
|
||||
"script-src http://www.example.com/path-1/file.js" },
|
||||
{ "script-src http://www.example.com/path-1/file.js?foo#bar",
|
||||
"script-src http://www.example.com/path-1/file.js" },
|
||||
{ "report-uri http://www.example.com/",
|
||||
"report-uri http://www.example.com/" },
|
||||
{ "report-uri http://www.example.com:8888/asdf",
|
||||
"report-uri http://www.example.com:8888/asdf" },
|
||||
|
@ -401,9 +419,9 @@ nsresult TestSimplePolicies() {
|
|||
{ "script-src 'none' 'none' 'none';",
|
||||
"script-src 'none'" },
|
||||
{ "script-src http://www.example.com/path-1//",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1//" },
|
||||
{ "script-src http://www.example.com/path-1//path_2",
|
||||
"script-src http://www.example.com" },
|
||||
"script-src http://www.example.com/path-1//path_2" },
|
||||
{ "default-src 127.0.0.1",
|
||||
"default-src http://127.0.0.1" },
|
||||
{ "default-src 127.0.0.1:*",
|
||||
|
@ -619,21 +637,21 @@ nsresult TestGoodGeneratedPolicies() {
|
|||
{ "connect-src https://three:81",
|
||||
"connect-src https://three:81" },
|
||||
{ "script-src http://self.com:80/foo",
|
||||
"script-src http://self.com:80" },
|
||||
"script-src http://self.com:80/foo" },
|
||||
{ "object-src http://self.com/foo",
|
||||
"object-src http://self.com" },
|
||||
"object-src http://self.com/foo" },
|
||||
{ "report-uri /report.py",
|
||||
"report-uri http://www.selfuri.com/report.py"},
|
||||
{ "img-src http://foo.org:34/report.py",
|
||||
"img-src http://foo.org:34" },
|
||||
"img-src http://foo.org:34/report.py" },
|
||||
{ "media-src foo/bar/report.py",
|
||||
"media-src http://foo" },
|
||||
"media-src http://foo/bar/report.py" },
|
||||
{ "report-uri /",
|
||||
"report-uri http://www.selfuri.com/"},
|
||||
{ "font-src https://self.com/report.py",
|
||||
"font-src https://self.com" },
|
||||
"font-src https://self.com/report.py" },
|
||||
{ "connect-src https://foo.com/report.py",
|
||||
"connect-src https://foo.com" },
|
||||
"connect-src https://foo.com/report.py" },
|
||||
{ "default-src *; report-uri http://www.reporturi.com/",
|
||||
"default-src *; report-uri http://www.reporturi.com/" },
|
||||
{ "default-src http://first.com",
|
||||
|
@ -651,15 +669,15 @@ nsresult TestGoodGeneratedPolicies() {
|
|||
{ "frame-src http://bar.com",
|
||||
"frame-src http://bar.com" },
|
||||
{ "font-src http://self.com/",
|
||||
"font-src http://self.com" },
|
||||
"font-src http://self.com/" },
|
||||
{ "script-src 'self'",
|
||||
"script-src http://www.selfuri.com" },
|
||||
{ "default-src http://self.com/foo.png",
|
||||
"default-src http://self.com" },
|
||||
"default-src http://self.com/foo.png" },
|
||||
{ "script-src http://self.com/foo.js",
|
||||
"script-src http://self.com" },
|
||||
"script-src http://self.com/foo.js" },
|
||||
{ "object-src http://bar.com/foo.js",
|
||||
"object-src http://bar.com" },
|
||||
"object-src http://bar.com/foo.js" },
|
||||
{ "style-src http://FOO.COM",
|
||||
"style-src http://foo.com" },
|
||||
{ "img-src HTTP",
|
||||
|
@ -697,11 +715,11 @@ nsresult TestGoodGeneratedPolicies() {
|
|||
{ "frame-ancestors http://self:80",
|
||||
"frame-ancestors http://self:80" },
|
||||
{ "frame-ancestors http://self.com/bar",
|
||||
"frame-ancestors http://self.com" },
|
||||
"frame-ancestors http://self.com/bar" },
|
||||
{ "default-src 'self'; frame-ancestors 'self'",
|
||||
"default-src http://www.selfuri.com; frame-ancestors http://www.selfuri.com" },
|
||||
{ "frame-ancestors http://bar.com/foo.png",
|
||||
"frame-ancestors http://bar.com" },
|
||||
"frame-ancestors http://bar.com/foo.png" },
|
||||
};
|
||||
|
||||
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
|
||||
|
@ -747,111 +765,111 @@ nsresult TestGoodGeneratedPoliciesForPathHandling() {
|
|||
{ "img-src http://test1.example.com",
|
||||
"img-src http://test1.example.com" },
|
||||
{ "img-src http://test1.example.com/",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/" },
|
||||
{ "img-src http://test1.example.com/path-1",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1" },
|
||||
{ "img-src http://test1.example.com/path-1/",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/" },
|
||||
{ "img-src http://test1.example.com/path-1/path_2/",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/" },
|
||||
{ "img-src http://test1.example.com/path-1/path_2/file.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/file.js" },
|
||||
{ "img-src http://test1.example.com/path-1/path_2/file_1.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/file_1.js" },
|
||||
{ "img-src http://test1.example.com/path-1/path_2/file-2.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/file-2.js" },
|
||||
{ "img-src http://test1.example.com/path-1/path_2/f.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/f.js" },
|
||||
{ "img-src http://test1.example.com/path-1/path_2/f.oo.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/f.oo.js" },
|
||||
{ "img-src test1.example.com",
|
||||
"img-src http://test1.example.com" },
|
||||
{ "img-src test1.example.com/",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/" },
|
||||
{ "img-src test1.example.com/path-1",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1" },
|
||||
{ "img-src test1.example.com/path-1/",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/" },
|
||||
{ "img-src test1.example.com/path-1/path_2/",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/" },
|
||||
{ "img-src test1.example.com/path-1/path_2/file.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/file.js" },
|
||||
{ "img-src test1.example.com/path-1/path_2/file_1.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/file_1.js" },
|
||||
{ "img-src test1.example.com/path-1/path_2/file-2.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/file-2.js" },
|
||||
{ "img-src test1.example.com/path-1/path_2/f.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/f.js" },
|
||||
{ "img-src test1.example.com/path-1/path_2/f.oo.js",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/path-1/path_2/f.oo.js" },
|
||||
{ "img-src *.example.com",
|
||||
"img-src http://*.example.com" },
|
||||
{ "img-src *.example.com/",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/" },
|
||||
{ "img-src *.example.com/path-1",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1" },
|
||||
{ "img-src *.example.com/path-1/",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/" },
|
||||
{ "img-src *.example.com/path-1/path_2/",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/path_2/" },
|
||||
{ "img-src *.example.com/path-1/path_2/file.js",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/path_2/file.js" },
|
||||
{ "img-src *.example.com/path-1/path_2/file_1.js",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/path_2/file_1.js" },
|
||||
{ "img-src *.example.com/path-1/path_2/file-2.js",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/path_2/file-2.js" },
|
||||
{ "img-src *.example.com/path-1/path_2/f.js",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/path_2/f.js" },
|
||||
{ "img-src *.example.com/path-1/path_2/f.oo.js",
|
||||
"img-src http://*.example.com" },
|
||||
"img-src http://*.example.com/path-1/path_2/f.oo.js" },
|
||||
{ "img-src test1.example.com:80",
|
||||
"img-src http://test1.example.com:80" },
|
||||
{ "img-src test1.example.com:80/",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/" },
|
||||
{ "img-src test1.example.com:80/path-1",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/path-1" },
|
||||
{ "img-src test1.example.com:80/path-1/",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/path-1/" },
|
||||
{ "img-src test1.example.com:80/path-1/path_2",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/path-1/path_2" },
|
||||
{ "img-src test1.example.com:80/path-1/path_2/",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/path-1/path_2/" },
|
||||
{ "img-src test1.example.com:80/path-1/path_2/file.js",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/path-1/path_2/file.js" },
|
||||
{ "img-src test1.example.com:80/path-1/path_2/f.ile.js",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/path-1/path_2/f.ile.js" },
|
||||
{ "img-src test1.example.com:*",
|
||||
"img-src http://test1.example.com:*" },
|
||||
{ "img-src test1.example.com:*/",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/" },
|
||||
{ "img-src test1.example.com:*/path-1",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/path-1" },
|
||||
{ "img-src test1.example.com:*/path-1/",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/path-1/" },
|
||||
{ "img-src test1.example.com:*/path-1/path_2",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/path-1/path_2" },
|
||||
{ "img-src test1.example.com:*/path-1/path_2/",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/path-1/path_2/" },
|
||||
{ "img-src test1.example.com:*/path-1/path_2/file.js",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/path-1/path_2/file.js" },
|
||||
{ "img-src test1.example.com:*/path-1/path_2/f.ile.js",
|
||||
"img-src http://test1.example.com:*" },
|
||||
"img-src http://test1.example.com:*/path-1/path_2/f.ile.js" },
|
||||
{ "img-src http://test1.example.com/abc//",
|
||||
"img-src http://test1.example.com" },
|
||||
"img-src http://test1.example.com/abc//" },
|
||||
{ "img-src https://test1.example.com/abc/def//",
|
||||
"img-src https://test1.example.com" },
|
||||
"img-src https://test1.example.com/abc/def//" },
|
||||
{ "img-src https://test1.example.com/abc/def/ghi//",
|
||||
"img-src https://test1.example.com" },
|
||||
"img-src https://test1.example.com/abc/def/ghi//" },
|
||||
{ "img-src http://test1.example.com:80/abc//",
|
||||
"img-src http://test1.example.com:80" },
|
||||
"img-src http://test1.example.com:80/abc//" },
|
||||
{ "img-src https://test1.example.com:80/abc/def//",
|
||||
"img-src https://test1.example.com:80" },
|
||||
"img-src https://test1.example.com:80/abc/def//" },
|
||||
{ "img-src https://test1.example.com:80/abc/def/ghi//",
|
||||
"img-src https://test1.example.com:80" },
|
||||
"img-src https://test1.example.com:80/abc/def/ghi//" },
|
||||
{ "img-src https://test1.example.com/abc////////////def/",
|
||||
"img-src https://test1.example.com" },
|
||||
"img-src https://test1.example.com/abc////////////def/" },
|
||||
{ "img-src https://test1.example.com/abc////////////",
|
||||
"img-src https://test1.example.com" },
|
||||
"img-src https://test1.example.com/abc////////////" },
|
||||
};
|
||||
|
||||
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
|
||||
|
|
|
@ -223,7 +223,7 @@
|
|||
// (the privileged junk scope, but we don't have a good way to test for that
|
||||
// specifically).
|
||||
is(unprivilegedObject.expando, undefined, "parent->child references should get Xrays");
|
||||
todo_is(unprivilegedObject.wrappedJSObject.expando, 42, "parent->child references should get waivable Xrays - see bug 1065811");
|
||||
is(unprivilegedObject.wrappedJSObject.expando, 42, "parent->child references should get waivable Xrays");
|
||||
|
||||
// Send an object to the child to let it verify invariants in the other direction.
|
||||
function passMe() { return 42; };
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 916054 - URLs with path are ignored by FF's CSP parser</title>
|
||||
<title>Bug 808292 - Implement path-level host-source matching to CSP</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testdiv">blocked</div>
|
||||
<script src="http://test1.example.com/tests/content/base/test/csp/file_csp_regexp_parsing.js"></script>
|
||||
<script src="http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js#foo"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 808292 - Implement path-level host-source matching to CSP</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="testdiv">blocked</div>
|
||||
<script src="http://example.com/tests/content/base/test/csp/file_csp_path_matching_redirect_server.sjs"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,13 @@
|
|||
// Redirect server specifically to handle redirects
|
||||
// for path-level host-source matching
|
||||
// see https://bugzilla.mozilla.org/show_bug.cgi?id=808292
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
|
||||
var newLocation = "http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js";
|
||||
|
||||
response.setStatusLine("1.1", 302, "Found");
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Location", newLocation, false);
|
||||
}
|
|
@ -81,9 +81,11 @@ support-files =
|
|||
file_hash_source.html^headers^
|
||||
file_self_none_as_hostname_confusion.html
|
||||
file_self_none_as_hostname_confusion.html^headers^
|
||||
file_csp_path_matching.html
|
||||
file_csp_path_matching.js
|
||||
file_csp_path_matching_redirect.html
|
||||
file_csp_path_matching_redirect_server.sjs
|
||||
file_csp_testserver.sjs
|
||||
file_csp_regexp_parsing.html
|
||||
file_csp_regexp_parsing.js
|
||||
file_report_uri_missing_in_report_only_header.html
|
||||
file_report_uri_missing_in_report_only_header.html^headers^
|
||||
file_csp_report.html
|
||||
|
@ -121,7 +123,8 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'and
|
|||
skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
|
||||
[test_self_none_as_hostname_confusion.html]
|
||||
[test_bug949549.html]
|
||||
[test_csp_regexp_parsing.html]
|
||||
[test_csp_path_matching.html]
|
||||
[test_csp_path_matching_redirect.html]
|
||||
[test_report_uri_missing_in_report_only_header.html]
|
||||
[test_csp_report.html]
|
||||
skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observer not supported in child process (bug 1009632)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 916054 - URLs with path are ignored by FF's CSP parser</title>
|
||||
<title>Bug 808292 - Implement path-level host-source matching to CSP</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
|
@ -16,49 +16,51 @@
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/* Description of the test:
|
||||
* We are loading the following url (including a fragment portion):
|
||||
* http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js#foo
|
||||
* using different policies and verify that the applied policy is accurately enforced.
|
||||
*/
|
||||
|
||||
var policies = [
|
||||
["allowed", "*"],
|
||||
["allowed", "test1.example.com"],
|
||||
["allowed", "test1.example.com/"],
|
||||
["allowed", "test1.example.com/path-1"],
|
||||
["allowed", "test1.example.com/path-1/"],
|
||||
["allowed", "test1.example.com/path-1/path_2/"],
|
||||
["allowed", "test1.example.com/path-1/path_2/file.js"],
|
||||
["allowed", "test1.example.com/path-1/path_2/file_1.js"],
|
||||
["allowed", "test1.example.com/path-1/path_2/file-2.js"],
|
||||
["allowed", "test1.example.com/path-1/path_2/f.js"],
|
||||
["allowed", "test1.example.com/path-1/path_2/f.oo.js"],
|
||||
["allowed", "test1.example.com/tests/content/base/test/csp/"],
|
||||
["allowed", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js"],
|
||||
|
||||
["allowed", "test1.example.com?foo=val"],
|
||||
["allowed", "test1.example.com/?foo=val"],
|
||||
["allowed", "test1.example.com/tests/content/base/test/csp/?foo=val"],
|
||||
["allowed", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js?foo=val"],
|
||||
|
||||
["allowed", "test1.example.com#foo"],
|
||||
["allowed", "test1.example.com/#foo"],
|
||||
["allowed", "test1.example.com/tests/content/base/test/csp/#foo"],
|
||||
["allowed", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js#foo"],
|
||||
|
||||
["allowed", "*.example.com"],
|
||||
["allowed", "*.example.com/"],
|
||||
["allowed", "*.example.com/path-1"],
|
||||
["allowed", "*.example.com/path-1/"],
|
||||
["allowed", "*.example.com/path-1/path_2/"],
|
||||
["allowed", "*.example.com/path-1/path_2/file.js"],
|
||||
["allowed", "*.example.com/path-1/path_2/file_1.js"],
|
||||
["allowed", "*.example.com/path-1/path_2/file-2.js"],
|
||||
["allowed", "*.example.com/path-1/path_2/f.js"],
|
||||
["allowed", "*.example.com/path-1/path_2/f.oo.js"],
|
||||
["allowed", "*.example.com/tests/content/base/test/csp/"],
|
||||
["allowed", "*.example.com/tests/content/base/test/csp/file_csp_path_matching.js"],
|
||||
|
||||
["allowed", "test1.example.com:80"],
|
||||
["allowed", "test1.example.com:80/"],
|
||||
["allowed", "test1.example.com:80/path-1"],
|
||||
["allowed", "test1.example.com:80/path-1/"],
|
||||
["allowed", "test1.example.com:80/path-1/path_2"],
|
||||
["allowed", "test1.example.com:80/path-1/path_2/"],
|
||||
["allowed", "test1.example.com:80/path-1/path_2/file.js"],
|
||||
["allowed", "test1.example.com:80/path-1/path_2/f.ile.js"],
|
||||
["allowed", "test1.example.com:80/tests/content/base/test/csp/"],
|
||||
["allowed", "test1.example.com:80/tests/content/base/test/csp/file_csp_path_matching.js"],
|
||||
|
||||
["allowed", "test1.example.com:*"],
|
||||
["allowed", "test1.example.com:*/"],
|
||||
["allowed", "test1.example.com:*/path-1"],
|
||||
["allowed", "test1.example.com:*/path-1/"],
|
||||
["allowed", "test1.example.com:*/path-1/path_2"],
|
||||
["allowed", "test1.example.com:*/path-1/path_2/"],
|
||||
["allowed", "test1.example.com:*/path-1/path_2/file.js"],
|
||||
["allowed", "test1.example.com:*/path-1/path_2/f.ile.js"],
|
||||
// the following tests should fail
|
||||
["blocked", "test1.example.com:88path-1/"],
|
||||
["blocked", "test1.example.com:80.js"],
|
||||
["blocked", "test1.example.com:*.js"],
|
||||
["blocked", "test1.example.com:*."]
|
||||
["allowed", "test1.example.com:*/tests/content/base/test/csp/"],
|
||||
["allowed", "test1.example.com:*/tests/content/base/test/csp/file_csp_path_matching.js"],
|
||||
|
||||
["blocked", "test1.example.com/tests"],
|
||||
["blocked", "test1.example.com/tests/content/base/test/csp"],
|
||||
["blocked", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.py"],
|
||||
|
||||
["blocked", "test1.example.com:8888/tests"],
|
||||
["blocked", "test1.example.com:8888/tests/content/base/test/csp"],
|
||||
["blocked", "test1.example.com:8888/tests/content/base/test/csp/file_csp_path_matching.py"],
|
||||
]
|
||||
|
||||
var counter = 0;
|
||||
|
@ -72,7 +74,7 @@ function loadNextTest() {
|
|||
policy = policies[counter++];
|
||||
var src = "file_csp_testserver.sjs";
|
||||
// append the file that should be served
|
||||
src += "?file=" + escape("tests/content/base/test/csp/file_csp_regexp_parsing.html");
|
||||
src += "?file=" + escape("tests/content/base/test/csp/file_csp_path_matching.html");
|
||||
// append the CSP that should be used to serve the file
|
||||
src += "&csp=" + escape("default-src 'none'; script-src " + policy[1]);
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 808292 - Implement path-level host-source matching to CSP (redirects)</title>
|
||||
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="visibility: hidden">
|
||||
<iframe style="width:100%;" id="testframe"></iframe>
|
||||
</div>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
/* Description of the test:
|
||||
* First, we try to load a script where the *path* does not match.
|
||||
* Second, we try to load a script which is allowed by the CSPs
|
||||
* script-src directive. The script then gets redirected to
|
||||
* an URL where the host matches, but the path wouldn't.
|
||||
* Since 'paths' should not be taken into account after redirects,
|
||||
* that load should succeed. We are using a similar test setup
|
||||
* as described in the spec, see:
|
||||
* http://www.w3.org/TR/CSP11/#source-list-paths-and-redirects
|
||||
*/
|
||||
|
||||
var policy = "script-src http://example.com http://test1.example.com/CSPAllowsScriptsInThatFolder";
|
||||
|
||||
var tests = [
|
||||
{
|
||||
// the script in file_csp_path_matching.html
|
||||
// <script src="http://test1.example.com/tests/content/base/..">
|
||||
// is not within the whitelisted path by the csp-policy
|
||||
// hence the script is 'blocked' by CSP.
|
||||
expected: "blocked",
|
||||
uri: "tests/content/base/test/csp/file_csp_path_matching.html"
|
||||
},
|
||||
{
|
||||
// the script in file_csp_path_matching_redirect.html
|
||||
// <script src="http://example.com/tests/content/..">
|
||||
// gets redirected to: http://test1.example.com/tests/content
|
||||
// where after the redirect the path of the policy is not enforced
|
||||
// anymore and hence execution of the script is 'allowed'.
|
||||
expected: "allowed",
|
||||
uri: "tests/content/base/test/csp/file_csp_path_matching_redirect.html"
|
||||
},
|
||||
];
|
||||
|
||||
var counter = 0;
|
||||
var curTest;
|
||||
|
||||
function checkResult() {
|
||||
try {
|
||||
document.getElementById("testframe").removeEventListener('load', checkResult, false);
|
||||
var testframe = document.getElementById("testframe");
|
||||
var divcontent = testframe.contentWindow.document.getElementById('testdiv').innerHTML;
|
||||
is(divcontent, curTest.expected, "should be blocked in test " + (counter - 1) + "!");
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "ERROR: could not access content in test " + (counter - 1) + "!");
|
||||
}
|
||||
loadNextTest();
|
||||
}
|
||||
|
||||
function loadNextTest() {
|
||||
if (counter == tests.length) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
else {
|
||||
curTest = tests[counter++];
|
||||
var src = "file_csp_testserver.sjs";
|
||||
// append the file that should be served
|
||||
src += "?file=" + escape(curTest.uri);
|
||||
// append the CSP that should be used to serve the file
|
||||
src += "&csp=" + escape(policy);
|
||||
|
||||
document.getElementById("testframe").addEventListener("load", checkResult, false);
|
||||
document.getElementById("testframe").src = src;
|
||||
}
|
||||
}
|
||||
|
||||
loadNextTest();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -33,8 +33,7 @@ window.onerror = function(message, uri, line) {
|
|||
</script>
|
||||
<script type="application/javascript">
|
||||
window.onerror = function(message, uri, line) {
|
||||
ok(message.contains("ReferenceError: c is not defined"),
|
||||
"Should have correct error message");
|
||||
is(message, "ReferenceError: c is not defined", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://mochi.test:8888/tests/content/base/test/bug461735-redirect2.sjs",
|
||||
"Unexpected error location URI");
|
||||
|
|
|
@ -38,8 +38,7 @@ window.onerror = function(message, uri, line) {
|
|||
errorFired = false;
|
||||
global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
ok(message.contains("ReferenceError: c is not defined"),
|
||||
"Should have correct error message");
|
||||
is(message, "ReferenceError: c is not defined", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-1.js",
|
||||
"Should also have correct script URI");
|
||||
|
|
|
@ -40,8 +40,7 @@ window.onerror = function(message, uri, line) {
|
|||
errorFired = false;
|
||||
global = "";
|
||||
window.onerror = function(message, uri, line) {
|
||||
ok(message.contains("ReferenceError: c is not defined"),
|
||||
"Should have correct error message");
|
||||
is(message, "ReferenceError: c is not defined", "Should have correct error message");
|
||||
is(uri,
|
||||
"http://example.com/tests/content/base/test/bug696301-script-1.js",
|
||||
"Should also have correct script URI");
|
||||
|
|
|
@ -222,6 +222,14 @@ let Activities = {
|
|||
startActivity: function activities_startActivity(aMsg) {
|
||||
debug("StartActivity: " + JSON.stringify(aMsg));
|
||||
|
||||
// The caller app will be killed by |assertAppHasStatus| if it doesn't
|
||||
// fit our permission requirement.
|
||||
let callerApp = this.callers[aMsg.id].mm;
|
||||
if (aMsg.options.name === 'internal-system-engineering-mode' &&
|
||||
!callerApp.assertAppHasStatus(Ci.nsIPrincipal.APP_STATUS_CERTIFIED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let self = this;
|
||||
let successCb = function successCb(aResults) {
|
||||
debug(JSON.stringify(aResults));
|
||||
|
@ -341,6 +349,12 @@ let Activities = {
|
|||
};
|
||||
|
||||
let matchFunc = function matchFunc(aResult) {
|
||||
let calleeApp = DOMApplicationRegistry.getAppByManifestURL(aResult.manifest);
|
||||
// Only allow certified apps to handle this special activity
|
||||
if (aMsg.options.name === 'internal-system-engineering-mode' &&
|
||||
calleeApp.appStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
return false;
|
||||
}
|
||||
return ActivitiesServiceFilter.match(aMsg.options.data,
|
||||
aResult.description.filters);
|
||||
};
|
||||
|
|
|
@ -56,7 +56,15 @@ ActivityProxy.prototype = {
|
|||
// Only let certified apps enumerate providers for this filter.
|
||||
if (aOptions.getFilterResults === true &&
|
||||
principal.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
Services.DOMRequest.fireError(this.activity, "SecurityError");
|
||||
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
|
||||
Services.obs.notifyObservers(null, "Activity:Error", null);
|
||||
return;
|
||||
}
|
||||
|
||||
// Only let certified app to initiate this activitiy.
|
||||
if (aOptions.name === 'internal-system-engineering-mode' &&
|
||||
principal.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
|
||||
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
|
||||
Services.obs.notifyObservers(null, "Activity:Error", null);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_AnimationUtils_h
|
||||
#define mozilla_dom_AnimationUtils_h
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/dom/Nullable.h"
|
||||
|
||||
|
@ -27,3 +30,5 @@ public:
|
|||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,7 +14,7 @@ EXPORTS.mozilla.dom += [
|
|||
'AnimationTimeline.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'Animation.cpp',
|
||||
'AnimationEffect.cpp',
|
||||
'AnimationPlayer.cpp',
|
||||
|
|
|
@ -487,6 +487,12 @@ this.PermissionsTable = { geolocation: {
|
|||
certified: ALLOW_ACTION,
|
||||
access: ["read", "write"],
|
||||
additional: ["settings-api"]
|
||||
},
|
||||
"engineering-mode": {
|
||||
app: DENY_ACTION,
|
||||
trusted: DENY_ACTION,
|
||||
privileged: DENY_ACTION,
|
||||
certified: ALLOW_ACTION
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1535,7 +1535,7 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
|
|||
}
|
||||
|
||||
// Check if the object is even callable.
|
||||
NS_ENSURE_STATE(JS_ObjectIsCallable(cx, &funval.toObject()));
|
||||
NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
|
||||
{
|
||||
// wrap parameters in the target compartment
|
||||
// we also pass in the calling window as the first argument
|
||||
|
|
|
@ -5274,7 +5274,7 @@ nsGlobalWindow::RequestAnimationFrame(JS::Handle<JS::Value> aCallback,
|
|||
JSContext* cx,
|
||||
int32_t* aHandle)
|
||||
{
|
||||
if (!aCallback.isObject() || !JS_ObjectIsCallable(cx, &aCallback.toObject())) {
|
||||
if (!aCallback.isObject() || !JS::IsCallable(&aCallback.toObject())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
|
|
@ -1699,7 +1699,7 @@ NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
if (!JS_WrapValue(cx, &toString)) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(JS_ObjectIsCallable(cx, &toString.toObject()));
|
||||
MOZ_ASSERT(JS::IsCallable(&toString.toObject()));
|
||||
JS::Rooted<JS::Value> toStringResult(cx);
|
||||
if (JS_CallFunctionValue(cx, obj, toString, JS::HandleValueArray::empty(),
|
||||
&toStringResult)) {
|
||||
|
|
|
@ -20,7 +20,7 @@ CallbackInterface::GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
|
|||
return false;
|
||||
}
|
||||
if (!aCallable.isObject() ||
|
||||
!JS_ObjectIsCallable(cx, &aCallable.toObject())) {
|
||||
!JS::IsCallable(&aCallable.toObject())) {
|
||||
char* propName =
|
||||
JS_EncodeString(cx, JS_FORGET_STRING_FLATNESS(JSID_TO_FLAT_STRING(aPropId)));
|
||||
nsPrintfCString description("Property '%s'", propName);
|
||||
|
|
|
@ -4911,7 +4911,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
conversion = indent(CGCallbackTempRoot(name).define())
|
||||
|
||||
if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
|
||||
haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
|
||||
haveCallable = "JS::IsCallable(&${val}.toObject())"
|
||||
if not isDefinitelyObject:
|
||||
haveCallable = "${val}.isObject() && " + haveCallable
|
||||
if defaultValue is not None:
|
||||
|
@ -4936,7 +4936,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
template = conversion
|
||||
else:
|
||||
template = wrapObjectTemplate(
|
||||
"if (JS_ObjectIsCallable(cx, &${val}.toObject())) {\n" +
|
||||
"if (JS::IsCallable(&${val}.toObject())) {\n" +
|
||||
conversion +
|
||||
"} else {\n" +
|
||||
indent(onFailureNotCallable(failureCode).define()) +
|
||||
|
@ -13417,7 +13417,7 @@ class CGCallback(CGClass):
|
|||
def getConstructors(self):
|
||||
if (not self.idlObject.isInterface() and
|
||||
not self.idlObject._treatNonObjectAsNull):
|
||||
body = "MOZ_ASSERT(JS_ObjectIsCallable(nullptr, mCallback));\n"
|
||||
body = "MOZ_ASSERT(JS::IsCallable(mCallback));\n"
|
||||
else:
|
||||
# Not much we can assert about it, other than not being null, and
|
||||
# CallbackObject does that already.
|
||||
|
@ -13879,7 +13879,7 @@ class CallCallback(CallbackMethod):
|
|||
|
||||
def getCallGuard(self):
|
||||
if self.callback._treatNonObjectAsNull:
|
||||
return "JS_ObjectIsCallable(cx, mCallback) && "
|
||||
return "JS::IsCallable(mCallback) && "
|
||||
return ""
|
||||
|
||||
|
||||
|
@ -13927,7 +13927,7 @@ class CallbackOperationBase(CallbackMethod):
|
|||
return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
|
||||
return fill(
|
||||
"""
|
||||
bool isCallable = JS_ObjectIsCallable(cx, mCallback);
|
||||
bool isCallable = JS::IsCallable(mCallback);
|
||||
JS::Rooted<JS::Value> callable(cx);
|
||||
if (isCallable) {
|
||||
callable = JS::ObjectValue(*mCallback);
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
|
||||
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothSocketInterface();
|
||||
};
|
||||
|
|
|
@ -238,7 +238,7 @@ BluetoothA2dpManager::ResetAvrcp()
|
|||
mMediaNumber = 0;
|
||||
mTotalMediaCount = 0;
|
||||
mPosition = 0;
|
||||
mPlayStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
|
||||
mPlayStatus = ControlPlayStatus::PLAYSTATUS_STOPPED;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -395,7 +395,10 @@ public:
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, new AcceptResultHandler(GetIO()));
|
||||
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
|
||||
GetIO()->mConsumer->SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -476,6 +479,7 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
|
|||
bool aAuth,
|
||||
bool aEncrypt)
|
||||
: mObserver(aObserver)
|
||||
, mCurrentRes(nullptr)
|
||||
, mImpl(nullptr)
|
||||
, mAuth(aAuth)
|
||||
, mEncrypt(aEncrypt)
|
||||
|
@ -527,13 +531,15 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress, int aChannel)
|
|||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
// TODO: uuid as argument
|
||||
sBluetoothSocketInterface->Connect(
|
||||
aDeviceAddress,
|
||||
BluetoothSocketType::RFCOMM,
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ConnectSocketResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -576,12 +582,14 @@ BluetoothSocket::ListenSocket(int aChannel)
|
|||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Listen(
|
||||
BluetoothSocketType::RFCOMM,
|
||||
NS_LITERAL_STRING("OBEX Object Push"),
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ListenResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -590,10 +598,16 @@ void
|
|||
BluetoothSocket::CloseSocket()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
if (!mImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop any watching |SocketMessageWatcher|
|
||||
if (mCurrentRes) {
|
||||
sBluetoothSocketInterface->Close(mCurrentRes);
|
||||
}
|
||||
|
||||
// From this point on, we consider mImpl as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
|
@ -633,6 +647,8 @@ BluetoothSocket::OnConnectSuccess()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectSuccess(this);
|
||||
}
|
||||
|
||||
|
@ -641,6 +657,8 @@ BluetoothSocket::OnConnectError()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectError(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSocketObserver;
|
||||
class BluetoothSocketResultHandler;
|
||||
class DroidSocketImpl;
|
||||
|
||||
class BluetoothSocket : public mozilla::ipc::SocketConsumerBase
|
||||
|
@ -47,8 +48,14 @@ public:
|
|||
mDeviceAddress = aDeviceAddress;
|
||||
}
|
||||
|
||||
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
mCurrentRes = aRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketObserver* mObserver;
|
||||
BluetoothSocketResultHandler* mCurrentRes;
|
||||
DroidSocketImpl* mImpl;
|
||||
nsString mDeviceAddress;
|
||||
bool mAuth;
|
||||
|
|
|
@ -9,24 +9,25 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include "BluetoothHALHelpers.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
|
||||
int, int>
|
||||
int, int>
|
||||
BluetoothSocketHALIntResultRunnable;
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable3<BluetoothSocketResultHandler, void,
|
||||
int, const nsString, int,
|
||||
int, const nsAString_internal&, int>
|
||||
int, const nsString, int,
|
||||
int, const nsAString_internal&, int>
|
||||
BluetoothSocketHALIntStringIntResultRunnable;
|
||||
|
||||
typedef
|
||||
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
BluetoothStatus, BluetoothStatus>
|
||||
BluetoothSocketHALErrorRunnable;
|
||||
|
||||
static nsresult
|
||||
|
@ -78,11 +79,11 @@ DispatchBluetoothSocketHALResult(
|
|||
|
||||
void
|
||||
BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
|
||||
const nsAString& aServiceName,
|
||||
const uint8_t aServiceUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
const nsAString& aServiceName,
|
||||
const uint8_t aServiceUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
int fd;
|
||||
bt_status_t status;
|
||||
|
@ -109,6 +110,34 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
|
|||
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
|
||||
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
|
||||
|
||||
class SocketMessageWatcher;
|
||||
|
||||
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
|
||||
* being released by hash table's Remove() method.
|
||||
*/
|
||||
class SocketMessageWatcherWrapper
|
||||
{
|
||||
public:
|
||||
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
|
||||
: mSocketMessageWatcher(aSocketMessageWatcher)
|
||||
{
|
||||
MOZ_ASSERT(mSocketMessageWatcher);
|
||||
}
|
||||
|
||||
SocketMessageWatcher* GetSocketMessageWatcher()
|
||||
{
|
||||
return mSocketMessageWatcher;
|
||||
}
|
||||
|
||||
private:
|
||||
SocketMessageWatcher* mSocketMessageWatcher;
|
||||
};
|
||||
|
||||
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
|
||||
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
|
||||
SocketMessageWatcherWrapper>
|
||||
sWatcherHashtable;
|
||||
|
||||
/* |SocketMessageWatcher| receives Bluedroid's socket setup
|
||||
* messages on the I/O thread. You need to inherit from this
|
||||
* class to make use of it.
|
||||
|
@ -135,11 +164,14 @@ public:
|
|||
static const unsigned char OFF_CHANNEL2 = 12;
|
||||
static const unsigned char OFF_STATUS = 16;
|
||||
|
||||
SocketMessageWatcher(int aFd)
|
||||
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: mFd(aFd)
|
||||
, mClientFd(-1)
|
||||
, mLen(0)
|
||||
{ }
|
||||
, mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
virtual ~SocketMessageWatcher()
|
||||
{ }
|
||||
|
@ -164,7 +196,7 @@ public:
|
|||
}
|
||||
|
||||
if (IsComplete() || status != STATUS_SUCCESS) {
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
StopWatching();
|
||||
Proceed(status);
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +206,9 @@ public:
|
|||
|
||||
void Watch()
|
||||
{
|
||||
// add this watcher and its result handler to hash table
|
||||
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
|
||||
|
||||
MessageLoopForIO::current()->WatchFileDescriptor(
|
||||
mFd,
|
||||
true,
|
||||
|
@ -182,6 +217,14 @@ public:
|
|||
this);
|
||||
}
|
||||
|
||||
void StopWatching()
|
||||
{
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
|
||||
// remove this watcher and its result handler from hash table
|
||||
sWatcherHashtable.Remove(mRes);
|
||||
}
|
||||
|
||||
bool IsComplete() const
|
||||
{
|
||||
return mLen == (MSG1_SIZE + MSG2_SIZE);
|
||||
|
@ -224,6 +267,11 @@ public:
|
|||
return mClientFd;
|
||||
}
|
||||
|
||||
BluetoothSocketResultHandler* GetResultHandler() const
|
||||
{
|
||||
return mRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothStatus RecvMsg1()
|
||||
{
|
||||
|
@ -322,6 +370,7 @@ private:
|
|||
int mClientFd;
|
||||
unsigned char mLen;
|
||||
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
|
||||
|
@ -373,32 +422,27 @@ class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
|
|||
{
|
||||
public:
|
||||
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Connect,
|
||||
GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
|
||||
BluetoothSocketType aType,
|
||||
const uint8_t aUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
BluetoothSocketType aType,
|
||||
const uint8_t aUuid[16],
|
||||
int aChannel, bool aEncrypt,
|
||||
bool aAuth,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
int fd;
|
||||
bt_status_t status;
|
||||
|
@ -425,10 +469,10 @@ BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
|
|||
}
|
||||
}
|
||||
|
||||
/* Specializes SocketMessageWatcher for Accept operations by
|
||||
* reading the socket messages from Bluedroid and forwarding
|
||||
* the received client socket to the resource handler. The
|
||||
* first message is received immediately. When there's a new
|
||||
/* |AcceptWatcher| specializes SocketMessageWatcher for Accept
|
||||
* operations by reading the socket messages from Bluedroid and
|
||||
* forwarding the received client socket to the resource handler.
|
||||
* The first message is received immediately. When there's a new
|
||||
* connection, Bluedroid sends the 2nd message with the socket
|
||||
* info and socket file descriptor.
|
||||
*/
|
||||
|
@ -436,37 +480,69 @@ class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
|
|||
{
|
||||
public:
|
||||
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
{
|
||||
/* not supplying a result handler leaks received file descriptor */
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Accept,
|
||||
GetClientFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Accept(int aFd,
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
/* receive Bluedroid's socket-setup messages and client fd */
|
||||
Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
|
||||
* on the I/O task
|
||||
*/
|
||||
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
|
||||
{
|
||||
public:
|
||||
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
void Run() MOZ_OVERRIDE
|
||||
{
|
||||
// look up hash table for the watcher corresponding to |mRes|
|
||||
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// stop the watcher if it exists
|
||||
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
|
||||
watcher->StopWatching();
|
||||
watcher->Proceed(STATUS_DONE);
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketResultHandler* mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(aRes);
|
||||
|
||||
/* stop the watcher corresponding to |aRes| */
|
||||
Task* t = new DeleteSocketMessageWatcherTask(aRes);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
|
||||
const btsock_interface_t* aInterface)
|
||||
: mInterface(aInterface)
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
|
||||
|
||||
void Close(BluetoothSocketResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
|
||||
~BluetoothSocketHALInterface();
|
||||
|
|
|
@ -38,5 +38,7 @@
|
|||
|
||||
/* CHLD values */
|
||||
#define BTA_AG_CHLD_VAL "(0,1,2,3)"
|
||||
/* SDP AVRCP 1.5 feature */
|
||||
#define SDP_AVRCP_1_5 FALSE
|
||||
|
||||
#endif /* B2G_BDROID_BUILDCFG_H */
|
||||
|
|
|
@ -54,6 +54,8 @@ public:
|
|||
|
||||
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~BluetoothSocketInterface();
|
||||
};
|
||||
|
|
|
@ -182,7 +182,7 @@ MobileConnectionListener::Listen(bool aStart)
|
|||
NS_ENSURE_TRUE(service, false);
|
||||
|
||||
nsCOMPtr<nsIMobileConnection> connection;
|
||||
mcService->GetItemByServiceId(mClientId, getter_AddRefs(connection));
|
||||
service->GetItemByServiceId(mClientId, getter_AddRefs(connection));
|
||||
NS_ENSURE_TRUE(connection, false);
|
||||
|
||||
nsresult rv;
|
||||
|
|
|
@ -395,7 +395,10 @@ public:
|
|||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, new AcceptResultHandler(GetIO()));
|
||||
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
|
||||
GetIO()->mConsumer->SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Accept(mFd, res);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -476,6 +479,7 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
|
|||
bool aAuth,
|
||||
bool aEncrypt)
|
||||
: mObserver(aObserver)
|
||||
, mCurrentRes(nullptr)
|
||||
, mImpl(nullptr)
|
||||
, mAuth(aAuth)
|
||||
, mEncrypt(aEncrypt)
|
||||
|
@ -527,13 +531,15 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress, int aChannel)
|
|||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
// TODO: uuid as argument
|
||||
sBluetoothSocketInterface->Connect(
|
||||
aDeviceAddress,
|
||||
BluetoothSocketType::RFCOMM,
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ConnectSocketResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -576,12 +582,14 @@ BluetoothSocket::ListenSocket(int aChannel)
|
|||
|
||||
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
|
||||
|
||||
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
|
||||
SetCurrentResultHandler(res);
|
||||
|
||||
sBluetoothSocketInterface->Listen(
|
||||
BluetoothSocketType::RFCOMM,
|
||||
NS_LITERAL_STRING("OBEX Object Push"),
|
||||
UUID_OBEX_OBJECT_PUSH,
|
||||
aChannel, mEncrypt, mAuth,
|
||||
new ListenResultHandler(mImpl));
|
||||
aChannel, mEncrypt, mAuth, res);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -590,10 +598,16 @@ void
|
|||
BluetoothSocket::CloseSocket()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(sBluetoothSocketInterface);
|
||||
if (!mImpl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Stop any watching |SocketMessageWatcher|
|
||||
if (mCurrentRes) {
|
||||
sBluetoothSocketInterface->Close(mCurrentRes);
|
||||
}
|
||||
|
||||
// From this point on, we consider mImpl as being deleted.
|
||||
// We sever the relationship here so any future calls to listen or connect
|
||||
// will create a new implementation.
|
||||
|
@ -633,6 +647,8 @@ BluetoothSocket::OnConnectSuccess()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectSuccess(this);
|
||||
}
|
||||
|
||||
|
@ -641,6 +657,8 @@ BluetoothSocket::OnConnectError()
|
|||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mObserver);
|
||||
|
||||
SetCurrentResultHandler(nullptr);
|
||||
mObserver->OnSocketConnectError(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothSocketObserver;
|
||||
class BluetoothSocketResultHandler;
|
||||
class DroidSocketImpl;
|
||||
|
||||
class BluetoothSocket : public mozilla::ipc::SocketConsumerBase
|
||||
|
@ -47,8 +48,14 @@ public:
|
|||
mDeviceAddress = aDeviceAddress;
|
||||
}
|
||||
|
||||
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
mCurrentRes = aRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketObserver* mObserver;
|
||||
BluetoothSocketResultHandler* mCurrentRes;
|
||||
DroidSocketImpl* mImpl;
|
||||
nsString mDeviceAddress;
|
||||
bool mAuth;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include "BluetoothHALHelpers.h"
|
||||
#include "nsClassHashtable.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
@ -109,6 +110,34 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
|
|||
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
|
||||
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
|
||||
|
||||
class SocketMessageWatcher;
|
||||
|
||||
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
|
||||
* being released by hash table's Remove() method.
|
||||
*/
|
||||
class SocketMessageWatcherWrapper
|
||||
{
|
||||
public:
|
||||
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
|
||||
: mSocketMessageWatcher(aSocketMessageWatcher)
|
||||
{
|
||||
MOZ_ASSERT(mSocketMessageWatcher);
|
||||
}
|
||||
|
||||
SocketMessageWatcher* GetSocketMessageWatcher()
|
||||
{
|
||||
return mSocketMessageWatcher;
|
||||
}
|
||||
|
||||
private:
|
||||
SocketMessageWatcher* mSocketMessageWatcher;
|
||||
};
|
||||
|
||||
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
|
||||
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
|
||||
SocketMessageWatcherWrapper>
|
||||
sWatcherHashtable;
|
||||
|
||||
/* |SocketMessageWatcher| receives Bluedroid's socket setup
|
||||
* messages on the I/O thread. You need to inherit from this
|
||||
* class to make use of it.
|
||||
|
@ -135,11 +164,14 @@ public:
|
|||
static const unsigned char OFF_CHANNEL2 = 12;
|
||||
static const unsigned char OFF_STATUS = 16;
|
||||
|
||||
SocketMessageWatcher(int aFd)
|
||||
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: mFd(aFd)
|
||||
, mClientFd(-1)
|
||||
, mLen(0)
|
||||
{ }
|
||||
, mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
virtual ~SocketMessageWatcher()
|
||||
{ }
|
||||
|
@ -164,7 +196,7 @@ public:
|
|||
}
|
||||
|
||||
if (IsComplete() || status != STATUS_SUCCESS) {
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
StopWatching();
|
||||
Proceed(status);
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +206,9 @@ public:
|
|||
|
||||
void Watch()
|
||||
{
|
||||
// add this watcher and its result handler to hash table
|
||||
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
|
||||
|
||||
MessageLoopForIO::current()->WatchFileDescriptor(
|
||||
mFd,
|
||||
true,
|
||||
|
@ -182,6 +217,14 @@ public:
|
|||
this);
|
||||
}
|
||||
|
||||
void StopWatching()
|
||||
{
|
||||
mWatcher.StopWatchingFileDescriptor();
|
||||
|
||||
// remove this watcher and its result handler from hash table
|
||||
sWatcherHashtable.Remove(mRes);
|
||||
}
|
||||
|
||||
bool IsComplete() const
|
||||
{
|
||||
return mLen == (MSG1_SIZE + MSG2_SIZE);
|
||||
|
@ -224,6 +267,11 @@ public:
|
|||
return mClientFd;
|
||||
}
|
||||
|
||||
BluetoothSocketResultHandler* GetResultHandler() const
|
||||
{
|
||||
return mRes;
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothStatus RecvMsg1()
|
||||
{
|
||||
|
@ -322,6 +370,7 @@ private:
|
|||
int mClientFd;
|
||||
unsigned char mLen;
|
||||
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
|
||||
|
@ -373,23 +422,18 @@ class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
|
|||
{
|
||||
public:
|
||||
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Connect,
|
||||
GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -436,26 +480,18 @@ class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
|
|||
{
|
||||
public:
|
||||
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
|
||||
: SocketMessageWatcher(aFd)
|
||||
, mRes(aRes)
|
||||
{
|
||||
/* not supplying a result handler leaks received file descriptor */
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
: SocketMessageWatcher(aFd, aRes)
|
||||
{ }
|
||||
|
||||
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
|
||||
{
|
||||
if (mRes) {
|
||||
DispatchBluetoothSocketHALResult(
|
||||
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
|
||||
GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
}
|
||||
DispatchBluetoothSocketHALResult(
|
||||
GetResultHandler(), &BluetoothSocketResultHandler::Accept,
|
||||
GetClientFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
|
||||
|
||||
MessageLoopForIO::current()->PostTask(
|
||||
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<BluetoothSocketResultHandler> mRes;
|
||||
};
|
||||
|
||||
void
|
||||
|
@ -467,6 +503,46 @@ BluetoothSocketHALInterface::Accept(int aFd,
|
|||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
|
||||
* on the I/O task
|
||||
*/
|
||||
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
|
||||
{
|
||||
public:
|
||||
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
|
||||
: mRes(aRes)
|
||||
{
|
||||
MOZ_ASSERT(mRes);
|
||||
}
|
||||
|
||||
void Run() MOZ_OVERRIDE
|
||||
{
|
||||
// look up hash table for the watcher corresponding to |mRes|
|
||||
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// stop the watcher if it exists
|
||||
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
|
||||
watcher->StopWatching();
|
||||
watcher->Proceed(STATUS_DONE);
|
||||
}
|
||||
|
||||
private:
|
||||
BluetoothSocketResultHandler* mRes;
|
||||
};
|
||||
|
||||
void
|
||||
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
|
||||
{
|
||||
MOZ_ASSERT(aRes);
|
||||
|
||||
/* stop the watcher corresponding to |aRes| */
|
||||
Task* t = new DeleteSocketMessageWatcherTask(aRes);
|
||||
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
|
||||
}
|
||||
|
||||
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
|
||||
const btsock_interface_t* aInterface)
|
||||
: mInterface(aInterface)
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
|
||||
|
||||
void Close(BluetoothSocketResultHandler* aRes);
|
||||
|
||||
protected:
|
||||
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
|
||||
~BluetoothSocketHALInterface();
|
||||
|
|
|
@ -1431,7 +1431,7 @@ WebGLContext::PresentScreenBuffer()
|
|||
void
|
||||
WebGLContext::DummyFramebufferOperation(const char *info)
|
||||
{
|
||||
GLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
||||
FBStatus status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
|
||||
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
|
||||
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
|
||||
}
|
||||
|
|
|
@ -355,6 +355,10 @@ public:
|
|||
void FramebufferTexture2D(GLenum target, GLenum attachment,
|
||||
GLenum textarget, WebGLTexture *tobj,
|
||||
GLint level);
|
||||
|
||||
// Framebuffer validation
|
||||
bool ValidateFramebufferAttachment(GLenum attachment, const char* funcName);
|
||||
|
||||
void FrontFace(GLenum mode);
|
||||
void GenerateMipmap(GLenum target);
|
||||
already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,
|
||||
|
|
|
@ -64,7 +64,7 @@ WebGLContext::CurValidFBRectObject() const
|
|||
if (mBoundFramebuffer) {
|
||||
// We don't really need to ask the driver.
|
||||
// Use 'precheck' to just check that our internal state looks good.
|
||||
GLenum precheckStatus = mBoundFramebuffer->PrecheckFramebufferStatus();
|
||||
FBStatus precheckStatus = mBoundFramebuffer->PrecheckFramebufferStatus();
|
||||
if (precheckStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE)
|
||||
rect = &mBoundFramebuffer->RectangleObject();
|
||||
} else {
|
||||
|
@ -348,7 +348,7 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
|
|||
if (!mBoundFramebuffer)
|
||||
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
|
||||
|
||||
return mBoundFramebuffer->CheckFramebufferStatus();
|
||||
return mBoundFramebuffer->CheckFramebufferStatus().get();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -795,7 +795,16 @@ WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum r
|
|||
if (!mBoundFramebuffer)
|
||||
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
|
||||
|
||||
return mBoundFramebuffer->FramebufferRenderbuffer(target, attachment, rbtarget, wrb);
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return ErrorInvalidEnumInfo("framebufferRenderbuffer: target", target);
|
||||
|
||||
if (rbtarget != LOCAL_GL_RENDERBUFFER)
|
||||
return ErrorInvalidEnumInfo("framebufferRenderbuffer: renderbuffer target:", rbtarget);
|
||||
|
||||
if (!ValidateFramebufferAttachment(attachment, "framebufferRenderbuffer"))
|
||||
return;
|
||||
|
||||
return mBoundFramebuffer->FramebufferRenderbuffer(attachment, rbtarget, wrb);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -811,6 +820,9 @@ WebGLContext::FramebufferTexture2D(GLenum target,
|
|||
if (!mBoundFramebuffer)
|
||||
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
|
||||
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
|
||||
|
||||
if (textarget != LOCAL_GL_TEXTURE_2D &&
|
||||
(textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
|
||||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
|
||||
|
@ -818,7 +830,10 @@ WebGLContext::FramebufferTexture2D(GLenum target,
|
|||
return ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
|
||||
}
|
||||
|
||||
return mBoundFramebuffer->FramebufferTexture2D(target, attachment, TexImageTarget(textarget), tobj, level);
|
||||
if (!ValidateFramebufferAttachment(attachment, "framebufferTexture2D"))
|
||||
return;
|
||||
|
||||
return mBoundFramebuffer->FramebufferTexture2D(attachment, textarget, tobj, level);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1084,27 +1099,11 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
|||
return JS::NullValue();
|
||||
}
|
||||
|
||||
if (attachment != LOCAL_GL_DEPTH_ATTACHMENT &&
|
||||
attachment != LOCAL_GL_STENCIL_ATTACHMENT &&
|
||||
attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
|
||||
{
|
||||
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
|
||||
attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments))
|
||||
{
|
||||
ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment);
|
||||
return JS::NullValue();
|
||||
}
|
||||
if (!ValidateFramebufferAttachment(attachment, "getFramebufferAttachmentParameter"))
|
||||
return JS::NullValue();
|
||||
|
||||
mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
|
||||
{
|
||||
ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment);
|
||||
return JS::NullValue();
|
||||
}
|
||||
}
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
|
||||
mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
|
|
|
@ -520,6 +520,34 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the framebuffer attachment is valid. Attachment must
|
||||
* be one of depth/stencil/depth_stencil/color attachment.
|
||||
*/
|
||||
bool
|
||||
WebGLContext::ValidateFramebufferAttachment(GLenum attachment, const char* funcName)
|
||||
{
|
||||
if (attachment == LOCAL_GL_DEPTH_ATTACHMENT ||
|
||||
attachment == LOCAL_GL_STENCIL_ATTACHMENT ||
|
||||
attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
GLenum colorAttachCount = 1;
|
||||
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
|
||||
colorAttachCount = mGLMaxColorAttachments;
|
||||
|
||||
if (attachment >= LOCAL_GL_COLOR_ATTACHMENT0 &&
|
||||
attachment < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + colorAttachCount))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.", funcName, attachment);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if format is a valid texture image format for source,
|
||||
* taking into account enabled WebGL extensions.
|
||||
|
|
|
@ -24,7 +24,7 @@ WebGLFramebuffer::WrapObject(JSContext* cx)
|
|||
}
|
||||
|
||||
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
|
||||
: WebGLBindableName<GLenum>()
|
||||
: WebGLBindableName<FBTarget>()
|
||||
, WebGLContextBoundObject(context)
|
||||
, mStatus(0)
|
||||
, mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
|
||||
|
@ -40,7 +40,7 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
|
|||
mColorAttachments[0].mAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
}
|
||||
|
||||
WebGLFramebuffer::Attachment::Attachment(GLenum aAttachmentPoint)
|
||||
WebGLFramebuffer::Attachment::Attachment(FBAttachment aAttachmentPoint)
|
||||
: mAttachmentPoint(aAttachmentPoint)
|
||||
, mTexImageTarget(LOCAL_GL_NONE)
|
||||
, mNeedsFinalize(false)
|
||||
|
@ -341,8 +341,8 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
|||
}
|
||||
|
||||
if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
|
||||
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 +
|
||||
WebGLContext::kMaxColorAttachments))
|
||||
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
|
||||
WebGLContext::kMaxColorAttachments))
|
||||
{
|
||||
return IsValidFBOTextureColorFormat(webGLFormat);
|
||||
}
|
||||
|
@ -363,8 +363,8 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
|||
return IsValidFBORenderbufferDepthStencilFormat(internalFormat);
|
||||
|
||||
if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
|
||||
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 +
|
||||
WebGLContext::kMaxColorAttachments))
|
||||
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
|
||||
WebGLContext::kMaxColorAttachments))
|
||||
{
|
||||
return IsValidFBORenderbufferColorFormat(internalFormat);
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ WebGLFramebuffer::Attachment::IsComplete() const
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmentLoc) const
|
||||
WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, FBAttachment attachmentLoc) const
|
||||
{
|
||||
if (!mNeedsFinalize)
|
||||
return;
|
||||
|
@ -391,7 +391,7 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmen
|
|||
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
|
||||
LOCAL_GL_RENDERBUFFER, 0);
|
||||
} else {
|
||||
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
|
||||
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
|
||||
LOCAL_GL_RENDERBUFFER, 0);
|
||||
}
|
||||
|
||||
|
@ -412,7 +412,7 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmen
|
|||
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
|
||||
imageTarget, glName, mipLevel);
|
||||
} else {
|
||||
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
|
||||
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
|
||||
imageTarget, glName, mipLevel);
|
||||
}
|
||||
return;
|
||||
|
@ -464,9 +464,8 @@ WebGLFramebuffer::DetachAllAttachments()
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum rbtarget,
|
||||
WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachment,
|
||||
RBTarget rbtarget,
|
||||
WebGLRenderbuffer* wrb)
|
||||
{
|
||||
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
|
||||
|
@ -474,12 +473,6 @@ WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
|
|||
if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer", wrb))
|
||||
return;
|
||||
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: target", target);
|
||||
|
||||
if (rbtarget != LOCAL_GL_RENDERBUFFER)
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: renderbuffer target:", rbtarget);
|
||||
|
||||
/* Get the requested attachment. If result is NULL, attachment is
|
||||
* invalid and an error is generated.
|
||||
*
|
||||
|
@ -509,8 +502,7 @@ WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::FramebufferTexture2D(GLenum target,
|
||||
GLenum attachment,
|
||||
WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachment,
|
||||
TexImageTarget texImageTarget,
|
||||
WebGLTexture* wtex,
|
||||
GLint level)
|
||||
|
@ -520,9 +512,6 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
|
|||
if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture", wtex))
|
||||
return;
|
||||
|
||||
if (target != LOCAL_GL_FRAMEBUFFER)
|
||||
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
|
||||
|
||||
if (wtex) {
|
||||
bool isTexture2D = wtex->Target() == LOCAL_GL_TEXTURE_2D;
|
||||
bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D;
|
||||
|
@ -563,7 +552,7 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
|
|||
}
|
||||
|
||||
WebGLFramebuffer::Attachment*
|
||||
WebGLFramebuffer::GetAttachmentOrNull(GLenum attachment)
|
||||
WebGLFramebuffer::GetAttachmentOrNull(FBAttachment attachment)
|
||||
{
|
||||
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
return &mDepthStencilAttachment;
|
||||
|
@ -574,17 +563,17 @@ WebGLFramebuffer::GetAttachmentOrNull(GLenum attachment)
|
|||
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
|
||||
return &mStencilAttachment;
|
||||
|
||||
if (!CheckColorAttachmentNumber(attachment, "getAttachmentOrNull"))
|
||||
if (!mContext->ValidateFramebufferAttachment(attachment.get(), "getAttachmentOrNull"))
|
||||
return nullptr;
|
||||
|
||||
size_t colorAttachmentId = attachment - LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
size_t colorAttachmentId = attachment.get() - LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
EnsureColorAttachments(colorAttachmentId);
|
||||
|
||||
return &mColorAttachments[colorAttachmentId];
|
||||
}
|
||||
|
||||
const WebGLFramebuffer::Attachment&
|
||||
WebGLFramebuffer::GetAttachment(GLenum attachment) const
|
||||
WebGLFramebuffer::GetAttachment(FBAttachment attachment) const
|
||||
{
|
||||
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
return mDepthStencilAttachment;
|
||||
|
@ -593,12 +582,12 @@ WebGLFramebuffer::GetAttachment(GLenum attachment) const
|
|||
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
|
||||
return mStencilAttachment;
|
||||
|
||||
if (!CheckColorAttachmentNumber(attachment, "getAttachment")) {
|
||||
if (!mContext->ValidateFramebufferAttachment(attachment.get(), "getAttachment")) {
|
||||
MOZ_ASSERT(false);
|
||||
return mColorAttachments[0];
|
||||
}
|
||||
|
||||
size_t colorAttachmentId = attachment - LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
size_t colorAttachmentId = attachment.get() - LOCAL_GL_COLOR_ATTACHMENT0;
|
||||
if (colorAttachmentId >= mColorAttachments.Length()) {
|
||||
MOZ_ASSERT(false);
|
||||
return mColorAttachments[0];
|
||||
|
@ -613,17 +602,17 @@ WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
|
|||
size_t count = mColorAttachments.Length();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (mColorAttachments[i].Texture() == tex) {
|
||||
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
FramebufferTexture2D(LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
// a texture might be attached more that once while editing the framebuffer
|
||||
}
|
||||
}
|
||||
|
||||
if (mDepthAttachment.Texture() == tex)
|
||||
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
FramebufferTexture2D(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
if (mStencilAttachment.Texture() == tex)
|
||||
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
FramebufferTexture2D(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
if (mDepthStencilAttachment.Texture() == tex)
|
||||
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
FramebufferTexture2D(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -632,17 +621,17 @@ WebGLFramebuffer::DetachRenderbuffer(const WebGLRenderbuffer* rb)
|
|||
size_t count = mColorAttachments.Length();
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
if (mColorAttachments[i].Renderbuffer() == rb) {
|
||||
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
FramebufferRenderbuffer(LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
// a renderbuffer might be attached more that once while editing the framebuffer
|
||||
}
|
||||
}
|
||||
|
||||
if (mDepthAttachment.Renderbuffer() == rb)
|
||||
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
FramebufferRenderbuffer(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
if (mStencilAttachment.Renderbuffer() == rb)
|
||||
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
FramebufferRenderbuffer(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
if (mDepthStencilAttachment.Renderbuffer() == rb)
|
||||
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
FramebufferRenderbuffer(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -757,7 +746,7 @@ WebGLFramebuffer::RectangleObject() const
|
|||
return GetAnyRectObject();
|
||||
}
|
||||
|
||||
GLenum
|
||||
FBStatus
|
||||
WebGLFramebuffer::PrecheckFramebufferStatus() const
|
||||
{
|
||||
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
|
||||
|
@ -777,13 +766,13 @@ WebGLFramebuffer::PrecheckFramebufferStatus() const
|
|||
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
GLenum
|
||||
FBStatus
|
||||
WebGLFramebuffer::CheckFramebufferStatus() const
|
||||
{
|
||||
if (mStatus != 0)
|
||||
return mStatus;
|
||||
|
||||
mStatus = PrecheckFramebufferStatus();
|
||||
mStatus = PrecheckFramebufferStatus().get();
|
||||
if (mStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE)
|
||||
return mStatus;
|
||||
|
||||
|
@ -897,33 +886,6 @@ WebGLFramebuffer::CheckAndInitializeAttachments()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool WebGLFramebuffer::CheckColorAttachmentNumber(GLenum attachment, const char* functionName) const
|
||||
{
|
||||
const char* const errorFormating = "%s: attachment: invalid enum value 0x%x";
|
||||
|
||||
if (mContext->IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
|
||||
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
|
||||
attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments))
|
||||
{
|
||||
mContext->ErrorInvalidEnum(errorFormating, functionName, attachment);
|
||||
return false;
|
||||
}
|
||||
} else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0) {
|
||||
if (attachment > LOCAL_GL_COLOR_ATTACHMENT0 &&
|
||||
attachment <= LOCAL_GL_COLOR_ATTACHMENT15)
|
||||
{
|
||||
mContext->ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x. "
|
||||
"Try the WEBGL_draw_buffers extension if supported.", functionName, attachment);
|
||||
return false;
|
||||
} else {
|
||||
mContext->ErrorInvalidEnum(errorFormating, functionName, attachment);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebGLFramebuffer::EnsureColorAttachments(size_t colorAttachmentId)
|
||||
{
|
||||
MOZ_ASSERT(colorAttachmentId < WebGLContext::kMaxColorAttachments);
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace gl {
|
|||
|
||||
class WebGLFramebuffer MOZ_FINAL
|
||||
: public nsWrapperCache
|
||||
, public WebGLBindableName<GLenum>
|
||||
, public WebGLBindableName<FBTarget>
|
||||
, public WebGLRefCountedObject<WebGLFramebuffer>
|
||||
, public LinkedListElement<WebGLFramebuffer>
|
||||
, public WebGLContextBoundObject
|
||||
|
@ -41,12 +41,12 @@ public:
|
|||
// deleting a texture or renderbuffer immediately detaches it
|
||||
WebGLRefPtr<WebGLTexture> mTexturePtr;
|
||||
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
|
||||
GLenum mAttachmentPoint;
|
||||
FBAttachment mAttachmentPoint;
|
||||
TexImageTarget mTexImageTarget;
|
||||
GLint mTexImageLevel;
|
||||
mutable bool mNeedsFinalize;
|
||||
|
||||
explicit Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
|
||||
explicit Attachment(FBAttachment aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
|
||||
~Attachment();
|
||||
|
||||
bool IsDefined() const;
|
||||
|
@ -88,18 +88,16 @@ public:
|
|||
bool HasImage() const;
|
||||
bool IsComplete() const;
|
||||
|
||||
void FinalizeAttachment(gl::GLContext* gl, GLenum attachmentLoc) const;
|
||||
void FinalizeAttachment(gl::GLContext* gl, FBAttachment attachmentLoc) const;
|
||||
};
|
||||
|
||||
void Delete();
|
||||
|
||||
void FramebufferRenderbuffer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum rbtarget,
|
||||
void FramebufferRenderbuffer(FBAttachment attachment,
|
||||
RBTarget rbtarget,
|
||||
WebGLRenderbuffer* wrb);
|
||||
|
||||
void FramebufferTexture2D(GLenum target,
|
||||
GLenum attachment,
|
||||
void FramebufferTexture2D(FBAttachment attachment,
|
||||
TexImageTarget texImageTarget,
|
||||
WebGLTexture* wtex,
|
||||
GLint level);
|
||||
|
@ -108,14 +106,14 @@ private:
|
|||
void DetachAttachment(WebGLFramebuffer::Attachment& attachment);
|
||||
void DetachAllAttachments();
|
||||
const WebGLRectangleObject& GetAnyRectObject() const;
|
||||
Attachment* GetAttachmentOrNull(GLenum attachment);
|
||||
Attachment* GetAttachmentOrNull(FBAttachment attachment);
|
||||
|
||||
public:
|
||||
bool HasDefinedAttachments() const;
|
||||
bool HasIncompleteAttachments() const;
|
||||
bool AllImageRectsMatch() const;
|
||||
GLenum PrecheckFramebufferStatus() const;
|
||||
GLenum CheckFramebufferStatus() const;
|
||||
FBStatus PrecheckFramebufferStatus() const;
|
||||
FBStatus CheckFramebufferStatus() const;
|
||||
GLenum GetFormatForAttachment(const WebGLFramebuffer::Attachment& attachment) const;
|
||||
|
||||
bool HasDepthStencilConflict() const {
|
||||
|
@ -143,7 +141,7 @@ public:
|
|||
return mDepthStencilAttachment;
|
||||
}
|
||||
|
||||
const Attachment& GetAttachment(GLenum attachment) const;
|
||||
const Attachment& GetAttachment(FBAttachment attachment) const;
|
||||
|
||||
void DetachTexture(const WebGLTexture* tex);
|
||||
|
||||
|
@ -167,11 +165,10 @@ public:
|
|||
|
||||
bool CheckAndInitializeAttachments();
|
||||
|
||||
bool CheckColorAttachmentNumber(GLenum attachment, const char* functionName) const;
|
||||
bool CheckColorAttachmentNumber(FBAttachment attachment, const char* functionName) const;
|
||||
|
||||
void EnsureColorAttachments(size_t colorAttachmentId);
|
||||
|
||||
Attachment* AttachmentFor(GLenum attachment);
|
||||
void NotifyAttachableChanged() const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
using namespace mozilla;
|
||||
|
||||
void
|
||||
WebGLFramebufferAttachable::AttachTo(WebGLFramebuffer* fb, GLenum attachment)
|
||||
WebGLFramebufferAttachable::AttachTo(WebGLFramebuffer* fb, FBAttachment attachment)
|
||||
{
|
||||
MOZ_ASSERT(fb);
|
||||
if (!fb)
|
||||
|
@ -25,7 +25,7 @@ WebGLFramebufferAttachable::AttachTo(WebGLFramebuffer* fb, GLenum attachment)
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebufferAttachable::DetachFrom(WebGLFramebuffer* fb, GLenum attachment)
|
||||
WebGLFramebufferAttachable::DetachFrom(WebGLFramebuffer* fb, FBAttachment attachment)
|
||||
{
|
||||
MOZ_ASSERT(fb);
|
||||
if (!fb)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "nsTArray.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -17,13 +18,13 @@ class WebGLFramebufferAttachable
|
|||
{
|
||||
struct AttachmentPoint
|
||||
{
|
||||
AttachmentPoint(const WebGLFramebuffer* fb, GLenum attachment)
|
||||
AttachmentPoint(const WebGLFramebuffer* fb, FBAttachment attachment)
|
||||
: mFB(fb)
|
||||
, mAttachment(attachment)
|
||||
{}
|
||||
|
||||
WeakPtr<const WebGLFramebuffer> mFB;
|
||||
GLenum mAttachment;
|
||||
FBAttachment mAttachment;
|
||||
|
||||
bool operator==(const AttachmentPoint& o) const {
|
||||
return mFB == o.mFB && mAttachment == o.mAttachment;
|
||||
|
@ -35,8 +36,8 @@ class WebGLFramebufferAttachable
|
|||
public:
|
||||
|
||||
// Track FBO/Attachment combinations
|
||||
void AttachTo(WebGLFramebuffer* fb, GLenum attachment);
|
||||
void DetachFrom(WebGLFramebuffer* fb, GLenum attachment);
|
||||
void AttachTo(WebGLFramebuffer* fb, FBAttachment attachment);
|
||||
void DetachFrom(WebGLFramebuffer* fb, FBAttachment attachment);
|
||||
void NotifyFBsStatusChanged();
|
||||
};
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ WebGLRenderbuffer::WrapObject(JSContext *cx) {
|
|||
}
|
||||
|
||||
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext *context)
|
||||
: WebGLBindableName<GLenum>()
|
||||
: WebGLBindableName<RBTarget>()
|
||||
, WebGLContextBoundObject(context)
|
||||
, mPrimaryRB(0)
|
||||
, mSecondaryRB(0)
|
||||
|
@ -182,10 +182,10 @@ WebGLRenderbuffer::RenderbufferStorage(GLenum internalFormat, GLsizei width, GLs
|
|||
}
|
||||
|
||||
void
|
||||
WebGLRenderbuffer::FramebufferRenderbuffer(GLenum attachment) const {
|
||||
WebGLRenderbuffer::FramebufferRenderbuffer(FBAttachment attachment) const {
|
||||
GLContext* gl = mContext->gl;
|
||||
if (attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
|
||||
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment, LOCAL_GL_RENDERBUFFER, mPrimaryRB);
|
||||
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment.get(), LOCAL_GL_RENDERBUFFER, mPrimaryRB);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -200,10 +200,10 @@ WebGLRenderbuffer::FramebufferRenderbuffer(GLenum attachment) const {
|
|||
}
|
||||
|
||||
GLint
|
||||
WebGLRenderbuffer::GetRenderbufferParameter(GLenum target, GLenum pname) const {
|
||||
WebGLRenderbuffer::GetRenderbufferParameter(RBTarget target, RBParam pname) const {
|
||||
GLContext* gl = mContext->gl;
|
||||
|
||||
switch (pname) {
|
||||
switch (pname.get()) {
|
||||
case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE: {
|
||||
if (NeedsDepthStencilEmu(mContext->gl, InternalFormatForGL())) {
|
||||
if (gl->WorkAroundDriverBugs() &&
|
||||
|
@ -215,7 +215,7 @@ WebGLRenderbuffer::GetRenderbufferParameter(GLenum target, GLenum pname) const {
|
|||
ScopedBindRenderbuffer autoRB(gl, mSecondaryRB);
|
||||
|
||||
GLint i = 0;
|
||||
gl->fGetRenderbufferParameteriv(target, pname, &i);
|
||||
gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
|
||||
return i;
|
||||
}
|
||||
// Fall through otherwise.
|
||||
|
@ -228,7 +228,7 @@ WebGLRenderbuffer::GetRenderbufferParameter(GLenum target, GLenum pname) const {
|
|||
case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
|
||||
case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE: {
|
||||
GLint i = 0;
|
||||
gl->fGetRenderbufferParameteriv(target, pname, &i);
|
||||
gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace mozilla {
|
|||
|
||||
class WebGLRenderbuffer MOZ_FINAL
|
||||
: public nsWrapperCache
|
||||
, public WebGLBindableName<GLenum>
|
||||
, public WebGLBindableName<RBTarget>
|
||||
, public WebGLRefCountedObject<WebGLRenderbuffer>
|
||||
, public LinkedListElement<WebGLRenderbuffer>
|
||||
, public WebGLRectangleObject
|
||||
|
@ -52,9 +52,9 @@ public:
|
|||
|
||||
void BindRenderbuffer() const;
|
||||
void RenderbufferStorage(GLenum internalFormat, GLsizei width, GLsizei height) const;
|
||||
void FramebufferRenderbuffer(GLenum attachment) const;
|
||||
void FramebufferRenderbuffer(FBAttachment attachment) const;
|
||||
// Only handles a subset of `pname`s.
|
||||
GLint GetRenderbufferParameter(GLenum target, GLenum pname) const;
|
||||
GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;
|
||||
|
||||
|
|
|
@ -153,6 +153,14 @@ public:
|
|||
return get() != other.get();
|
||||
}
|
||||
|
||||
bool operator<=(const StrongGLenum& other) const {
|
||||
return get() <= other.get();
|
||||
}
|
||||
|
||||
bool operator>=(const StrongGLenum& other) const {
|
||||
return get() >= other.get();
|
||||
}
|
||||
|
||||
static bool IsValueLegal(GLenum value) {
|
||||
if (value > UINT16_MAX) {
|
||||
return false;
|
||||
|
@ -342,4 +350,59 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
|
|||
STRONG_GLENUM_VALUE(RGB10_A2UI),
|
||||
STRONG_GLENUM_END(TexInternalFormat)
|
||||
|
||||
STRONG_GLENUM_BEGIN(FBTarget)
|
||||
STRONG_GLENUM_VALUE(NONE),
|
||||
STRONG_GLENUM_VALUE(READ_FRAMEBUFFER),
|
||||
STRONG_GLENUM_VALUE(DRAW_FRAMEBUFFER),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER),
|
||||
STRONG_GLENUM_END(FBTarget)
|
||||
|
||||
STRONG_GLENUM_BEGIN(RBTarget)
|
||||
STRONG_GLENUM_VALUE(NONE),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER),
|
||||
STRONG_GLENUM_END(RBTarget)
|
||||
|
||||
STRONG_GLENUM_BEGIN(FBAttachment)
|
||||
STRONG_GLENUM_VALUE(DEPTH_STENCIL_ATTACHMENT),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT0),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT1),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT2),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT3),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT4),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT5),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT6),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT7),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT8),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT9),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT10),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT11),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT12),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT13),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT14),
|
||||
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT15),
|
||||
STRONG_GLENUM_VALUE(DEPTH_ATTACHMENT),
|
||||
STRONG_GLENUM_VALUE(STENCIL_ATTACHMENT),
|
||||
STRONG_GLENUM_END(FBAttachment)
|
||||
|
||||
STRONG_GLENUM_BEGIN(FBStatus)
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_COMPLETE),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_DIMENSIONS),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_READ_BUFFER),
|
||||
STRONG_GLENUM_VALUE(FRAMEBUFFER_UNSUPPORTED),
|
||||
STRONG_GLENUM_END(FBStatus)
|
||||
|
||||
STRONG_GLENUM_BEGIN(RBParam)
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_WIDTH),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_HEIGHT),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_RED_SIZE),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_GREEN_SIZE),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_BLUE_SIZE),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_ALPHA_SIZE),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_DEPTH_SIZE),
|
||||
STRONG_GLENUM_VALUE(RENDERBUFFER_STENCIL_SIZE),
|
||||
STRONG_GLENUM_END(RBParam)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,7 @@ EXPORTS.mozilla.dom += [
|
|||
'DataStoreService.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'DataStore.cpp',
|
||||
'DataStoreCursor.cpp',
|
||||
'DataStoreDB.cpp',
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
component {27e55b94-fc43-42b3-b0f0-28bebdd804f1} EngineeringModeAPI.js
|
||||
contract @mozilla.org/dom/engineering-mode-api;1 {27e55b94-fc43-42b3-b0f0-28bebdd804f1}
|
||||
|
||||
component {1345a96a-7b8d-4017-a776-07d918f14d84} EngineeringModeService.js
|
||||
contract @mozilla.org/engineering-mode-service;1 {1345a96a-7b8d-4017-a776-07d918f14d84}
|
||||
category profile-after-change EngineeringModeService @mozilla.org/engineering-mode-service;1
|
|
@ -0,0 +1,135 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = false;
|
||||
function debug(s) {
|
||||
if (DEBUG) dump("-*- EngineeringModeAPI: " + s + "\n");
|
||||
}
|
||||
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
function EngineeringModeAPI() {
|
||||
}
|
||||
|
||||
EngineeringModeAPI.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
classDescription: "Engineering Mode API",
|
||||
classID: Components.ID("{27e55b94-fc43-42b3-b0f0-28bebdd804f1}"),
|
||||
contractID: "@mozilla.org/dom/engineering-mode-api;1",
|
||||
|
||||
// For DOMRequestHelper: must have nsISupportsWeakReference and nsIObserver.
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsIObserver]),
|
||||
|
||||
init: function(aWindow) {
|
||||
this.initDOMRequestHelper(aWindow, ["EngineeringMode:OnMessage",
|
||||
"EngineeringMode:SetValue:Result:OK",
|
||||
"EngineeringMode:SetValue:Result:KO",
|
||||
"EngineeringMode:GetValue:Result:OK",
|
||||
"EngineeringMode:GetValue:Result:KO"]);
|
||||
cpmm.sendAsyncMessage("EngineeringMode:Register", null);
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
cpmm.sendAsyncMessage("EngineeringMode:Unregister", null);
|
||||
},
|
||||
|
||||
// This returns a Promise<DOMString>
|
||||
getValue: function getValue(aName) {
|
||||
debug("getValue " + aName);
|
||||
let promiseInit = function(resolve, reject) {
|
||||
debug("promise init called for getValue " + aName);
|
||||
let resolverId = this.getPromiseResolverId({resolve: resolve,
|
||||
reject: reject });
|
||||
debug("promise init " + resolverId);
|
||||
cpmm.sendAsyncMessage("EngineeringMode:GetValue", {
|
||||
requestId: resolverId,
|
||||
name: aName
|
||||
});
|
||||
}.bind(this);
|
||||
|
||||
return this.createPromise(promiseInit);
|
||||
},
|
||||
|
||||
// This returns a Promise<void>
|
||||
setValue: function setValue(aName, aValue) {
|
||||
debug("setValue " + aName + ' as ' + aValue );
|
||||
let promiseInit = function(resolve, reject) {
|
||||
debug("promise init called for setValue " + aName);
|
||||
let resolverId = this.getPromiseResolverId({resolve: resolve,
|
||||
reject: reject });
|
||||
debug("promise init " + resolverId);
|
||||
cpmm.sendAsyncMessage("EngineeringMode:SetValue", {
|
||||
requestId: resolverId,
|
||||
name: aName,
|
||||
value: aValue
|
||||
});
|
||||
}.bind(this);
|
||||
|
||||
return this.createPromise(promiseInit);
|
||||
},
|
||||
|
||||
set onmessage(aHandler) {
|
||||
this.__DOM_IMPL__.setEventHandler("onmessage", aHandler);
|
||||
},
|
||||
|
||||
get onmessage() {
|
||||
return this.__DOM_IMPL__.getEventHandler("onmessage");
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
debug("receiveMessage: name: " + aMessage.name);
|
||||
let resolver = null;
|
||||
let data = aMessage.data;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "EngineeringMode:OnMessage":
|
||||
let detail = Cu.cloneInto(data, this._window);
|
||||
let event = new this._window.CustomEvent("message", {"detail": detail});
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
break;
|
||||
case "EngineeringMode:GetValue:Result:OK":
|
||||
case "EngineeringMode:GetValue:Result:KO":
|
||||
resolver = this.takePromiseResolver(data.requestId);
|
||||
if (!resolver) {
|
||||
return;
|
||||
}
|
||||
if (aMessage.name === "EngineeringMode:GetValue:Result:OK") {
|
||||
resolver.resolve(data.value);
|
||||
} else {
|
||||
resolver.reject(data.reason);
|
||||
}
|
||||
break;
|
||||
case "EngineeringMode:SetValue:Result:OK":
|
||||
case "EngineeringMode:SetValue:Result:KO":
|
||||
resolver = this.takePromiseResolver(data.requestId);
|
||||
if (!resolver) {
|
||||
return;
|
||||
}
|
||||
if (aMessage.name === "EngineeringMode:SetValue:Result:OK") {
|
||||
resolver.resolve();
|
||||
} else {
|
||||
resolver.reject(data.reason);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EngineeringModeAPI]);
|
|
@ -0,0 +1,163 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const DEBUG = false;
|
||||
function debug(s) {
|
||||
if (DEBUG) dump("-*- EngineeringModeService: " + s + "\n");
|
||||
}
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
|
||||
"@mozilla.org/parentprocessmessagemanager;1",
|
||||
"nsIMessageBroadcaster");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "EngineeringMode",
|
||||
"@mozilla.org/b2g/engineering-mode-impl;1",
|
||||
"nsIEngineeringMode");
|
||||
|
||||
function EngineeringModeService() {
|
||||
}
|
||||
|
||||
EngineeringModeService.prototype = {
|
||||
classID: Components.ID("{1345a96a-7b8d-4017-a776-07d918f14d84}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsIEngineeringModeMessageHandler]),
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
debug("-- init");
|
||||
|
||||
switch(aTopic) {
|
||||
case "profile-after-change":
|
||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||
ppmm.addMessageListener("EngineeringMode:Register", this);
|
||||
ppmm.addMessageListener("EngineeringMode:Unregister", this);
|
||||
ppmm.addMessageListener("EngineeringMode:SetValue", this);
|
||||
ppmm.addMessageListener("EngineeringMode:GetValue", this);
|
||||
this._clients = [];
|
||||
break;
|
||||
case "xpcom-shutdown":
|
||||
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||
ppmm.removeMessageListener("EngineeringMode:Register", this);
|
||||
ppmm.removeMessageListener("EngineeringMode:Unregister", this);
|
||||
ppmm.removeMessageListener("EngineeringMode:SetValue", this);
|
||||
ppmm.removeMessageListener("EngineeringMode:GetValue", this);
|
||||
if (this._hasEngineeringModeImpl()) {
|
||||
EngineeringMode.setMessageHandler(function(){});
|
||||
}
|
||||
this._clients = null;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
debug("receiveMessage: name: " + aMessage.name);
|
||||
|
||||
if (!aMessage.target.assertPermission("engineering-mode")) {
|
||||
debug(aMessage.name + " from a content process with no 'engineering-mode' privileges.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "EngineeringMode:Register":
|
||||
// Lazy bind message handler until we have first client.
|
||||
if (this._hasEngineeringModeImpl() && this._clients.length === 0) {
|
||||
EngineeringMode.setMessageHandler(this.onMessage.bind(this));
|
||||
}
|
||||
|
||||
this._clients.push(aMessage.target);
|
||||
break;
|
||||
|
||||
case "EngineeringMode:Unregister":
|
||||
let index = this._clients.indexOf(aMessage.target);
|
||||
if (index > -1) {
|
||||
this._clients.splice(index, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case "EngineeringMode:SetValue":
|
||||
this.setValue(aMessage.target, aMessage.data);
|
||||
break;
|
||||
|
||||
case "EngineeringMode:GetValue":
|
||||
this.getValue(aMessage.target, aMessage.data);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
setValue: function(aTarget, aData) {
|
||||
if (!this._hasEngineeringModeImpl()) {
|
||||
aTarget.sendAsyncMessage("EngineeringMode:SetValue:Result:KO", {
|
||||
requestId: aData.requestId,
|
||||
reason: "No engineering mode implementation"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
EngineeringMode.setValue(aData.name, aData.value, {
|
||||
onsuccess: function() {
|
||||
aTarget.sendAsyncMessage("EngineeringMode:SetValue:Result:OK", {
|
||||
requestId: aData.requestId
|
||||
});
|
||||
},
|
||||
onerror: function(aError) {
|
||||
aTarget.sendAsyncMessage("EngineeringMode:SetValue:Result:KO", {
|
||||
requestId: aData.requestId,
|
||||
reason: "Error: code " + aError
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getValue: function(aTarget, aData) {
|
||||
if (!this._hasEngineeringModeImpl()) {
|
||||
aTarget.sendAsyncMessage("EngineeringMode:GetValue:Result:KO", {
|
||||
requestId: aData.requestId,
|
||||
reason: "No engineering mode implementation"
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
EngineeringMode.getValue(aData.name, {
|
||||
onsuccess: function(aValue) {
|
||||
aTarget.sendAsyncMessage("EngineeringMode:GetValue:Result:OK", {
|
||||
requestId: aData.requestId,
|
||||
value: aValue
|
||||
});
|
||||
},
|
||||
onerror: function(aError) {
|
||||
aTarget.sendAsyncMessage("EngineeringMode:GetValue:Result:KO", {
|
||||
requestId: aData.requestId,
|
||||
reason: "Error: code " + aError
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onMessage: function(aMessage) {
|
||||
this._clients.forEach(function(aClient) {
|
||||
aClient.sendAsyncMessage("EngineeringMode:OnMessage", {
|
||||
data: aMessage
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
_hasEngineeringModeImpl: function() {
|
||||
if (typeof Cc["@mozilla.org/b2g/engineering-mode-impl;1"] === "undefined") {
|
||||
debug("Can not get engineering mode implementation.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EngineeringModeService]);
|
|
@ -0,0 +1,19 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['MOZ_B2G']:
|
||||
EXTRA_COMPONENTS += [
|
||||
'EngineeringMode.manifest',
|
||||
'EngineeringModeAPI.js',
|
||||
'EngineeringModeService.js',
|
||||
]
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIEngineeringMode.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_engineeringmode'
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/* 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 "nsISupports.idl"
|
||||
|
||||
[scriptable, function, uuid(82e7c515-d174-4e84-9091-e7e89617a6d9)]
|
||||
interface nsIEngineeringModeMessageHandler : nsISupports
|
||||
{
|
||||
void handleMessage(in DOMString message);
|
||||
};
|
||||
|
||||
[scriptable, uuid(fdae21b9-bd8c-4d01-bc6a-6c3a7b5efb27)]
|
||||
interface nsIEngineeringModeCallback : nsISupports
|
||||
{
|
||||
void onsuccess([optional] in DOMString value);
|
||||
void onerror(in int32_t error);
|
||||
};
|
||||
|
||||
// Implemented by contract id @mozilla.org/b2g/engineering-mode-impl;1
|
||||
[scriptable, uuid(7251c99b-225f-4e39-8336-a7e2a087aa21)]
|
||||
interface nsIEngineeringMode : nsISupports
|
||||
{
|
||||
void getValue(in DOMString name, in nsIEngineeringModeCallback callback);
|
||||
void setValue(in DOMString name, in DOMString value,
|
||||
in nsIEngineeringModeCallback callback);
|
||||
void setMessageHandler(in nsIEngineeringModeMessageHandler handler);
|
||||
};
|
||||
|
|
@ -278,8 +278,7 @@ DOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
|
|||
{
|
||||
nsRefPtr<EventHandlerNonNull> handler;
|
||||
JS::Rooted<JSObject*> callable(aCx);
|
||||
if (aValue.isObject() &&
|
||||
JS_ObjectIsCallable(aCx, callable = &aValue.toObject())) {
|
||||
if (aValue.isObject() && JS::IsCallable(callable = &aValue.toObject())) {
|
||||
handler = new EventHandlerNonNull(callable, dom::GetIncumbentGlobal());
|
||||
}
|
||||
SetEventHandler(aType, EmptyString(), handler);
|
||||
|
|
|
@ -13,7 +13,7 @@ EXPORTS.mozilla.dom += [
|
|||
'FileSystemUtils.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'CreateDirectoryTask.cpp',
|
||||
'CreateFileTask.cpp',
|
||||
'DeviceStorageFileSystem.cpp',
|
||||
|
|
|
@ -11,7 +11,7 @@ EXPORTS.mozilla.dom += [
|
|||
'FMRadioRequestParent.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'FMRadioChild.cpp',
|
||||
'FMRadioParent.cpp',
|
||||
'FMRadioRequestChild.cpp',
|
||||
|
|
|
@ -15,7 +15,7 @@ if CONFIG['MOZ_B2G_FM']:
|
|||
'FMRadioService.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'FMRadio.cpp',
|
||||
'FMRadioService.cpp',
|
||||
]
|
||||
|
|
|
@ -11,7 +11,7 @@ EXPORTS.mozilla.dom += [
|
|||
'IccManager.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'Icc.cpp',
|
||||
'IccListener.cpp',
|
||||
'IccManager.cpp',
|
||||
|
|
|
@ -217,8 +217,7 @@ nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
|
|||
JS::Rooted<JS::Value> val(cx, aValue);
|
||||
JS::Rooted<JS::Value> toJSON(cx);
|
||||
if (JS_GetProperty(cx, obj, "toJSON", &toJSON) &&
|
||||
toJSON.isObject() &&
|
||||
JS_ObjectIsCallable(cx, &toJSON.toObject())) {
|
||||
toJSON.isObject() && JS::IsCallable(&toJSON.toObject())) {
|
||||
// If toJSON is implemented, it must not throw
|
||||
if (!JS_CallFunctionValue(cx, obj, toJSON, JS::HandleValueArray::empty(), &val)) {
|
||||
if (JS_IsExceptionPending(cx))
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
#include "nsJSUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#ifdef CONVERT_STRING_TO_NULLABLE_ENUM
|
||||
#undef CONVERT_STRING_TO_NULLABLE_ENUM
|
||||
#endif
|
||||
#define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum) \
|
||||
{ \
|
||||
uint32_t i = 0; \
|
||||
|
|
|
@ -231,13 +231,15 @@ MobileConnectionCallback::NotifyGetNetworksSuccess(uint32_t aCount,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult)
|
||||
MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
|
||||
JSContext* aCx)
|
||||
{
|
||||
return NotifySuccess(aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults)
|
||||
MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
|
||||
JSContext* aCx)
|
||||
{
|
||||
return NotifySuccess(aResults);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
|
||||
#include "jsapi.h"
|
||||
|
||||
#ifdef CONVERT_STRING_TO_NULLABLE_ENUM
|
||||
#undef CONVERT_STRING_TO_NULLABLE_ENUM
|
||||
#endif
|
||||
#define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum) \
|
||||
{ \
|
||||
_enum.SetNull(); \
|
||||
|
@ -117,7 +120,7 @@ MobileConnectionInfo::Update(nsIMobileConnectionInfo* aInfo)
|
|||
CONVERT_STRING_TO_NULLABLE_ENUM(type, MobileConnectionType, mType);
|
||||
|
||||
// Update mSignalStrength
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSContext cx;
|
||||
JS::Rooted<JS::Value> signalStrength(cx, JSVAL_VOID);
|
||||
aInfo->GetSignalStrength(&signalStrength);
|
||||
if (signalStrength.isNumber()) {
|
||||
|
|
|
@ -124,7 +124,7 @@ interface nsIMobileConnectionListener : nsISupports
|
|||
#define NO_ADDITIONAL_INFORMATION 0
|
||||
%}
|
||||
|
||||
[scriptable, builtinclass, uuid(e9d7c247-34c6-42bf-875b-f99b19db394f)]
|
||||
[scriptable, builtinclass, uuid(7f2dbbe0-42f2-11e4-916c-0800200c9a66)]
|
||||
interface nsIMobileConnectionCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -139,8 +139,10 @@ interface nsIMobileConnectionCallback : nsISupports
|
|||
void notifyGetNetworksSuccess(in uint32_t count,
|
||||
[array, size_is(count)] in nsIMobileNetworkInfo networks);
|
||||
|
||||
[implicit_jscontext]
|
||||
void notifySendCancelMmiSuccess(in jsval result /* MozMMIResult */);
|
||||
|
||||
[implicit_jscontext]
|
||||
void notifyGetCallForwardingSuccess(in jsval results /* Array of MozCallForwardingOptions */);
|
||||
|
||||
void notifyGetCallBarringSuccess(in unsigned short program,
|
||||
|
|
|
@ -242,7 +242,12 @@ NS_IMETHODIMP
|
|||
MobileConnectionChild::SetCallForwarding(JS::Handle<JS::Value> aOptions,
|
||||
nsIMobileConnectionCallback* aCallback)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSAPI jsapi;
|
||||
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
IPC::MozCallForwardingOptions options;
|
||||
if(!options.Init(cx, aOptions)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
|
@ -264,7 +269,12 @@ NS_IMETHODIMP
|
|||
MobileConnectionChild::SetCallBarring(JS::Handle<JS::Value> aOptions,
|
||||
nsIMobileConnectionCallback* aCallback)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSAPI jsapi;
|
||||
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
IPC::MozCallBarringOptions options;
|
||||
if(!options.Init(cx, aOptions)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
|
@ -278,7 +288,12 @@ NS_IMETHODIMP
|
|||
MobileConnectionChild::GetCallBarring(JS::Handle<JS::Value> aOptions,
|
||||
nsIMobileConnectionCallback* aCallback)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSAPI jsapi;
|
||||
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
IPC::MozCallBarringOptions options;
|
||||
if(!options.Init(cx, aOptions)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
|
@ -292,7 +307,12 @@ NS_IMETHODIMP
|
|||
MobileConnectionChild::ChangeCallBarringPassword(JS::Handle<JS::Value> aOptions,
|
||||
nsIMobileConnectionCallback* aCallback)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSAPI jsapi;
|
||||
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
IPC::MozCallBarringOptions options;
|
||||
if(!options.Init(cx, aOptions)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "mozilla/dom/MobileNetworkInfo.h"
|
||||
#include "mozilla/dom/MozMobileConnectionBinding.h"
|
||||
|
||||
using mozilla::AutoSafeJSContext;
|
||||
using mozilla::AutoJSContext;
|
||||
using mozilla::dom::MobileNetworkInfo;
|
||||
using mozilla::dom::MobileCellInfo;
|
||||
using mozilla::dom::MobileConnectionInfo;
|
||||
|
@ -261,7 +261,7 @@ struct ParamTraits<nsIMobileConnectionInfo*>
|
|||
return;
|
||||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSContext cx;
|
||||
nsString pString;
|
||||
bool pBool;
|
||||
nsCOMPtr<nsIMobileNetworkInfo> pNetworkInfo;
|
||||
|
@ -330,7 +330,7 @@ struct ParamTraits<nsIMobileConnectionInfo*>
|
|||
return true;
|
||||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
AutoJSContext cx;
|
||||
nsString state;
|
||||
bool connected;
|
||||
bool emergencyOnly;
|
||||
|
|
|
@ -423,7 +423,19 @@ MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aReques
|
|||
{
|
||||
NS_ENSURE_TRUE(mMobileConnection, false);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
// There are cases (bug 1070083) where this is called with no JS on the stack.
|
||||
// And since mobileConnectionService might be JS-Implemented, so we just
|
||||
// create it in the System-Principaled Junk Scope. We are going to get rid of
|
||||
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
|
||||
// we don't need these things.
|
||||
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
|
||||
// approval from the XPConnect module owner (bholley).
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> options(cx);
|
||||
if (!ToJSValue(cx, aRequest.options(), &options)) {
|
||||
JS_ClearPendingException(cx);
|
||||
|
@ -446,7 +458,19 @@ MobileConnectionRequestParent::DoRequest(const SetCallBarringRequest& aRequest)
|
|||
{
|
||||
NS_ENSURE_TRUE(mMobileConnection, false);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
// There are cases (bug 1070083) where this is called with no JS on the stack.
|
||||
// And since mobileConnectionService might be JS-Implemented, so we just
|
||||
// create it in the System-Principaled Junk Scope. We are going to get rid of
|
||||
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
|
||||
// we don't need these things.
|
||||
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
|
||||
// approval from the XPConnect module owner (bholley).
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> options(cx);
|
||||
if (!ToJSValue(cx, aRequest.options(), &options)) {
|
||||
JS_ClearPendingException(cx);
|
||||
|
@ -461,7 +485,19 @@ MobileConnectionRequestParent::DoRequest(const GetCallBarringRequest& aRequest)
|
|||
{
|
||||
NS_ENSURE_TRUE(mMobileConnection, false);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
// There are cases (bug 1070083) where this is called with no JS on the stack.
|
||||
// And since mobileConnectionService might be JS-Implemented, so we just
|
||||
// create it in the System-Principaled Junk Scope. We are going to get rid of
|
||||
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
|
||||
// we don't need these things.
|
||||
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
|
||||
// approval from the XPConnect module owner (bholley).
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> options(cx);
|
||||
if (!ToJSValue(cx, aRequest.options(), &options)) {
|
||||
JS_ClearPendingException(cx);
|
||||
|
@ -476,7 +512,19 @@ MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest&
|
|||
{
|
||||
NS_ENSURE_TRUE(mMobileConnection, false);
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
// There are cases (bug 1070083) where this is called with no JS on the stack.
|
||||
// And since mobileConnectionService might be JS-Implemented, so we just
|
||||
// create it in the System-Principaled Junk Scope. We are going to get rid of
|
||||
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
|
||||
// we don't need these things.
|
||||
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
|
||||
// approval from the XPConnect module owner (bholley).
|
||||
AutoJSAPI jsapi;
|
||||
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> options(cx);
|
||||
if (!ToJSValue(cx, aRequest.options(), &options)) {
|
||||
JS_ClearPendingException(cx);
|
||||
|
@ -579,12 +627,12 @@ MobileConnectionRequestParent::NotifyGetNetworksSuccess(uint32_t aCount,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult)
|
||||
MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
|
||||
JSContext* aCx)
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
RootedDictionary<MozMMIResult> result(cx);
|
||||
RootedDictionary<MozMMIResult> result(aCx);
|
||||
|
||||
if (!result.Init(cx, aResult)) {
|
||||
if (!result.Init(aCx, aResult)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
|
@ -605,13 +653,13 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
|
|||
|
||||
if (additionInformation.IsObject()) {
|
||||
uint32_t length;
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
JS::Rooted<JSObject*> object(cx, additionInformation.GetAsObject());
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
JS::Rooted<JSObject*> object(aCx, additionInformation.GetAsObject());
|
||||
|
||||
if (!JS_IsArrayObject(cx, object) ||
|
||||
!JS_GetArrayLength(cx, object, &length) || length <= 0 ||
|
||||
if (!JS_IsArrayObject(aCx, object) ||
|
||||
!JS_GetArrayLength(aCx, object, &length) || length <= 0 ||
|
||||
// Check first element to decide the format of array.
|
||||
!JS_GetElement(cx, object, 0, &value)) {
|
||||
!JS_GetElement(aCx, object, 0, &value)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
|
@ -620,12 +668,12 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
|
|||
// String[]
|
||||
nsTArray<nsString> infos;
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
if (!JS_GetElement(cx, object, i, &value) || !value.isString()) {
|
||||
if (!JS_GetElement(aCx, object, i, &value) || !value.isString()) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
nsAutoJSString str;
|
||||
if (!str.init(cx, value.toString())) {
|
||||
if (!str.init(aCx, value.toString())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
infos.AppendElement(str);
|
||||
|
@ -639,7 +687,7 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
|
|||
nsTArray<IPC::MozCallForwardingOptions> infos;
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
IPC::MozCallForwardingOptions info;
|
||||
if (!JS_GetElement(cx, object, i, &value) || !info.Init(cx, value)) {
|
||||
if (!JS_GetElement(aCx, object, i, &value) || !info.Init(aCx, value)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
|
@ -656,23 +704,23 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults)
|
||||
MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
|
||||
JSContext* aCx)
|
||||
{
|
||||
uint32_t length;
|
||||
AutoSafeJSContext cx;
|
||||
JS::Rooted<JSObject*> object(cx, &aResults.toObject());
|
||||
JS::Rooted<JSObject*> object(aCx, &aResults.toObject());
|
||||
nsTArray<IPC::MozCallForwardingOptions> results;
|
||||
|
||||
if (!JS_IsArrayObject(cx, object) ||
|
||||
!JS_GetArrayLength(cx, object, &length)) {
|
||||
if (!JS_IsArrayObject(aCx, object) ||
|
||||
!JS_GetArrayLength(aCx, object, &length)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
JS::Rooted<JS::Value> entry(cx);
|
||||
JS::Rooted<JS::Value> entry(aCx);
|
||||
IPC::MozCallForwardingOptions info;
|
||||
|
||||
if (!JS_GetElement(cx, object, i, &entry) || !info.Init(cx, entry)) {
|
||||
if (!JS_GetElement(aCx, object, i, &entry) || !info.Init(aCx, entry)) {
|
||||
return NS_ERROR_TYPE_ERR;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ XPIDL_SOURCES += [
|
|||
'interfaces/nsINeighboringCellInfo.idl',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'DOMMMIError.cpp',
|
||||
'ipc/MobileConnectionChild.cpp',
|
||||
'ipc/MobileConnectionIPCService.cpp',
|
||||
|
|
|
@ -10,16 +10,12 @@
|
|||
|
||||
namespace {
|
||||
|
||||
const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
|
||||
#define kPrefDefaultServiceId "dom.sms.defaultServiceId"
|
||||
const char* kObservedPrefs[] = {
|
||||
kPrefDefaultServiceId,
|
||||
nullptr
|
||||
};
|
||||
|
||||
uint32_t
|
||||
getDefaultServiceId()
|
||||
{
|
||||
static const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
|
||||
int32_t id = mozilla::Preferences::GetInt(kPrefDefaultServiceId, 0);
|
||||
int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1);
|
||||
|
||||
|
@ -46,6 +42,10 @@ SmsService::SmsService()
|
|||
NS_WARN_IF_FALSE(mRil, "This shouldn't fail!");
|
||||
|
||||
// Initialize observer.
|
||||
static const char* kObservedPrefs[] = {
|
||||
kPrefDefaultServiceId,
|
||||
nullptr
|
||||
};
|
||||
Preferences::AddStrongObservers(this, kObservedPrefs);
|
||||
mDefaultServiceId = getDefaultServiceId();
|
||||
}
|
||||
|
|
|
@ -19,14 +19,8 @@ using namespace mozilla::dom::mobilemessage;
|
|||
|
||||
namespace {
|
||||
|
||||
const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
|
||||
#define kPrefMmsDefaultServiceId "dom.mms.defaultServiceId"
|
||||
#define kPrefSmsDefaultServiceId "dom.sms.defaultServiceId"
|
||||
const char* kObservedPrefs[] = {
|
||||
kPrefMmsDefaultServiceId,
|
||||
kPrefSmsDefaultServiceId,
|
||||
nullptr
|
||||
};
|
||||
|
||||
// TODO: Bug 767082 - WebSMS: sSmsChild leaks at shutdown
|
||||
PSmsChild* gSmsChild;
|
||||
|
@ -86,6 +80,7 @@ SendCursorRequest(const IPCMobileMessageCursor& aRequest,
|
|||
uint32_t
|
||||
getDefaultServiceId(const char* aPrefKey)
|
||||
{
|
||||
static const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
|
||||
int32_t id = mozilla::Preferences::GetInt(aPrefKey, 0);
|
||||
int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1);
|
||||
|
||||
|
@ -119,6 +114,11 @@ SmsIPCService::GetSingleton()
|
|||
|
||||
SmsIPCService::SmsIPCService()
|
||||
{
|
||||
static const char* kObservedPrefs[] = {
|
||||
kPrefMmsDefaultServiceId,
|
||||
kPrefSmsDefaultServiceId,
|
||||
nullptr
|
||||
};
|
||||
Preferences::AddStrongObservers(this, kObservedPrefs);
|
||||
mMmsDefaultServiceId = getDefaultServiceId(kPrefMmsDefaultServiceId);
|
||||
mSmsDefaultServiceId = getDefaultServiceId(kPrefSmsDefaultServiceId);
|
||||
|
|
|
@ -35,7 +35,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
|
|||
'gonk/MobileMessageDatabaseService.js',
|
||||
'gonk/MobileMessageDatabaseService.manifest',
|
||||
]
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'gonk/SmsService.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -128,7 +128,8 @@ if CONFIG['MOZ_NFC']:
|
|||
if CONFIG['MOZ_B2G']:
|
||||
DIRS += [
|
||||
'downloads',
|
||||
'mobileid'
|
||||
'mobileid',
|
||||
'engineeringmode'
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_B2G_BT_API_V2']:
|
||||
|
|
|
@ -14,7 +14,7 @@ if CONFIG['MOZ_NFC']:
|
|||
EXPORTS.mozilla.dom += [
|
||||
'MozNDEFRecord.h',
|
||||
]
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'MozNDEFRecord.cpp',
|
||||
]
|
||||
EXTRA_COMPONENTS += [
|
||||
|
@ -24,7 +24,7 @@ if CONFIG['MOZ_NFC']:
|
|||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_NFC']:
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'gonk/NfcMessageHandler.cpp',
|
||||
'gonk/NfcService.cpp',
|
||||
]
|
||||
|
|
|
@ -1609,7 +1609,7 @@ NPObjWrapper_Convert(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint, JS::
|
|||
JS::Rooted<JS::Value> v(cx, JSVAL_VOID);
|
||||
if (!JS_GetProperty(cx, obj, "toString", &v))
|
||||
return false;
|
||||
if (!v.isPrimitive() && JS_ObjectIsCallable(cx, v.toObjectOrNull())) {
|
||||
if (!v.isPrimitive() && JS::IsCallable(v.toObjectOrNull())) {
|
||||
if (!JS_CallFunctionValue(cx, obj, v, JS::HandleValueArray::empty(), vp))
|
||||
return false;
|
||||
if (vp.isPrimitive())
|
||||
|
|
|
@ -1092,7 +1092,7 @@ Promise::ResolveInternal(JSContext* aCx,
|
|||
return;
|
||||
}
|
||||
|
||||
if (then.isObject() && JS_ObjectIsCallable(aCx, &then.toObject())) {
|
||||
if (then.isObject() && JS::IsCallable(&then.toObject())) {
|
||||
// This is the then() function of the thenable aValueObj.
|
||||
JS::Rooted<JSObject*> thenObj(aCx, &then.toObject());
|
||||
nsRefPtr<PromiseInit> thenCallback =
|
||||
|
|
|
@ -12,7 +12,7 @@ EXPORTS += [
|
|||
'SpeakerManagerServiceChild.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
UNIFIED_SOURCES += [
|
||||
'SpeakerManager.cpp',
|
||||
'SpeakerManagerService.cpp',
|
||||
'SpeakerManagerServiceChild.cpp',
|
||||
|
|
|
@ -378,7 +378,7 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
|
|||
// The volume name will have already been parsed, and the tokenizer will point
|
||||
// to the token after the volume name
|
||||
switch (aResponseCode) {
|
||||
case ResponseCode::VolumeListResult: {
|
||||
case ::ResponseCode::VolumeListResult: {
|
||||
// Each line will look something like:
|
||||
//
|
||||
// sdcard /mnt/sdcard 1
|
||||
|
@ -397,7 +397,7 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
|
|||
break;
|
||||
}
|
||||
|
||||
case ResponseCode::VolumeStateChange: {
|
||||
case ::ResponseCode::VolumeStateChange: {
|
||||
// Format of the line looks something like:
|
||||
//
|
||||
// Volume sdcard /mnt/sdcard state changed from 7 (Shared-Unmounted) to 1 (Idle-Unmounted)
|
||||
|
@ -415,12 +415,12 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
|
|||
break;
|
||||
}
|
||||
|
||||
case ResponseCode::VolumeDiskInserted:
|
||||
case ::ResponseCode::VolumeDiskInserted:
|
||||
SetMediaPresent(true);
|
||||
break;
|
||||
|
||||
case ResponseCode::VolumeDiskRemoved: // fall-thru
|
||||
case ResponseCode::VolumeBadRemoval:
|
||||
case ::ResponseCode::VolumeDiskRemoved: // fall-thru
|
||||
case ::ResponseCode::VolumeBadRemoval:
|
||||
SetMediaPresent(false);
|
||||
break;
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче