Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-02-24 12:07:20 +01:00
Родитель 6f691ca2b0 20095687cf
Коммит 94388a5225
248 изменённых файлов: 3522 добавлений и 2243 удалений

Просмотреть файл

@ -18,22 +18,26 @@
src="../layout.js"></script>
<script type="application/javascript">
var kX = 10, kY = 10, kWidth = 150, kHeight = 100;
function doTest()
{
var canv = document.getElementById("c");
var context = canv.getContext('2d');
var element = document.getElementById("showA");
context.beginPath();
context.rect(10, 10, 150, 100);
context.rect(kX, kY, kWidth, kHeight);
context.addHitRegion({control: element});
var input = getAccessible("showA");
var input = getAccessible("showA");
var [cnvX, cnvY, cnvWidth, cnvHeight] = getBoundsForDOMElm(canv);
var [accX, accY, accWidth, accHeight] = getBounds(input);
is(accX, cnvX + 10, "accX should be 10 and not " + accX);
is(accY, cnvY + 10, "accY should be 10 and not " + accY);
is(accWidth, 150, "accWidth should be 150 and not " + accWidth);
is(accHeight, 100, "accHeight should be 100 and not " + accHeight);
var [x, y, w, h] = CSSToDevicePixels(window, kX, kY, kWidth, kHeight);
is(accX, cnvX + x, "wrong accX");
is(accY, cnvY + y, "wrong accY");
is(accWidth, w, "wrong accWidth");
is(accHeight, h, "wrong accHeight");
SimpleTest.finish();
}

Просмотреть файл

@ -345,10 +345,17 @@ function eventQueue(aEventType)
var msg = "Test with ID = '" + this.getEventID(checker) +
"' succeed. ";
if (checker.unexpected)
ok(true, msg + "There's no unexpected " + typeStr + " event.");
else
if (checker.unexpected) {
if (checker.todo) {
todo(false, "Event " + typeStr + " event is still missing");
}
else {
ok(true, msg + "There's no unexpected " + typeStr + " event.");
}
}
else {
ok(true, msg + "Event " + typeStr + " was handled.");
}
}
}
}
@ -371,8 +378,13 @@ function eventQueue(aEventType)
ok(false, msg + "Dupe " + typeStr + " event.");
if (checker.unexpected) {
if (checker.wasCaught)
if (checker.todo) {
todo(checker.wasCaught,
"Event " + typeStr + " event is still missing");
}
else if (checker.wasCaught) {
ok(false, msg + "There's unexpected " + typeStr + " event.");
}
} else if (!checker.wasCaught) {
ok(false, msg + typeStr + " event was missed.");
}
@ -1667,6 +1679,18 @@ function invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg, aIsAsync)
this.mTargetFuncArg = aTargetFuncArg;
}
/**
* Generic invoker checker for todo events.
*/
function todo_invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
{
this.__proto__ = new invokerChecker(aEventType, aTargetOrFunc,
aTargetFuncArg, true);
this.unexpected = true;
this.todo = true;
}
/**
* Generic invoker checker for unexpected events.
*/

Просмотреть файл

@ -358,6 +358,25 @@
}
}
function showHiddenParentOfVisibleChild()
{
this.eventSeq = [
new todo_invokerChecker(EVENT_HIDE, getNode("c4_child")),
new invokerChecker(EVENT_SHOW, getNode("c4_middle")),
new invokerChecker(EVENT_REORDER, getNode("c4"))
];
this.invoke = function showHiddenParentOfVisibleChild_invoke()
{
getNode("c4_middle").style.visibility = 'visible';
}
this.getID = function showHiddenParentOfVisibleChild_getID()
{
return "show hidden parent of visible child";
}
}
/**
* Target getters.
*/
@ -484,6 +503,7 @@
gQueue.push(new test2("testContainer", "testNestedContainer"));
gQueue.push(new test3("testContainer"));
gQueue.push(new insertReferredElm("testContainer3"));
gQueue.push(new showHiddenParentOfVisibleChild());
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -544,5 +564,11 @@
</div>
<div id="testContainer2"></div>
<div id="testContainer3"></div>
<div id="c4">
<div style="visibility:hidden" id="c4_middle">
<div style="visibility:visible" id="c4_child"></div>
</div>
</div>
</body>
</html>

Просмотреть файл

@ -41,29 +41,31 @@
function doTest()
{
var offsetX = 20, offsetY = 40;
getNode("hitcanvas").scrollIntoView(true);
var context = document.getElementById("hitcanvas").getContext('2d');
redrawCheckbox(context, document.getElementById('hitcheck'), 20, 40);
redrawCheckbox(context, document.getElementById('hitcheck'),
offsetX, offsetY);
var hitcanvas = getAccessible("hitcanvas");
var hitcheck = getAccessible("hitcheck");
var [hitX, hitY, hitWidth, hitHeight] = getBounds(hitcanvas);
var [deltaX, deltaY] = CSSToDevicePixels(window, offsetX, offsetY);
var docAcc = getAccessible(document);
var tgtX = hitX+25;
var tgtY = hitY+45;
hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY);
// test if we hit the region associated with the shadow dom checkbox
is(hitAcc, hitcheck, "Hit match at " + tgtX + "," + tgtY +
". Found: " + prettyName(hitAcc));
tgtY = hitY+75;
// test if we hit the region associated with the shadow dom checkbox
var tgtX = hitX + deltaX;
var tgtY = hitY + deltaY;
hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY);
isObject(hitAcc, hitcheck, `Hit match at (${tgtX}, ${tgtY}`);
// test that we don't hit the region associated with the shadow dom checkbox
is(hitAcc, hitcanvas, "Hit match at " + tgtX + "," + tgtY +
". Found: " + prettyName(hitAcc));
tgtY = hitY + deltaY * 2;
hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY);
isObject(hitAcc, hitcanvas, `Hit match at (${tgtX}, ${tgtY}`);
SimpleTest.finish();
}

Просмотреть файл

@ -2,7 +2,6 @@
[test_bindings.xhtml]
[test_embeds.xul]
skip-if = (os == "linux" && (debug || asan)) # Bug 845176
[test_general.html]
[test_general.xul]
[test_tabbrowser.xul]

Просмотреть файл

@ -37,7 +37,7 @@
}
this.eventSeq = [
new invokerChecker(EVENT_REORDER, currentBrowser)
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
];
this.finalCheck = function loadURI_finalCheck()
@ -52,27 +52,6 @@
}
}
function browserReorderChecker()
{
this.type = EVENT_REORDER;
this.match = function browserReorderChecker_match(aEvent)
{
if (!isAccessible(currentBrowser()))
return false;
// Reorder event might be duped because of temporary document creation.
if (aEvent.accessible == getAccessible(currentBrowser())) {
this.cnt++;
return this.cnt != 2;
}
return false;
}
this.cnt = 0;
}
function loadOneTab(aURI)
{
this.invoke = function loadOneTab_invoke()
@ -81,7 +60,7 @@
}
this.eventSeq = [
new browserReorderChecker()
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
];
this.finalCheck = function loadURI_finalCheck()
@ -99,7 +78,7 @@
////////////////////////////////////////////////////////////////////////////
// Testing
gA11yEventDumpToConsole = true; // debug
//gA11yEventDumpToConsole = true; // debug
var gQueue = null;
function doTests()

Просмотреть файл

@ -32,7 +32,8 @@
anchor = getAccessible("bottom2");
var [x, y] = getPos(anchor);
var wnd = getRootAccessible().DOMDocument.defaultView;
var scrollToX = docX - wnd.screenX, scrollToY = docY - wnd.screenY;
var [screenX, screenY] = CSSToDevicePixels(wnd, wnd.screenX, wnd.screenY);
var scrollToX = docX - screenX, scrollToY = docY - screenY;
anchor.scrollToPoint(COORDTYPE_WINDOW_RELATIVE, scrollToX, scrollToY);
testPos(anchor, [x, docY]);

Просмотреть файл

@ -16,6 +16,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429659
src="role.js"></script>
<script type="application/javascript"
src="attributes.js"></script>
<script type="application/javascript"
src="layout.js"></script>
<script type="application/javascript">
function testCoordinates(aID, aAcc, aWidth, aHeight)
@ -70,10 +72,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429659
// "Wrong screen y coordinate for " + aID + "!");
}
var [expected_w, expected_h] = CSSToDevicePixels(window, aWidth, aHeight);
var width = {}, height = {};
aAcc.getImageSize(width, height);
is(width.value, aWidth, "Wrong width for " + aID + "!");
is(height.value, aHeight, "wrong height for " + aID + "!");
is(width.value, expected_w, "Wrong width for " + aID + "!");
is(height.value, expected_h, "wrong height for " + aID + "!");
}
function testThis(aID, aSRC, aWidth, aHeight,

Просмотреть файл

@ -407,6 +407,8 @@ XULMenupopupAccessible::
mSelectControl = do_QueryInterface(mContent->GetFlattenedTreeParent());
if (!mSelectControl)
mGenericTypes &= ~eSelect;
mStateFlags |= eNoXBLKids;
}
uint64_t

Просмотреть файл

@ -157,10 +157,11 @@ const Utils = {
// We also reject handlers registered from a different host (see bug 402287)
// The pref allows us to test the feature
let pb = Services.prefs;
if ((!pb.prefHasUserValue(PREF_ALLOW_DIFFERENT_HOST) ||
!pb.getBoolPref(PREF_ALLOW_DIFFERENT_HOST)) &&
aContentWindow.location.hostname != uri.host)
if (!pb.getBoolPref(PREF_ALLOW_DIFFERENT_HOST) &&
(!["http:", "https:"].includes(aContentWindow.location.protocol) ||
aContentWindow.location.hostname != uri.host)) {
throw("Permission denied to add " + uri.spec + " as a content or protocol handler");
}
// If the uri doesn't contain '%s', it won't be a good handler
if (uri.spec.indexOf("%s") < 0)

Просмотреть файл

@ -27,6 +27,8 @@ If you would like to use a different directory, hit CTRL+c and set the
MOZBUILD_STATE_PATH environment variable to the directory you would like to
use and re-run mach. For this change to take effect forever, you'll likely
want to export this environment variable from your shell's init scripts.
Press ENTER/RETURN to continue or CTRL+c to abort.
'''.lstrip()
NO_MERCURIAL_SETUP = '''
@ -254,8 +256,26 @@ def bootstrap(topsrcdir, mozilla_dir=None):
raise
# Add common metadata to help submit sorted data later on.
# For now, we'll just record the mach command that was invoked.
data['argv'] = sys.argv
data.setdefault('system', {}).update(dict(
architecture=list(platform.architecture()),
machine=platform.machine(),
python_version=platform.python_version(),
release=platform.release(),
system=platform.system(),
version=platform.version(),
))
if platform.system() == 'Linux':
dist = list(platform.linux_distribution())
data['system']['linux_distribution'] = dist
elif platform.system() == 'Windows':
win32_ver=list((platform.win32_ver())),
data['system']['win32_ver'] = win32_ver
elif platform.system() == 'Darwin':
# mac version is a special Cupertino snowflake
r, v, m = platform.mac_ver()
data['system']['mac_ver'] = [r, list(v), m]
with open(os.path.join(outgoing_dir, str(uuid.uuid4()) + '.json'),
'w') as f:
@ -383,25 +403,18 @@ def bootstrap(topsrcdir, mozilla_dir=None):
if is_environ:
if not os.path.exists(state_dir):
print('Creating global state directory from environment variable: %s'
% state_dir)
% state_dir)
os.makedirs(state_dir, mode=0o770)
print('Please re-run mach.')
sys.exit(1)
else:
if not os.path.exists(state_dir):
print(STATE_DIR_FIRST_RUN.format(userdir=state_dir))
try:
for i in range(20, -1, -1):
time.sleep(1)
sys.stdout.write('%d ' % i)
sys.stdout.flush()
sys.stdin.readline()
except KeyboardInterrupt:
sys.exit(1)
print('\nCreating default state directory: %s' % state_dir)
os.mkdir(state_dir)
print('Please re-run mach.')
sys.exit(1)
os.makedirs(state_dir, mode=0o770)
return state_dir

Просмотреть файл

@ -0,0 +1,24 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"argv": {"type": "array"},
"system": {
"type": "object",
"properties": {
"architecture": {"type": "array"},
"linux_distribution": {"type": "array"},
"mac_ver": {"type": "array"},
"machine": {"type": "string"},
"python_version": {"type": "string"},
"release": {"type": "string"},
"system": {"type": "string"},
"version": {"type": "string"},
"win_ver": {"type": "array"}
},
"required": ["architecture", "machine", "python_version",
"release", "system", "version"]
}
},
"required": ["argv", "system"]
}

Просмотреть файл

@ -3851,18 +3851,6 @@ MOZ_ARG_WITH_STRING(gcm-senderid-keyfile,
MOZ_ANDROID_GCM_SENDERID=`cat $withval`)
AC_SUBST(MOZ_ANDROID_GCM_SENDERID)
# Whether to include optional-but-large font files in the final APK.
# We want this in mobile/android/confvars.sh, so it goes early.
MOZ_ARG_DISABLE_BOOL(android-include-fonts,
[ --disable-android-include-fonts
Disable the inclusion of fonts into the final APK],
MOZ_ANDROID_EXCLUDE_FONTS=1)
if test -n "$MOZ_ANDROID_EXCLUDE_FONTS"; then
AC_DEFINE(MOZ_ANDROID_EXCLUDE_FONTS)
fi
AC_SUBST(MOZ_ANDROID_EXCLUDE_FONTS)
# Whether this APK is destined for resource constrained devices.
# We want this in mobile/android/confvars.sh, so it goes early.
MOZ_ARG_ENABLE_BOOL(android-resource-constrained,
@ -4775,6 +4763,13 @@ if test -n "$MOZ_ANDROID_MLS_STUMBLER"; then
AC_DEFINE(MOZ_ANDROID_MLS_STUMBLER)
fi
dnl =========================================================
dnl = Whether to exclude font files in the build
dnl =========================================================
if test -n "$MOZ_ANDROID_EXCLUDE_FONTS"; then
AC_DEFINE(MOZ_ANDROID_EXCLUDE_FONTS)
fi
dnl =========================================================
dnl = Whether to exclude hyphenations files in the build
dnl =========================================================
@ -8457,6 +8452,7 @@ AC_SUBST(MOZ_ANDROID_APPLICATION_CLASS)
AC_SUBST(MOZ_ANDROID_BROWSER_INTENT_CLASS)
AC_SUBST(MOZ_ANDROID_SEARCH_INTENT_CLASS)
AC_SUBST(MOZ_ANDROID_DOWNLOAD_CONTENT_SERVICE)
AC_SUBST(MOZ_ANDROID_EXCLUDE_FONTS)
AC_SUBST(MOZ_EXCLUDE_HYPHENATION_DICTIONARIES)
AC_SUBST(MOZ_INSTALL_TRACKING)
AC_SUBST(MOZ_SWITCHBOARD)

Просмотреть файл

@ -1,8 +1,8 @@
load 1239889-1.html
load 1244595-1.html
load 1216842-1.html
load 1216842-2.html
load 1216842-3.html
load 1216842-4.html
load 1216842-5.html
load 1216842-6.html
pref(dom.animations-api.core.enabled,true) load 1239889-1.html
pref(dom.animations-api.core.enabled,true) load 1244595-1.html
pref(dom.animations-api.core.enabled,true) load 1216842-1.html
pref(dom.animations-api.core.enabled,true) load 1216842-2.html
pref(dom.animations-api.core.enabled,true) load 1216842-3.html
pref(dom.animations-api.core.enabled,true) load 1216842-4.html
pref(dom.animations-api.core.enabled,true) load 1216842-5.html
pref(dom.animations-api.core.enabled,true) load 1216842-6.html

Просмотреть файл

@ -125,7 +125,7 @@ FormData::Append(const nsAString& aName, Blob& aBlob,
return;
}
AddNameBlobPair(aName, file);
AddNameBlobOrNullPair(aName, file);
}
void
@ -179,12 +179,18 @@ FormData::Has(const nsAString& aName)
}
nsresult
FormData::AddNameBlobPair(const nsAString& aName, Blob* aBlob)
FormData::AddNameBlobOrNullPair(const nsAString& aName, Blob* aBlob)
{
MOZ_ASSERT(aBlob);
RefPtr<File> file;
if (!aBlob) {
FormDataTuple* data = mFormData.AppendElement();
SetNameValuePair(data, aName, EmptyString(), true /* aWasNullBlob */);
return NS_OK;
}
ErrorResult rv;
RefPtr<File> file = GetOrCreateFileCalledBlob(*aBlob, rv);
file = GetOrCreateFileCalledBlob(*aBlob, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
@ -269,10 +275,12 @@ FormData::GetValueAtIndex(uint32_t aIndex) const
void
FormData::SetNameValuePair(FormDataTuple* aData,
const nsAString& aName,
const nsAString& aValue)
const nsAString& aValue,
bool aWasNullBlob)
{
MOZ_ASSERT(aData);
aData->name = aName;
aData->wasNullBlob = aWasNullBlob;
aData->value.SetAsUSVString() = aValue;
}
@ -285,6 +293,7 @@ FormData::SetNameFilePair(FormDataTuple* aData,
MOZ_ASSERT(aFile);
aData->name = aName;
aData->wasNullBlob = false;
aData->value.SetAsBlob() = aFile;
}
@ -366,13 +375,16 @@ FormData::GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
nsFSMultipartFormData fs(NS_LITERAL_CSTRING("UTF-8"), nullptr);
for (uint32_t i = 0; i < mFormData.Length(); ++i) {
if (mFormData[i].value.IsBlob()) {
fs.AddNameBlobPair(mFormData[i].name, mFormData[i].value.GetAsBlob());
if (mFormData[i].wasNullBlob) {
MOZ_ASSERT(mFormData[i].value.IsUSVString());
fs.AddNameBlobOrNullPair(mFormData[i].name, nullptr);
} else if (mFormData[i].value.IsUSVString()) {
fs.AddNameValuePair(mFormData[i].name,
mFormData[i].value.GetAsUSVString());
} else {
MOZ_CRASH("This should no be possible.");
MOZ_ASSERT(mFormData[i].value.IsBlob());
fs.AddNameBlobOrNullPair(mFormData[i].name,
mFormData[i].value.GetAsBlob());
}
}

Просмотреть файл

@ -35,6 +35,7 @@ private:
struct FormDataTuple
{
nsString name;
bool wasNullBlob;
OwningBlobOrUSVString value;
};
@ -45,7 +46,8 @@ private:
void SetNameValuePair(FormDataTuple* aData,
const nsAString& aName,
const nsAString& aValue);
const nsAString& aValue,
bool aWasNullBlob = false);
void SetNameFilePair(FormDataTuple* aData,
const nsAString& aName,
@ -114,8 +116,8 @@ public:
return NS_OK;
}
virtual nsresult AddNameBlobPair(const nsAString& aName,
Blob* aBlob) override;
virtual nsresult AddNameBlobOrNullPair(const nsAString& aName,
Blob* aBlob) override;
typedef bool (*FormDataEntryCallback)(const nsString& aName,
const OwningBlobOrUSVString& aValue,

Просмотреть файл

@ -1824,16 +1824,8 @@ WebSocket::CreateAndDispatchMessageEvent(const nsACString& aData,
}
}
return CreateAndDispatchMessageEvent(jsapi.cx(), aData, aIsBinary);
}
nsresult
WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
const nsACString& aData,
bool aIsBinary)
{
MOZ_ASSERT(mImpl);
AssertIsOnTargetThread();
jsapi.TakeOwnershipOfErrorReporting();
JSContext* cx = jsapi.cx();
nsresult rv = CheckInnerWindowCorrectness();
if (NS_FAILED(rv)) {
@ -1843,19 +1835,19 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
uint16_t messageType = nsIWebSocketEventListener::TYPE_STRING;
// Create appropriate JS object for message
JS::Rooted<JS::Value> jsData(aCx);
JS::Rooted<JS::Value> jsData(cx);
if (aIsBinary) {
if (mBinaryType == dom::BinaryType::Blob) {
messageType = nsIWebSocketEventListener::TYPE_BLOB;
nsresult rv = nsContentUtils::CreateBlobBuffer(aCx, GetOwner(), aData,
nsresult rv = nsContentUtils::CreateBlobBuffer(cx, GetOwner(), aData,
&jsData);
NS_ENSURE_SUCCESS(rv, rv);
} else if (mBinaryType == dom::BinaryType::Arraybuffer) {
messageType = nsIWebSocketEventListener::TYPE_ARRAYBUFFER;
JS::Rooted<JSObject*> arrayBuf(aCx);
nsresult rv = nsContentUtils::CreateArrayBuffer(aCx, aData,
JS::Rooted<JSObject*> arrayBuf(cx);
nsresult rv = nsContentUtils::CreateArrayBuffer(cx, aData,
arrayBuf.address());
NS_ENSURE_SUCCESS(rv, rv);
jsData.setObject(*arrayBuf);
@ -1867,7 +1859,7 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx,
// JS string
NS_ConvertUTF8toUTF16 utf16Data(aData);
JSString* jsString;
jsString = JS_NewUCStringCopyN(aCx, utf16Data.get(), utf16Data.Length());
jsString = JS_NewUCStringCopyN(cx, utf16Data.get(), utf16Data.Length());
NS_ENSURE_TRUE(jsString, NS_ERROR_FAILURE);
jsData.setString(jsString);

Просмотреть файл

@ -138,9 +138,6 @@ private: // constructor && distructor
nsresult CreateAndDispatchSimpleEvent(const nsAString& aName);
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
bool aIsBinary);
nsresult CreateAndDispatchMessageEvent(JSContext* aCx,
const nsACString& aData,
bool aIsBinary);
nsresult CreateAndDispatchCloseEvent(bool aWasClean,
uint16_t aCode,
const nsAString& aReason);

Просмотреть файл

@ -25,7 +25,9 @@
#include "MediaDecoder.h"
// nsNPAPIPluginInstance must be included before nsIDocument.h, which is included in mozAutoDocUpdate.h.
#include "nsNPAPIPluginInstance.h"
#include "gfxDrawable.h"
#include "gfxPrefs.h"
#include "ImageOps.h"
#include "mozAutoDocUpdate.h"
#include "mozilla/ArrayUtils.h"
#include "mozilla/Attributes.h"
@ -200,6 +202,7 @@
#include "nsICookieService.h"
#include "mozilla/EnumSet.h"
#include "mozilla/BloomFilter.h"
#include "SourceSurfaceRawData.h"
#include "nsIBidiKeyboard.h"
@ -216,6 +219,7 @@ extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
class imgLoader;
using namespace mozilla::dom;
using namespace mozilla::gfx;
using namespace mozilla::layers;
using namespace mozilla::widget;
using namespace mozilla;
@ -7427,6 +7431,48 @@ nsContentUtils::IsFileImage(nsIFile* aFile, nsACString& aType)
return StringBeginsWith(aType, NS_LITERAL_CSTRING("image/"));
}
nsresult
nsContentUtils::DataTransferItemToImage(const IPCDataTransferItem& aItem,
imgIContainer** aContainer)
{
MOZ_ASSERT(aItem.data().type() == IPCDataTransferData::TnsCString);
MOZ_ASSERT(IsFlavorImage(aItem.flavor()));
const IPCDataTransferImage& imageDetails = aItem.imageDetails();
const IntSize size(imageDetails.width(), imageDetails.height());
if (!size.width || !size.height) {
return NS_ERROR_FAILURE;
}
const nsCString& text = aItem.data().get_nsCString();
// InitWrappingData takes a non-const pointer for reading.
nsCString& nonConstText = const_cast<nsCString&>(text);
RefPtr<SourceSurfaceRawData> image = new SourceSurfaceRawData();
image->InitWrappingData(reinterpret_cast<uint8_t*>(nonConstText.BeginWriting()),
size, imageDetails.stride(),
static_cast<SurfaceFormat>(imageDetails.format()),
false);
image->GuaranteePersistance();
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(image, size);
nsCOMPtr<imgIContainer> imageContainer =
image::ImageOps::CreateFromDrawable(drawable);
imageContainer.forget(aContainer);
return NS_OK;
}
bool
nsContentUtils::IsFlavorImage(const nsACString& aFlavor)
{
return aFlavor.EqualsLiteral(kNativeImageMime) ||
aFlavor.EqualsLiteral(kJPEGImageMime) ||
aFlavor.EqualsLiteral(kJPGImageMime) ||
aFlavor.EqualsLiteral(kPNGImageMime) ||
aFlavor.EqualsLiteral(kGIFImageMime);
}
void
nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
IPCDataTransfer* aIPCDataTransfer,

Просмотреть файл

@ -121,6 +121,7 @@ class DocumentFragment;
class Element;
class EventTarget;
class IPCDataTransfer;
class IPCDataTransferItem;
class NodeInfo;
class nsIContentChild;
class nsIContentParent;
@ -2428,6 +2429,21 @@ public:
*/
static bool IsFileImage(nsIFile* aFile, nsACString& aType);
/**
* Given an IPCDataTransferItem that has a flavor for which IsFlavorImage
* returns true and whose IPCDataTransferData is of type nsCString (raw image
* data), construct an imgIContainer for the image encoded by the transfer
* item.
*/
static nsresult DataTransferItemToImage(const mozilla::dom::IPCDataTransferItem& aItem,
imgIContainer** aContainer);
/**
* Given a flavor obtained from an IPCDataTransferItem or nsITransferable,
* returns true if we should treat the data as an image.
*/
static bool IsFlavorImage(const nsACString& aFlavor);
static void TransferablesToIPCTransferables(nsISupportsArray* aTransferables,
nsTArray<mozilla::dom::IPCDataTransfer>& aIPC,
bool aInSyncMessage,

Просмотреть файл

@ -3171,7 +3171,7 @@ nsDOMWindowUtils::ExitFullscreen()
// Although we would not use the old size if we have already exited
// fullscreen, we still want to cleanup in case we haven't.
nsSize oldSize = OldWindowSize::GetAndRemove(doc->GetWindow());
if (!doc->IsFullScreenDoc()) {
if (!doc->GetFullscreenElement()) {
return NS_OK;
}

Просмотреть файл

@ -9286,7 +9286,7 @@ nsDocument::OnPageHide(bool aPersisted,
EnumerateActivityObservers(NotifyActivityChanged, nullptr);
ClearPendingFullscreenRequests(this);
if (IsFullScreenDoc()) {
if (GetFullscreenElement()) {
// If this document was fullscreen, we should exit fullscreen in this
// doctree branch. This ensures that if the user navigates while in
// fullscreen mode we don't leave its still visible ancestor documents
@ -11099,7 +11099,7 @@ nsIDocument::AsyncExitFullscreen(nsIDocument* aDoc)
static bool
CountFullscreenSubDocuments(nsIDocument* aDoc, void* aData)
{
if (aDoc->IsFullScreenDoc()) {
if (aDoc->GetFullscreenElement()) {
uint32_t* count = static_cast<uint32_t*>(aData);
(*count)++;
}
@ -11119,7 +11119,7 @@ nsDocument::IsFullscreenLeaf()
{
// A fullscreen leaf document is fullscreen, and has no fullscreen
// subdocuments.
if (!IsFullScreenDoc()) {
if (!GetFullscreenElement()) {
return false;
}
return CountFullscreenSubDocuments(this) == 0;
@ -11128,11 +11128,12 @@ nsDocument::IsFullscreenLeaf()
static bool
ResetFullScreen(nsIDocument* aDocument, void* aData)
{
if (aDocument->IsFullScreenDoc()) {
if (aDocument->GetFullscreenElement()) {
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
"Should have at most 1 fullscreen subdocument.");
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
NS_ASSERTION(!aDocument->IsFullScreenDoc(), "Should reset full-screen");
NS_ASSERTION(!aDocument->GetFullscreenElement(),
"Should reset full-screen");
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
changed->AppendElement(aDocument);
aDocument->EnumerateSubDocuments(ResetFullScreen, aData);
@ -11179,7 +11180,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
UnlockPointer();
nsCOMPtr<nsIDocument> root = aMaybeNotARootDoc->GetFullscreenRoot();
if (!root || !root->IsFullScreenDoc()) {
if (!root || !root->GetFullscreenElement()) {
// If a document was detached before exiting from fullscreen, it is
// possible that the root had left fullscreen state. In this case,
// we would not get anything from the ResetFullScreen() call. Root's
@ -11208,7 +11209,7 @@ nsIDocument::ExitFullscreenInDocTree(nsIDocument* aMaybeNotARootDoc)
DispatchFullScreenChange(changed[changed.Length() - i - 1]);
}
NS_ASSERTION(!root->IsFullScreenDoc(),
NS_ASSERTION(!root->GetFullscreenElement(),
"Fullscreen root should no longer be a fullscreen doc...");
// Move the top-level window out of fullscreen mode.
@ -11225,7 +11226,7 @@ GetFullscreenLeaf(nsIDocument* aDoc, void* aData)
nsIDocument** result = static_cast<nsIDocument**>(aData);
*result = aDoc;
return false;
} else if (aDoc->IsFullScreenDoc()) {
} else if (aDoc->GetFullscreenElement()) {
aDoc->EnumerateSubDocuments(GetFullscreenLeaf, aData);
}
return true;
@ -11244,7 +11245,7 @@ GetFullscreenLeaf(nsIDocument* aDoc)
nsIDocument* root = nsContentUtils::GetRootDocument(aDoc);
// Check that the root is actually fullscreen so we don't waste time walking
// around its descendants.
if (!root->IsFullScreenDoc()) {
if (!root->GetFullscreenElement()) {
return nullptr;
}
GetFullscreenLeaf(root, &leaf);
@ -11254,10 +11255,10 @@ GetFullscreenLeaf(nsIDocument* aDoc)
void
nsDocument::RestorePreviousFullScreenState()
{
NS_ASSERTION(!IsFullScreenDoc() || !FullscreenRoots::IsEmpty(),
NS_ASSERTION(!GetFullscreenElement() || !FullscreenRoots::IsEmpty(),
"Should have at least 1 fullscreen root when fullscreen!");
if (!IsFullScreenDoc() || !GetWindow() || FullscreenRoots::IsEmpty()) {
if (!GetFullscreenElement() || !GetWindow() || FullscreenRoots::IsEmpty()) {
return;
}
@ -11337,12 +11338,6 @@ nsDocument::RestorePreviousFullScreenState()
}
}
bool
nsDocument::IsFullScreenDoc()
{
return GetFullscreenElement() != nullptr;
}
class nsCallRequestFullScreen : public nsRunnable
{
public:
@ -11814,7 +11809,7 @@ ShouldApplyFullscreenDirectly(nsIDocument* aDoc,
// If we are in the content process, we can apply the fullscreen
// state directly only if we have been in DOM fullscreen, because
// otherwise we always need to notify the chrome.
return nsContentUtils::GetRootDocument(aDoc)->IsFullScreenDoc();
return !!nsContentUtils::GetRootDocument(aDoc)->GetFullscreenElement();
} else {
// If we are in the chrome process, and the window has not been in
// fullscreen, we certainly need to make that fullscreen first.
@ -12151,7 +12146,7 @@ public:
return NS_OK;
}
if (doc->IsFullScreenDoc() || doc->mAllowRelocking) {
if (doc->GetFullscreenElement() || doc->mAllowRelocking) {
Allow(JS::UndefinedHandleValue);
return NS_OK;
}

Просмотреть файл

@ -1200,7 +1200,6 @@ public:
mozilla::UniquePtr<FullscreenRequest>&& aRequest) override;
virtual void RestorePreviousFullScreenState() override;
virtual bool IsFullscreenLeaf() override;
virtual bool IsFullScreenDoc() override;
virtual nsresult
RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) override;

Просмотреть файл

@ -1230,7 +1230,8 @@ nsFocusManager::SetFocusInner(nsIContent* aNewContent, int32_t aFlags,
// to guard against phishing.
#ifndef XP_MACOSX
if (contentToFocus &&
nsContentUtils::GetRootDocument(contentToFocus->OwnerDoc())->IsFullScreenDoc() &&
nsContentUtils::
GetRootDocument(contentToFocus->OwnerDoc())->GetFullscreenElement() &&
nsContentUtils::HasPluginWithUncontrolledEventDispatch(contentToFocus)) {
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DOM"),

Просмотреть файл

@ -1175,11 +1175,6 @@ public:
*/
virtual void RestorePreviousFullScreenState() = 0;
/**
* Returns true if this document is in full-screen mode.
*/
virtual bool IsFullScreenDoc() = 0;
/**
* Returns true if this document is a fullscreen leaf document, i.e. it
* is in fullscreen mode and has no fullscreen children.
@ -2505,7 +2500,7 @@ public:
virtual Element* GetFullscreenElement() = 0;
bool MozFullScreen()
{
return IsFullScreenDoc();
return !!GetFullscreenElement();
}
void ExitFullscreen();
Element* GetMozPointerLockElement();

Просмотреть файл

@ -2091,7 +2091,7 @@ nsRange::CutContents(DocumentFragment** aFragment)
} else if (nodeToResult) {
nsMutationGuard guard;
nsCOMPtr<nsINode> node = nodeToResult;
nsINode* parent = node->GetParentNode();
nsCOMPtr<nsINode> parent = node->GetParentNode();
if (parent) {
mozilla::ErrorResult error;
parent->RemoveChild(*node, error);

Просмотреть файл

@ -58,8 +58,7 @@ nsStructuredCloneContainer::InitFromJSVal(JS::Handle<JS::Value> aData,
NS_IMETHODIMP
nsStructuredCloneContainer::InitFromBase64(const nsAString &aData,
uint32_t aFormatVersion,
JSContext* aCx)
uint32_t aFormatVersion)
{
if (DataLength()) {
return NS_ERROR_FAILURE;

Просмотреть файл

@ -1415,8 +1415,8 @@ nsTreeSanitizer::SanitizeChildren(nsINode* aRoot)
}
if (MustFlatten(ns, localName)) {
RemoveAllAttributes(node);
nsIContent* next = node->GetNextNode(aRoot);
nsIContent* parent = node->GetParent();
nsCOMPtr<nsIContent> next = node->GetNextNode(aRoot);
nsCOMPtr<nsIContent> parent = node->GetParent();
nsCOMPtr<nsIContent> child; // Must keep the child alive during move
ErrorResult rv;
while ((child = node->GetFirstChild())) {

Просмотреть файл

@ -0,0 +1,60 @@
const CC = Components.Constructor;
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream");
function utf8decode(s) {
return decodeURIComponent(escape(s));
}
function utf8encode(s) {
return unescape(encodeURIComponent(s));
}
function handleRequest(request, response) {
var bodyStream = new BinaryInputStream(request.bodyInputStream);
var requestBody = "";
while ((bodyAvail = bodyStream.available()) > 0) {
requestBody += bodyStream.readBytes(bodyAvail);
}
var result = [];
if (request.method == "POST") {
var contentTypeParams = {};
request.getHeader("Content-Type").split(/\s*\;\s*/).forEach(function(s) {
if (s.indexOf('=') >= 0) {
let [name, value] = s.split('=');
contentTypeParams[name] = value;
}
else {
contentTypeParams[''] = s;
}
});
if (contentTypeParams[''] == "multipart/form-data" &&
request.queryString == "") {
requestBody.split("--" + contentTypeParams.boundary).slice(1, -1).forEach(function (s) {
let headers = {};
let headerEnd = s.indexOf("\r\n\r\n");
s.substr(2, headerEnd-2).split("\r\n").forEach(function(s) {
// We're assuming UTF8 for now
let [name, value] = s.split(': ');
headers[name] = utf8decode(value);
});
let body = s.substring(headerEnd + 4, s.length - 2);
if (!headers["Content-Type"] || headers["Content-Type"] == "text/plain") {
// We're assuming UTF8 for now
body = utf8decode(body);
}
result.push({ headers: headers, body: body});
});
}
}
response.setHeader("Content-Type", "text/plain; charset=utf-8", false);
response.write(utf8encode(JSON.stringify(result)));
}

Просмотреть файл

@ -258,6 +258,7 @@ support-files =
referrer_change_server.sjs
file_change_policy_redirect.html
file_bug1198095.js
file_bug1250148.sjs
[test_anonymousContent_api.html]
[test_anonymousContent_append_after_reflow.html]
@ -870,3 +871,4 @@ skip-if = buildapp == 'b2g' #no ssl support
[test_bug1198095.html]
[test_bug1187157.html]
[test_bug769117.html]
[test_bug1250148.html]

Просмотреть файл

@ -15,14 +15,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=789315
<script type="text/javascript">
var obj = new FormData(document.getElementById('a')).get('b');
is(obj, "", "We want an empty string.");
ok(obj instanceof Blob, "This should return an empty Blob");
is(obj.size, 0, "Size should be 0");
is(obj.type, "application/octet-stream", "Type should be application/octet-stream");
var o = obj.slice(10, 100, "foo/bar");
is(o.size, 0, "The new blob has size 0");
is(o.type, "foo/bar", "The new blob has type foo/bar");
</script>
</body>

Просмотреть файл

@ -0,0 +1,52 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1250148
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1250148 - FormData and HTML submission compatibility</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<form id="form" enctype="multipart/form-data"><input type="file" name="test" /></form>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
var f = document.getElementById('form');
var fd = new FormData(f);
is(fd.get("test"), "", "We want an empty string.");
var getAll = fd.getAll("test");
ok(Array.isArray(getAll), "We want an array with 1 empty string.");
is(getAll.length, 1, "We want an array with 1 empty string.");
is(getAll[0], "", "We want an array with 1 empty string.");
var xhr = new XMLHttpRequest();
xhr.open("POST", "file_bug1250148.sjs", true);
xhr.onload = function() {
var obj = JSON.parse(xhr.responseText);
ok(Array.isArray(obj), "XHR response is an array.");
is(obj.length, 1, "XHR response array contains 1 result.");
ok("headers" in obj[0], "XHR response has an header value");
ok("Content-Disposition" in obj[0].headers, "XHR response.headers array has a Content-Desposition value");
is(obj[0].headers["Content-Disposition"], "form-data; name=\"test\"; filename=\"\"", "Correct Content-Disposition");
ok("Content-Type" in obj[0].headers, "XHR response.headers array has a Content-Type value");
is(obj[0].headers["Content-Type"], "application/octet-stream", "Correct Content-Type");
ok("body" in obj[0], "XHR response has a body value");
is(obj[0].body, "", "Correct body value");
SimpleTest.finish();
}
xhr.send(fd);
</script>
</body>
</html>

Просмотреть файл

@ -2,6 +2,8 @@
# 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/.
ifdef COMPILE_ENVIRONMENT
include ../webidlsrcs.mk
# $(test_sources) comes from webidlsrcs.mk.
@ -12,6 +14,8 @@ CPPSRCS += $(addprefix ../,$(test_sources))
# rules.mk and running make with no target in this dir does the right thing.
include $(topsrcdir)/config/rules.mk
endif
check::
PYTHONDONTWRITEBYTECODE=1 $(PYTHON) $(topsrcdir)/config/pythonpath.py \
$(PLY_INCLUDE) $(srcdir)/../parser/runtests.py

Просмотреть файл

@ -177,7 +177,7 @@ public:
// Getter for the window that this Geolocation is owned by
nsIWeakReference* GetOwner() { return mOwner; }
// Check to see if the widnow still exists
// Check to see if the window still exists
bool WindowOwnerStillExists();
// Check to see if any active request requires high accuracy

Просмотреть файл

@ -5582,14 +5582,11 @@ HTMLInputElement::SubmitNamesValues(nsFormSubmission* aFormSubmission)
const nsTArray<RefPtr<File>>& files = GetFilesInternal();
for (uint32_t i = 0; i < files.Length(); ++i) {
aFormSubmission->AddNameBlobPair(name, files[i]);
aFormSubmission->AddNameBlobOrNullPair(name, files[i]);
}
if (files.IsEmpty()) {
RefPtr<BlobImpl> blobImpl =
new EmptyBlobImpl(NS_LITERAL_STRING("application/octet-stream"));
RefPtr<Blob> blob = Blob::Create(OwnerDoc()->GetInnerWindow(), blobImpl);
aFormSubmission->AddNameBlobPair(name, blob);
aFormSubmission->AddNameBlobOrNullPair(name, nullptr);
}
return NS_OK;

Просмотреть файл

@ -577,7 +577,7 @@ HTMLSelectElement::Add(nsGenericHTMLElement& aElement,
// Just in case we're not the parent, get the parent of the reference
// element
nsINode* parent = aBefore->Element::GetParentNode();
nsCOMPtr<nsINode> parent = aBefore->Element::GetParentNode();
if (!parent || !nsContentUtils::ContentIsDescendantOf(parent, this)) {
// NOT_FOUND_ERR: Raised if before is not a descendant of the SELECT
// element.

Просмотреть файл

@ -521,8 +521,8 @@ HTMLTableElement::InsertRow(int32_t aIndex, ErrorResult& aError)
refIndex = rowCount - 1;
}
Element* refRow = rows->Item(refIndex);
nsINode* parent = refRow->GetParentNode();
RefPtr<Element> refRow = rows->Item(refIndex);
nsCOMPtr<nsINode> parent = refRow->GetParentNode();
// create the row
RefPtr<mozilla::dom::NodeInfo> nodeInfo;

Просмотреть файл

@ -57,7 +57,9 @@ SendJSWarning(nsIDocument* aDocument,
static void
RetrieveFileName(Blob* aBlob, nsAString& aFilename)
{
MOZ_ASSERT(aBlob);
if (!aBlob) {
return;
}
RefPtr<File> file = aBlob->ToFile();
if (file) {
@ -88,8 +90,8 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue) override;
virtual nsresult AddNameBlobPair(const nsAString& aName,
Blob* aBlob) override;
virtual nsresult AddNameBlobOrNullPair(const nsAString& aName,
Blob* aBlob) override;
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream)
override;
@ -175,11 +177,9 @@ nsFSURLEncoded::AddIsindex(const nsAString& aValue)
}
nsresult
nsFSURLEncoded::AddNameBlobPair(const nsAString& aName,
Blob* aBlob)
nsFSURLEncoded::AddNameBlobOrNullPair(const nsAString& aName,
Blob* aBlob)
{
MOZ_ASSERT(aBlob);
if (!mWarnedFileControl) {
SendJSWarning(mDocument, "ForgotFileEnctypeWarning", nullptr, 0);
mWarnedFileControl = true;
@ -436,7 +436,7 @@ nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
// Make MIME block for name/value pair
// XXX: name parameter should be encoded per RFC 2231
// RFC 2388 specifies that RFC 2047 be used, but I think it's not
// RFC 2388 specifies that RFC 2047 be used, but I think it's not
// consistent with MIME standard.
mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary
+ NS_LITERAL_CSTRING(CRLF)
@ -448,66 +448,69 @@ nsFSMultipartFormData::AddNameValuePair(const nsAString& aName,
}
nsresult
nsFSMultipartFormData::AddNameBlobPair(const nsAString& aName,
Blob* aBlob)
nsFSMultipartFormData::AddNameBlobOrNullPair(const nsAString& aName,
Blob* aBlob)
{
MOZ_ASSERT(aBlob);
// Encode the control name
nsAutoCString nameStr;
nsresult rv = EncodeVal(aName, nameStr, true);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString filename16;
RetrieveFileName(aBlob, filename16);
nsAutoCString filename;
nsAutoCString contentType;
nsCOMPtr<nsIInputStream> fileStream;
ErrorResult error;
nsAutoString filepath16;
RefPtr<File> file = aBlob->ToFile();
if (file) {
file->GetPath(filepath16, error);
if (aBlob) {
nsAutoString filename16;
RetrieveFileName(aBlob, filename16);
ErrorResult error;
nsAutoString filepath16;
RefPtr<File> file = aBlob->ToFile();
if (file) {
file->GetPath(filepath16, error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
}
if (!filepath16.IsEmpty()) {
// File.path includes trailing "/"
filename16 = filepath16 + filename16;
}
rv = EncodeVal(filename16, filename, true);
NS_ENSURE_SUCCESS(rv, rv);
// Get content type
nsAutoString contentType16;
aBlob->GetType(contentType16);
if (contentType16.IsEmpty()) {
contentType16.AssignLiteral("application/octet-stream");
}
contentType.Adopt(nsLinebreakConverter::
ConvertLineBreaks(NS_ConvertUTF16toUTF8(contentType16).get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace));
// Get input stream
aBlob->GetInternalStream(getter_AddRefs(fileStream), error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
}
if (!filepath16.IsEmpty()) {
// File.path includes trailing "/"
filename16 = filepath16 + filename16;
}
if (fileStream) {
// Create buffered stream (for efficiency)
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
fileStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString filename;
rv = EncodeVal(filename16, filename, true);
NS_ENSURE_SUCCESS(rv, rv);
// Get content type
nsAutoString contentType16;
aBlob->GetType(contentType16);
if (contentType16.IsEmpty()) {
contentType16.AssignLiteral("application/octet-stream");
}
nsAutoCString contentType;
contentType.Adopt(nsLinebreakConverter::
ConvertLineBreaks(NS_ConvertUTF16toUTF8(contentType16).get(),
nsLinebreakConverter::eLinebreakAny,
nsLinebreakConverter::eLinebreakSpace));
// Get input stream
nsCOMPtr<nsIInputStream> fileStream;
aBlob->GetInternalStream(getter_AddRefs(fileStream), error);
if (NS_WARN_IF(error.Failed())) {
return error.StealNSResult();
}
if (fileStream) {
// Create buffered stream (for efficiency)
nsCOMPtr<nsIInputStream> bufferedStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedStream),
fileStream, 8192);
NS_ENSURE_SUCCESS(rv, rv);
fileStream = bufferedStream;
fileStream = bufferedStream;
}
} else {
contentType.AssignLiteral("application/octet-stream");
}
//
@ -517,7 +520,7 @@ nsFSMultipartFormData::AddNameBlobPair(const nsAString& aName,
mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary
+ NS_LITERAL_CSTRING(CRLF);
// XXX: name/filename parameter should be encoded per RFC 2231
// RFC 2388 specifies that RFC 2047 be used, but I think it's not
// RFC 2388 specifies that RFC 2047 be used, but I think it's not
// consistent with the MIME standard.
mPostDataChunk +=
NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
@ -576,7 +579,7 @@ nsresult
nsFSMultipartFormData::AddPostDataStream()
{
nsresult rv = NS_OK;
nsCOMPtr<nsIInputStream> postDataChunkStream;
rv = NS_NewCStringInputStream(getter_AddRefs(postDataChunkStream),
mPostDataChunk);
@ -603,8 +606,8 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue) override;
virtual nsresult AddNameBlobPair(const nsAString& aName,
Blob* aBlob) override;
virtual nsresult AddNameBlobOrNullPair(const nsAString& aName,
Blob* aBlob) override;
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream)
override;
@ -627,11 +630,9 @@ nsFSTextPlain::AddNameValuePair(const nsAString& aName,
}
nsresult
nsFSTextPlain::AddNameBlobPair(const nsAString& aName,
Blob* aBlob)
nsFSTextPlain::AddNameBlobOrNullPair(const nsAString& aName,
Blob* aBlob)
{
MOZ_ASSERT(aBlob);
nsAutoString filename;
RetrieveFileName(aBlob, filename);
AddNameValuePair(aName, filename);

Просмотреть файл

@ -49,10 +49,11 @@ public:
*
* @param aName the name of the parameter
* @param aBlob the blob to submit. The file's name will be used if the Blob
* is actually a File, otherwise 'blob' string is used instead.
* is actually a File, otherwise 'blob' string is used instead if the aBlob is
* not null.
*/
virtual nsresult AddNameBlobPair(const nsAString& aName,
mozilla::dom::Blob* aBlob) = 0;
virtual nsresult AddNameBlobOrNullPair(const nsAString& aName,
mozilla::dom::Blob* aBlob) = 0;
/**
* Reports whether the instance supports AddIsindex().
@ -160,8 +161,8 @@ public:
virtual nsresult AddNameValuePair(const nsAString& aName,
const nsAString& aValue) override;
virtual nsresult AddNameBlobPair(const nsAString& aName,
mozilla::dom::Blob* aBlob) override;
virtual nsresult AddNameBlobOrNullPair(const nsAString& aName,
mozilla::dom::Blob* aBlob) override;
virtual nsresult GetEncodedSubmission(nsIURI* aURI,
nsIInputStream** aPostDataStream) override;

Просмотреть файл

@ -486,7 +486,7 @@ skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' # b2g
[test_iframe_sandbox_popups.html]
skip-if = buildapp == 'b2g' # b2g(multiple concurrent window.open()s fail on B2G) b2g-debug(multiple concurrent window.open()s fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage)
[test_iframe_sandbox_popups_inheritance.html]
skip-if = buildapp == 'b2g' || e10s || toolkit == 'android' # b2g(multiple concurrent window.open()s fail on B2G) b2g-debug(multiple concurrent window.open()s fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) android(bug 939642)
skip-if = buildapp == 'b2g' || toolkit == 'android' # b2g(multiple concurrent window.open()s fail on B2G) b2g-debug(multiple concurrent window.open()s fail on B2G) b2g-desktop(Bug 931116, b2g desktop specific, initial triage) android(bug 939642)
[test_iframe_sandbox_redirect.html]
[test_iframe_sandbox_refresh.html]
[test_iframe_sandbox_same_origin.html]
@ -582,7 +582,7 @@ skip-if = toolkit == 'android'
[test_bug677495.html]
[test_bug677495-1.html]
[test_bug741266.html]
skip-if = buildapp == "mulet" || buildapp == "b2g" || toolkit == "android" || toolkit == "windows" || e10s # b2g(needs control of popup window size) b2g-debug(needs control of popup window size) b2g-desktop(needs control of popup window size) windows(bug 1234520)
skip-if = buildapp == "mulet" || buildapp == "b2g" || toolkit == "android" || toolkit == "windows" # b2g(needs control of popup window size) b2g-debug(needs control of popup window size) b2g-desktop(needs control of popup window size) windows(bug 1234520)
[test_non-ascii-cookie.html]
skip-if = buildapp == 'b2g'
support-files = file_cookiemanager.js

Просмотреть файл

@ -590,7 +590,7 @@ var expectedAugment = [
//{ name: "aNameUndef", value: "undefined" },
];
function checkMPSubmission(sub, expected, test, isFormData = false) {
function checkMPSubmission(sub, expected, test) {
function getPropCount(o) {
var x, l = 0;
for (x in o) ++l;
@ -625,7 +625,7 @@ function checkMPSubmission(sub, expected, test, isFormData = false) {
else {
is(sub[i].headers["Content-Disposition"],
"form-data; name=\"" + mpquote(expected[i].name) + "\"; filename=\"" +
mpquote(expected[i].fileName != "" || !isFormData ? expected[i].fileName : "blob") + "\"",
mpquote(expected[i].fileName) + "\"",
"Correct name in " + test);
is(sub[i].headers["Content-Type"],
expected[i].contentType,
@ -782,14 +782,14 @@ function runTest() {
xhr.open("POST", "form_submit_server.sjs");
xhr.send(new FormData(form));
yield undefined; // Wait for XHR load
checkMPSubmission(JSON.parse(xhr.responseText), expectedSub, "send form using XHR and FormData", true);
checkMPSubmission(JSON.parse(xhr.responseText), expectedSub, "send form using XHR and FormData");
// Send disabled form using XHR and FormData
setDisabled(document.querySelectorAll("input, select, textarea"), true);
xhr.open("POST", "form_submit_server.sjs");
xhr.send(new FormData(form));
yield undefined;
checkMPSubmission(JSON.parse(xhr.responseText), [], "send disabled form using XHR and FormData", true);
checkMPSubmission(JSON.parse(xhr.responseText), [], "send disabled form using XHR and FormData");
setDisabled(document.querySelectorAll("input, select, textarea"), false);
// Send FormData
@ -804,7 +804,7 @@ function runTest() {
xhr.open("POST", "form_submit_server.sjs");
xhr.send(fd);
yield undefined;
checkMPSubmission(JSON.parse(xhr.responseText), expectedAugment, "send FormData", true);
checkMPSubmission(JSON.parse(xhr.responseText), expectedAugment, "send FormData");
// Augment <form> using FormData
fd = new FormData(form);
@ -813,7 +813,7 @@ function runTest() {
xhr.send(fd);
yield undefined;
checkMPSubmission(JSON.parse(xhr.responseText),
expectedSub.concat(expectedAugment), "send augmented FormData", true);
expectedSub.concat(expectedAugment), "send augmented FormData");
SimpleTest.finish();
yield undefined;

Просмотреть файл

@ -308,7 +308,7 @@ struct FullObjectStoreMetadata
// These two members are only ever touched on a transaction thread!
int64_t mNextAutoIncrementId;
int64_t mComittedAutoIncrementId;
int64_t mCommittedAutoIncrementId;
bool mDeleted;
@ -316,7 +316,7 @@ public:
FullObjectStoreMetadata()
: mCommonMetadata(0, nsString(), KeyPath(0), false)
, mNextAutoIncrementId(0)
, mComittedAutoIncrementId(0)
, mCommittedAutoIncrementId(0)
, mDeleted(false)
{
// This can happen either on the QuotaManager IO thread or on a
@ -12618,7 +12618,7 @@ FullDatabaseMetadata::Duplicate() const
newOSMetadata->mCommonMetadata = value->mCommonMetadata;
newOSMetadata->mNextAutoIncrementId = value->mNextAutoIncrementId;
newOSMetadata->mComittedAutoIncrementId = value->mComittedAutoIncrementId;
newOSMetadata->mCommittedAutoIncrementId = value->mCommittedAutoIncrementId;
for (auto iter = value->mIndexes.ConstIter(); !iter.Done(); iter.Next()) {
auto key = iter.Key();
@ -15138,7 +15138,7 @@ VersionChangeTransaction::RecvCreateObjectStore(
RefPtr<FullObjectStoreMetadata> newMetadata = new FullObjectStoreMetadata();
newMetadata->mCommonMetadata = aMetadata;
newMetadata->mNextAutoIncrementId = aMetadata.autoIncrement() ? 1 : 0;
newMetadata->mComittedAutoIncrementId = newMetadata->mNextAutoIncrementId;
newMetadata->mCommittedAutoIncrementId = newMetadata->mNextAutoIncrementId;
if (NS_WARN_IF(!dbMetadata->mObjectStores.Put(aMetadata.id(), newMetadata,
fallible))) {
@ -20270,7 +20270,7 @@ OpenDatabaseOp::LoadDatabaseInformation(mozIStorageConnection* aConnection)
metadata->mCommonMetadata.autoIncrement() = !!nextAutoIncrementId;
metadata->mNextAutoIncrementId = nextAutoIncrementId;
metadata->mComittedAutoIncrementId = nextAutoIncrementId;
metadata->mCommittedAutoIncrementId = nextAutoIncrementId;
if (NS_WARN_IF(!objectStores.Put(objectStoreId, metadata, fallible))) {
return NS_ERROR_OUT_OF_MEMORY;
@ -21062,13 +21062,16 @@ OpenDatabaseOp::AssertMetadataConsistency(const FullDatabaseMetadata* aMetadata)
otherObjectStore->mCommonMetadata.autoIncrement());
MOZ_ASSERT(thisObjectStore->mCommonMetadata.keyPath() ==
otherObjectStore->mCommonMetadata.keyPath());
// mNextAutoIncrementId and mComittedAutoIncrementId may be modified
// mNextAutoIncrementId and mCommittedAutoIncrementId may be modified
// concurrently with this OpenOp, so it is not possible to assert equality
// here.
// here. It's also possible that we've written the new ids to disk but not
// yet updated the in-memory count.
MOZ_ASSERT(thisObjectStore->mNextAutoIncrementId <=
otherObjectStore->mNextAutoIncrementId);
MOZ_ASSERT(thisObjectStore->mComittedAutoIncrementId <=
otherObjectStore->mComittedAutoIncrementId);
MOZ_ASSERT(thisObjectStore->mCommittedAutoIncrementId <=
otherObjectStore->mCommittedAutoIncrementId ||
thisObjectStore->mCommittedAutoIncrementId ==
otherObjectStore->mNextAutoIncrementId);
MOZ_ASSERT(!otherObjectStore->mDeleted);
MOZ_ASSERT(thisObjectStore->mIndexes.Count() ==
@ -22151,9 +22154,9 @@ CommitOp::CommitOrRollbackAutoIncrementCounts()
RefPtr<FullObjectStoreMetadata>& metadata = metadataArray[index];
if (committed) {
metadata->mComittedAutoIncrementId = metadata->mNextAutoIncrementId;
metadata->mCommittedAutoIncrementId = metadata->mNextAutoIncrementId;
} else {
metadata->mNextAutoIncrementId = metadata->mComittedAutoIncrementId;
metadata->mNextAutoIncrementId = metadata->mCommittedAutoIncrementId;
}
}
}

Просмотреть файл

@ -42,8 +42,7 @@ interface nsIStructuredCloneContainer : nsISupports
* stream, stored in aData. aFormatVersion should be the version of the
* structured clone algorithm which was used to generate aData.
*/
[implicit_jscontext]
void initFromBase64(in AString aData,in unsigned long aFormatVersion);
void initFromBase64(in AString aData, in unsigned long aFormatVersion);
/**
* Deserializes this structured clone container returning it as a jsval.

Просмотреть файл

@ -156,8 +156,6 @@
#include "nsPIWindowWatcher.h"
#include "nsWindowWatcher.h"
#include "nsIXULRuntime.h"
#include "gfxDrawable.h"
#include "ImageOps.h"
#include "mozilla/dom/nsMixedContentBlocker.h"
#include "nsMemoryInfoDumper.h"
#include "nsMemoryReporterManager.h"
@ -2865,75 +2863,56 @@ ContentParent::RecvSetClipboard(const IPCDataTransfer& aDataTransfer,
nsCOMPtr<nsIClipboard> clipboard(do_GetService(kCClipboardCID, &rv));
NS_ENSURE_SUCCESS(rv, true);
nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
nsCOMPtr<nsITransferable> trans =
do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
NS_ENSURE_SUCCESS(rv, true);
trans->Init(nullptr);
const nsTArray<IPCDataTransferItem>& items = aDataTransfer.items();
for (uint32_t j = 0; j < items.Length(); ++j) {
const IPCDataTransferItem& item = items[j];
for (const auto& item : items) {
trans->AddDataFlavor(item.flavor().get());
if (item.data().type() == IPCDataTransferData::TnsString) {
nsCOMPtr<nsISupportsString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, true);
nsString text = item.data().get_nsString();
rv = dataWrapper->SetData(text);
NS_ENSURE_SUCCESS(rv, true);
rv = trans->SetTransferData(item.flavor().get(), dataWrapper,
text.Length() * sizeof(char16_t));
NS_ENSURE_SUCCESS(rv, true);
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
if (item.flavor().EqualsLiteral(kNativeImageMime) ||
item.flavor().EqualsLiteral(kJPEGImageMime) ||
item.flavor().EqualsLiteral(kJPGImageMime) ||
item.flavor().EqualsLiteral(kPNGImageMime) ||
item.flavor().EqualsLiteral(kGIFImageMime)) {
const IPCDataTransferImage& imageDetails = item.imageDetails();
const gfx::IntSize size(imageDetails.width(), imageDetails.height());
if (!size.width || !size.height) {
return true;
}
nsCString text = item.data().get_nsCString();
RefPtr<gfx::DataSourceSurface> image =
new mozilla::gfx::SourceSurfaceRawData();
mozilla::gfx::SourceSurfaceRawData* raw =
static_cast<mozilla::gfx::SourceSurfaceRawData*>(image.get());
raw->InitWrappingData(
reinterpret_cast<uint8_t*>(const_cast<nsCString&>(text).BeginWriting()),
size, imageDetails.stride(),
static_cast<mozilla::gfx::SurfaceFormat>(imageDetails.format()), false);
raw->GuaranteePersistance();
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(image, size);
nsCOMPtr<imgIContainer> imageContainer(image::ImageOps::CreateFromDrawable(drawable));
nsCOMPtr<nsISupportsInterfacePointer>
imgPtr(do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv));
rv = imgPtr->SetData(imageContainer);
nsCOMPtr<nsISupportsString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, true);
trans->SetTransferData(item.flavor().get(), imgPtr, sizeof(nsISupports*));
} else {
nsCOMPtr<nsISupportsCString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, true);
const nsCString& text = item.data().get_nsCString();
const nsString& text = item.data().get_nsString();
rv = dataWrapper->SetData(text);
NS_ENSURE_SUCCESS(rv, true);
rv = trans->SetTransferData(item.flavor().get(), dataWrapper, text.Length());
rv = trans->SetTransferData(item.flavor().get(), dataWrapper,
text.Length() * sizeof(char16_t));
NS_ENSURE_SUCCESS(rv, true);
}
} else if (item.data().type() == IPCDataTransferData::TnsCString) {
if (nsContentUtils::IsFlavorImage(item.flavor())) {
nsCOMPtr<imgIContainer> imageContainer;
rv = nsContentUtils::DataTransferItemToImage(item,
getter_AddRefs(imageContainer));
NS_ENSURE_SUCCESS(rv, true);
nsCOMPtr<nsISupportsInterfacePointer> imgPtr =
do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID);
NS_ENSURE_TRUE(imgPtr, true);
rv = imgPtr->SetData(imageContainer);
NS_ENSURE_SUCCESS(rv, true);
trans->SetTransferData(item.flavor().get(), imgPtr, sizeof(nsISupports*));
} else {
nsCOMPtr<nsISupportsCString> dataWrapper =
do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, true);
const nsCString& text = item.data().get_nsCString();
rv = dataWrapper->SetData(text);
NS_ENSURE_SUCCESS(rv, true);
rv = trans->SetTransferData(item.flavor().get(), dataWrapper, text.Length());
NS_ENSURE_SUCCESS(rv, true);
}
}
}

Просмотреть файл

@ -3152,24 +3152,7 @@ TabParent::RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
EventStateManager* esm = shell->GetPresContext()->EventStateManager();
for (uint32_t i = 0; i < aTransfers.Length(); ++i) {
auto& items = aTransfers[i].items();
nsTArray<DataTransferItem>* itemArray = mInitialDataTransferItems.AppendElement();
for (uint32_t j = 0; j < items.Length(); ++j) {
const IPCDataTransferItem& item = items[j];
DataTransferItem* localItem = itemArray->AppendElement();
localItem->mFlavor = item.flavor();
if (item.data().type() == IPCDataTransferData::TnsString) {
localItem->mType = DataTransferItem::DataType::eString;
localItem->mStringData = item.data().get_nsString();
} else if (item.data().type() == IPCDataTransferData::TPBlobChild) {
localItem->mType = DataTransferItem::DataType::eBlob;
BlobParent* blobParent =
static_cast<BlobParent*>(item.data().get_PBlobParent());
if (blobParent) {
localItem->mBlobData = blobParent->GetBlobImpl();
}
}
}
mInitialDataTransferItems.AppendElement(mozilla::Move(aTransfers[i].items()));
}
if (Manager()->IsContentParent()) {
nsCOMPtr<nsIDragService> dragService =
@ -3205,24 +3188,37 @@ void
TabParent::AddInitialDnDDataTo(DataTransfer* aDataTransfer)
{
for (uint32_t i = 0; i < mInitialDataTransferItems.Length(); ++i) {
nsTArray<DataTransferItem>& itemArray = mInitialDataTransferItems[i];
for (uint32_t j = 0; j < itemArray.Length(); ++j) {
DataTransferItem& item = itemArray[j];
nsTArray<IPCDataTransferItem>& itemArray = mInitialDataTransferItems[i];
for (auto& item : itemArray) {
RefPtr<nsVariantCC> variant = new nsVariantCC();
// Special case kFilePromiseMime so that we get the right
// nsIFlavorDataProvider for it.
if (item.mFlavor.EqualsLiteral(kFilePromiseMime)) {
if (item.flavor().EqualsLiteral(kFilePromiseMime)) {
RefPtr<nsISupports> flavorDataProvider =
new nsContentAreaDragDropDataProvider();
variant->SetAsISupports(flavorDataProvider);
} else if (item.mType == DataTransferItem::DataType::eString) {
variant->SetAsAString(item.mStringData);
} else if (item.mType == DataTransferItem::DataType::eBlob) {
variant->SetAsISupports(item.mBlobData);
} else if (item.data().type() == IPCDataTransferData::TnsString) {
variant->SetAsAString(item.data().get_nsString());
} else if (item.data().type() == IPCDataTransferData::TPBlobParent) {
auto* parent = static_cast<BlobParent*>(item.data().get_PBlobParent());
RefPtr<BlobImpl> impl = parent->GetBlobImpl();
variant->SetAsISupports(impl);
} else if (item.data().type() == IPCDataTransferData::TnsCString &&
nsContentUtils::IsFlavorImage(item.flavor())) {
// An image! Get the imgIContainer for it and set it in the variant.
nsCOMPtr<imgIContainer> imageContainer;
nsresult rv =
nsContentUtils::DataTransferItemToImage(item,
getter_AddRefs(imageContainer));
if (NS_FAILED(rv)) {
continue;
}
variant->SetAsISupports(imageContainer);
}
// Using system principal here, since once the data is on parent process
// side, it can be handled as being from browser chrome or OS.
aDataTransfer->SetDataWithPrincipal(NS_ConvertUTF8toUTF16(item.mFlavor),
aDataTransfer->SetDataWithPrincipal(NS_ConvertUTF8toUTF16(item.flavor()),
variant, i,
nsContentUtils::GetSystemPrincipal());
}

Просмотреть файл

@ -644,19 +644,7 @@ private:
uint32_t mChromeFlags;
struct DataTransferItem
{
nsCString mFlavor;
nsString mStringData;
RefPtr<mozilla::dom::BlobImpl> mBlobData;
enum DataType
{
eString,
eBlob
};
DataType mType;
};
nsTArray<nsTArray<DataTransferItem>> mInitialDataTransferItems;
nsTArray<nsTArray<IPCDataTransferItem>> mInitialDataTransferItems;
RefPtr<gfx::DataSourceSurface> mDnDVisualization;
int32_t mDragAreaX;

Просмотреть файл

@ -2052,6 +2052,17 @@ MediaManager::GetUserMedia(nsPIDOMWindowInner* aWindow,
RemoveFromWindowList(windowID, listener);
return NS_OK;
}
} else if (loop) {
// Record that we gave Loop permission to use camera access.
nsCOMPtr<nsIPermissionManager> permManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = permManager->Add(docURI, "camera",
nsIPermissionManager::ALLOW_ACTION,
nsIPermissionManager::EXPIRE_SESSION,
0);
NS_ENSURE_SUCCESS(rv, rv);
}
#if defined(MOZ_B2G_CAMERA) && defined(MOZ_WIDGET_GONK)

Просмотреть файл

@ -137,17 +137,6 @@ GetPluginFile(const nsAString& aPluginPath,
}
#endif
static bool
GetInfoFile(const nsAString& aPluginPath,
nsCOMPtr<nsIFile>& aInfoFile)
{
nsAutoString baseName;
GetFileBase(aPluginPath, aInfoFile, baseName);
nsAutoString infoFileName = baseName + NS_LITERAL_STRING(".info");
aInfoFile->AppendRelativePath(infoFileName);
return true;
}
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
static nsCString
GetNativeTarget(nsIFile* aFile)
@ -268,14 +257,6 @@ GMPChild::Init(const nsAString& aPluginPath,
mPluginPath = aPluginPath;
mSandboxVoucherPath = aVoucherPath;
nsCOMPtr<nsIFile> infoFile;
if (!GetInfoFile(mPluginPath, infoFile) || !infoFile) {
return false;
}
if (!mInfoParser.Init(infoFile)) {
return false;
}
return true;
}
@ -300,12 +281,12 @@ GMPChild::GetAPI(const char* aAPIName, void* aHostAPI, void** aPluginAPI)
return mGMPLoader->GetAPI(aAPIName, aHostAPI, aPluginAPI);
}
#ifdef XP_WIN
// Pre-load DLLs that need to be used by the EME plugin but that can't be
// loaded after the sandbox has started
bool
GMPChild::PreLoadLibraries()
GMPChild::RecvPreloadLibs(const nsCString& aLibs)
{
#ifdef XP_WIN
// Pre-load DLLs that need to be used by the EME plugin but that can't be
// loaded after the sandbox has started
// Items in this must be lowercase!
static const char* whitelist[] = {
"d3d9.dll", // Create an `IDirect3D9` to get adapter information
@ -319,12 +300,8 @@ GMPChild::PreLoadLibraries()
"msmpeg2vdec.dll", // H.264 decoder
};
if (!mInfoParser.Contains(NS_LITERAL_CSTRING("libraries"))) {
return false;
}
nsTArray<nsCString> libs;
SplitAt(", ", mInfoParser.Get(NS_LITERAL_CSTRING("libraries")), libs);
SplitAt(", ", aLibs, libs);
for (nsCString lib : libs) {
ToLowerCase(lib);
for (const char* whiteListedLib : whitelist) {
@ -334,10 +311,9 @@ GMPChild::PreLoadLibraries()
}
}
}
#endif
return true;
}
#endif
bool
GMPChild::GetUTF8LibPath(nsACString& aOutLibPath)
@ -373,9 +349,6 @@ GMPChild::AnswerStartPlugin()
{
LOGD("%s", __FUNCTION__);
#if defined(XP_WIN)
PreLoadLibraries();
#endif
if (!PreLoadPluginVoucher()) {
NS_WARNING("Plugin voucher failed to load!");
return false;

Просмотреть файл

@ -13,7 +13,6 @@
#include "gmp-async-shutdown.h"
#include "gmp-entrypoints.h"
#include "prlink.h"
#include "GMPUtils.h"
namespace mozilla {
namespace gmp {
@ -32,9 +31,6 @@ public:
base::ProcessId aParentPid,
MessageLoop* aIOLoop,
IPC::Channel* aChannel);
#ifdef XP_WIN
bool PreLoadLibraries();
#endif
MessageLoop* GMPMessageLoop();
// Main thread only.
@ -58,6 +54,7 @@ private:
bool RecvSetNodeId(const nsCString& aNodeId) override;
bool AnswerStartPlugin() override;
bool RecvPreloadLibs(const nsCString& aLibs) override;
PCrashReporterChild* AllocPCrashReporterChild(const NativeThreadId& aThread) override;
bool DeallocPCrashReporterChild(PCrashReporterChild*) override;
@ -94,7 +91,6 @@ private:
GMPLoader* mGMPLoader;
nsTArray<uint8_t> mPluginVoucher;
nsTArray<uint8_t> mSandboxVoucher;
GMPInfoFileParser mInfoParser;
};
} // namespace gmp

Просмотреть файл

@ -162,6 +162,17 @@ GMPParent::LoadProcess()
}
LOGD("%s: Sent node id to child process", __FUNCTION__);
#ifdef XP_WIN
if (!mLibs.IsEmpty()) {
bool ok = SendPreloadLibs(mLibs);
if (!ok) {
LOGD("%s: Failed to send preload-libs to child process", __FUNCTION__);
return NS_ERROR_FAILURE;
}
LOGD("%s: Sent preload-libs ('%s') to child process", __FUNCTION__, mLibs.get());
}
#endif
// Intr call to block initialization on plugin load.
ok = CallStartPlugin();
if (!ok) {
@ -731,7 +742,7 @@ GMPParent::DeallocPGMPTimerParent(PGMPTimerParent* aActor)
}
bool
ReadRequiredField(GMPInfoFileParser& aParser, const nsCString& aKey, nsACString& aOutValue)
ReadInfoField(GMPInfoFileParser& aParser, const nsCString& aKey, nsACString& aOutValue)
{
if (!aParser.Contains(aKey) || aParser.Get(aKey).IsEmpty()) {
return false;
@ -759,13 +770,18 @@ GMPParent::ReadGMPMetaData()
}
nsAutoCString apis;
if (!ReadRequiredField(parser, NS_LITERAL_CSTRING("name"), mDisplayName) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("description"), mDescription) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("version"), mVersion) ||
!ReadRequiredField(parser, NS_LITERAL_CSTRING("apis"), apis)) {
if (!ReadInfoField(parser, NS_LITERAL_CSTRING("name"), mDisplayName) ||
!ReadInfoField(parser, NS_LITERAL_CSTRING("description"), mDescription) ||
!ReadInfoField(parser, NS_LITERAL_CSTRING("version"), mVersion) ||
!ReadInfoField(parser, NS_LITERAL_CSTRING("apis"), apis)) {
return NS_ERROR_FAILURE;
}
#ifdef XP_WIN
// "Libraries" field is optional.
ReadInfoField(parser, NS_LITERAL_CSTRING("libraries"), mLibs);
#endif
nsTArray<nsCString> apiTokens;
SplitAt(", ", apis, apiTokens);
for (nsCString api : apiTokens) {

Просмотреть файл

@ -193,6 +193,9 @@ private:
nsCString mDisplayName; // name of plugin displayed to users
nsCString mDescription; // description of plugin for display to users
nsCString mVersion;
#ifdef XP_WIN
nsCString mLibs;
#endif
uint32_t mPluginId;
nsTArray<nsAutoPtr<GMPCapability>> mCapabilities;
GMPProcessParent* mProcess;

Просмотреть файл

@ -36,6 +36,7 @@ child:
async CrashPluginNow();
intr StartPlugin();
async SetNodeId(nsCString nodeId);
async PreloadLibs(nsCString libs);
async CloseActive();
};

Просмотреть файл

@ -1,27 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// The scoped_ptr.h our IPC copy of Chromium's code does not include
// scoped_array, so adapt it to nsAutoArrayPtr here.
#ifndef FAKE_SCOPED_PTR_H_
#define FAKE_SCOPED_PTR_H_
#include "mozilla/ArrayUtils.h"
#include "nsAutoPtr.h"
template<class T>
class scoped_array : public nsAutoArrayPtr<T> {
public:
scoped_array(T* t) : nsAutoArrayPtr<T>(t) {}
void reset(T* t) {
scoped_array<T> other(t);
this->operator=(other);
}
};
#define arraysize mozilla::ArrayLength
#endif

Просмотреть файл

@ -6,8 +6,8 @@
#include <sddl.h> // For ConvertSidToStringSidW.
#include <string>
#include <vector>
#include "mozilla/ArrayUtils.h"
#include "base/memory/scoped_ptr.h"
#include "rlz/lib/assert.h"
namespace rlz_lib {
@ -41,13 +41,13 @@ bool GetSystemVolumeSerialNumber(int* number) {
bool GetComputerSid(const wchar_t* account_name, SID* sid, DWORD sid_size) {
static const DWORD kStartDomainLength = 128; // reasonable to start with
scoped_array<wchar_t> domain_buffer(new wchar_t[kStartDomainLength]);
std::vector<wchar_t> domain_buffer(kStartDomainLength, 0);
DWORD domain_size = kStartDomainLength;
DWORD sid_dword_size = sid_size;
SID_NAME_USE sid_name_use;
BOOL success = ::LookupAccountNameW(NULL, account_name, sid,
&sid_dword_size, domain_buffer.get(),
&sid_dword_size, &domain_buffer.front(),
&domain_size, &sid_name_use);
if (!success && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
// We could have gotten the insufficient buffer error because
@ -57,10 +57,10 @@ bool GetComputerSid(const wchar_t* account_name, SID* sid, DWORD sid_size) {
return false;
if (domain_size > kStartDomainLength)
domain_buffer.reset(new wchar_t[domain_size]);
domain_buffer.resize(domain_size);
success = ::LookupAccountNameW(NULL, account_name, sid, &sid_dword_size,
domain_buffer.get(), &domain_size,
&domain_buffer.front(), &domain_size,
&sid_name_use);
}
@ -110,7 +110,7 @@ bool GetRawMachineId(std::vector<uint8_t>* sid_bytes, int* volume_id) {
// Calculate the Windows SID.
wchar_t computer_name[MAX_COMPUTERNAME_LENGTH + 1] = {0};
DWORD size = arraysize(computer_name);
DWORD size = mozilla::ArrayLength(computer_name);
if (!GetComputerNameW(computer_name, &size)) {
return false;

Просмотреть файл

@ -1084,20 +1084,16 @@ Notification::ConstructFromFields(
{
MOZ_ASSERT(aGlobal);
AutoJSAPI jsapi;
DebugOnly<bool> ok = jsapi.Init(aGlobal);
MOZ_ASSERT(ok);
RootedDictionary<NotificationOptions> options(jsapi.cx());
RootedDictionary<NotificationOptions> options(nsContentUtils::RootingCxForThread());
options.mDir = Notification::StringToDirection(nsString(aDir));
options.mLang = aLang;
options.mBody = aBody;
options.mTag = aTag;
options.mIcon = aIcon;
RefPtr<Notification> notification = CreateInternal(aGlobal, aID, aTitle,
options);
options);
notification->InitFromBase64(jsapi.cx(), aData, aRv);
notification->InitFromBase64(aData, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return nullptr;
}
@ -2341,8 +2337,7 @@ Notification::GetData(JSContext* aCx,
nsresult rv;
RefPtr<nsStructuredCloneContainer> container =
new nsStructuredCloneContainer();
rv = container->InitFromBase64(mDataAsBase64, JS_STRUCTURED_CLONE_VERSION,
aCx);
rv = container->InitFromBase64(mDataAsBase64, JS_STRUCTURED_CLONE_VERSION);
if (NS_WARN_IF(NS_FAILED(rv))) {
aRetval.setNull();
return;
@ -2386,8 +2381,7 @@ Notification::InitFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aData,
dataObjectContainer->GetDataAsBase64(mDataAsBase64);
}
void Notification::InitFromBase64(JSContext* aCx, const nsAString& aData,
ErrorResult& aRv)
void Notification::InitFromBase64(const nsAString& aData, ErrorResult& aRv)
{
if (!mDataAsBase64.IsEmpty() || aData.IsEmpty()) {
return;
@ -2396,8 +2390,7 @@ void Notification::InitFromBase64(JSContext* aCx, const nsAString& aData,
// To and fro to ensure it is valid base64.
RefPtr<nsStructuredCloneContainer> container =
new nsStructuredCloneContainer();
aRv = container->InitFromBase64(aData, JS_STRUCTURED_CLONE_VERSION,
aCx);
aRv = container->InitFromBase64(aData, JS_STRUCTURED_CLONE_VERSION);
if (NS_WARN_IF(aRv.Failed())) {
return;
}

Просмотреть файл

@ -279,7 +279,7 @@ public:
void InitFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aData, ErrorResult& aRv);
void InitFromBase64(JSContext* aCx, const nsAString& aData, ErrorResult& aRv);
void InitFromBase64(const nsAString& aData, ErrorResult& aRv);
void AssertIsOnTargetThread() const
{

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for B2G PresentationReceiver on a non-receiver inner iframe of the receiver page at receiver side (OOP)</title>
</head>
<body onload="testConnectionAvailable()">
<div id="content"></div>
<script type="application/javascript;version=1.7">
"use strict";
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
}
function testConnectionAvailable() {
return new Promise(function(aResolve, aReject) {
ok(!navigator.presentation, "navigator.presentation shouldn't be available in inner iframes with different origins from receiving OOP pages.");
aResolve();
});
}
</script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for B2G PresentationReceiver in an inner iframe of the receiver page at receiver side (OOP)</title>
</head>
<body onload="testConnectionAvailable()">
<div id="content"></div>
<script type="application/javascript;version=1.7">
"use strict";
function ok(a, msg) {
alert((a ? 'OK ' : 'KO ') + msg);
}
function testConnectionAvailable() {
return new Promise(function(aResolve, aReject) {
ok(navigator.presentation, "navigator.presentation should be available in same-origin inner iframes of receiving OOP pages.");
aResolve();
});
}
</script>
</body>
</html>

Просмотреть файл

@ -54,7 +54,7 @@ function testConnectionAvailable() {
});
}
function testConnectionAvailableInnerIframe() {
function testConnectionAvailableSameOriginInnerIframe() {
return new Promise(function(aResolve, aReject) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', './file_presentation_receiver_inner_iframe_oop.html');
@ -64,6 +64,16 @@ function testConnectionAvailableInnerIframe() {
});
}
function testConnectionUnavailableDiffOriginInnerIframe() {
return new Promise(function(aResolve, aReject) {
var iframe = document.createElement('iframe');
iframe.setAttribute('src', 'http://example.com/tests/dom/presentation/tests/mochitest/file_presentation_non_receiver_inner_iframe_oop.html');
document.body.appendChild(iframe);
aResolve();
});
}
function testConnectionReady() {
return new Promise(function(aResolve, aReject) {
connection.onstatechange = function() {
@ -104,7 +114,11 @@ function testTerminateConnection() {
}
testConnectionAvailable().
then(testConnectionAvailableInnerIframe).
// TODO Bug 1234128 - Fix the timing issue for navigator.presentation.receiver.
// This test fails intermittently under some edge cases. Disable it for now until
// the issue gets fixed.
// then(testConnectionAvailableSameOriginInnerIframe).
then(testConnectionUnavailableDiffOriginInnerIframe).
then(testConnectionReady).
then(testIncomingMessage).
then(testTerminateConnection).

Просмотреть файл

@ -6,6 +6,8 @@ support-files =
file_presentation_receiver_oop.html
file_presentation_non_receiver_oop.html
file_presentation_receiver_establish_connection_error.html
file_presentation_receiver_inner_iframe_oop.html
file_presentation_non_receiver_inner_iframe_oop.html
[test_presentation_device_info.html]
[test_presentation_device_info_permission.html]

Просмотреть файл

@ -404,10 +404,20 @@ this.PushDB.prototype = {
aKeyID, newRecord);
return;
}
aStore.put(newRecord).onsuccess = aEvent => {
console.debug("update: Update successful", aKeyID, newRecord);
aTxn.result = newRecord;
};
function putRecord() {
let req = aStore.put(newRecord);
req.onsuccess = aEvent => {
console.debug("update: Update successful", aKeyID, newRecord);
aTxn.result = newRecord;
};
}
if (aKeyID === newRecord.keyID) {
putRecord();
} else {
// If we changed the primary key, delete the old record to avoid
// unique constraint errors.
aStore.delete(aKeyID).onsuccess = putRecord;
}
};
},
resolve,

Просмотреть файл

@ -39,14 +39,21 @@ function handleRequest(request, response)
data.push(bodyStream.readByteArray(available));
size += available;
}
xhr.send(concatUint8Arrays(data, size));
function reply(statusCode, statusText) {
response.setStatusLine(request.httpVersion, statusCode, statusText);
response.finish();
}
xhr.onload = function(e) {
debug("xhr : " + this.status);
}
reply(this.status, this.statusText);
};
xhr.onerror = function(e) {
debug("xhr error: " + e);
}
reply(500, "Internal Server Error");
};
response.setStatusLine(request.httpVersion, "200", "OK");
response.processAsync();
xhr.send(concatUint8Arrays(data, size));
}

Просмотреть файл

@ -107,7 +107,7 @@ http://creativecommons.org/licenses/publicdomain/
function waitForMessage(pushSubscription, message) {
return Promise.all([
controlledFrame.waitOnWorkerMessage("finished"),
webpush(pushSubscription, message),
webpush(pushSubscription, message, 120),
]).then(([message]) => message);
}
@ -167,6 +167,7 @@ http://creativecommons.org/licenses/publicdomain/
headers: {
"X-Push-Method": "POST",
"X-Push-Server": pushSubscription.endpoint,
"TTL": "120",
},
}),
]);

Просмотреть файл

@ -71,6 +71,7 @@ http://creativecommons.org/licenses/publicdomain/
headers: {
"X-Push-Method": "POST",
"X-Push-Server": pushSubscription.endpoint,
"TTL": "120",
},
}),
]);

Просмотреть файл

@ -75,9 +75,10 @@
// Work around CORS for now.
var xhr = new XMLHttpRequest();
xhr.open('GET', "http://mochi.test:8888/tests/dom/push/test/push-server.sjs", true);
xhr.setRequestHeader("X-Push-Method", "PUT");
xhr.setRequestHeader("X-Push-Method", "POST");
xhr.setRequestHeader("X-Push-Server", pushEndpoint);
xhr.send("version=24601");
xhr.setRequestHeader("TTL", "120");
xhr.send(null);
}
function unregisterPushNotification(ctx) {

Просмотреть файл

@ -169,7 +169,7 @@
* parameters.
* @param data The message to send.
*/
function webpush(subscription, data) {
function webpush(subscription, data, ttl) {
data = ensureView(data);
var salt = g.crypto.getRandomValues(new Uint8Array(16));
@ -189,13 +189,14 @@
'X-Push-Method': 'POST',
'Encryption-Key': 'keyid=p256dh;dh=' + base64url.encode(pubkey),
Encryption: 'keyid=p256dh;salt=' + base64url.encode(salt),
'Content-Encoding': 'aesgcm128'
'Content-Encoding': 'aesgcm128',
'TTL': ttl,
},
body: payload,
};
return fetch('http://mochi.test:8888/tests/dom/push/test/push-server.sjs', options);
}).then(response => {
if (response.status / 100 !== 2) {
if (Math.floor(response.status / 100) !== 2) {
throw new Error('Unable to deliver message');
}
return response;

Просмотреть файл

@ -14,15 +14,18 @@ XPCOMUtils.defineLazyGetter(this, "serverPort", function() {
return httpServer.identity.primaryPort;
});
var handlerDone;
var handlerPromise = new Promise(r => handlerDone = after(3, r));
function listen4xxCodeHandler(metadata, response) {
ok(true, "Listener point error")
do_test_finished();
handlerDone();
response.setStatusLine(metadata.httpVersion, 410, "GONE");
}
function resubscribeHandler(metadata, response) {
ok(true, "Ask for new subscription");
do_test_finished();
handlerDone();
response.setHeader("Location",
'http://localhost:' + serverPort + '/newSubscription')
response.setHeader("Link",
@ -33,7 +36,7 @@ function resubscribeHandler(metadata, response) {
function listenSuccessHandler(metadata, response) {
do_check_true(true, "New listener point");
httpServer.stop(do_test_finished);
httpServer.stop(handlerDone);
response.setStatusLine(metadata.httpVersion, 204, "Try again");
}
@ -61,10 +64,6 @@ add_task(function* test1() {
return db.drop().then(_ => db.close());
});
do_test_pending();
do_test_pending();
do_test_pending();
var serverURL = "http://localhost:" + httpServer.identity.primaryPort;
let records = [{
@ -85,4 +84,17 @@ add_task(function* test1() {
db
});
yield handlerPromise;
let record = yield db.getByIdentifiers({
scope: 'https://example.com/page',
originAttributes: '',
});
equal(record.keyID, serverURL + '/newSubscription',
'Should update subscription URL');
equal(record.pushEndpoint, serverURL + '/newPushEndpoint',
'Should update push endpoint');
equal(record.pushReceiptEndpoint, serverURL + '/newReceiptPushEndpoint',
'Should update push receipt endpoint');
});

Просмотреть файл

@ -14,11 +14,13 @@ XPCOMUtils.defineLazyGetter(this, "serverPort", function() {
return httpServer.identity.primaryPort;
});
var retries = 0
var retries = 0;
var handlerDone;
var handlerPromise = new Promise(r => handlerDone = after(5, r));
function listen5xxCodeHandler(metadata, response) {
ok(true, "Listener 5xx code");
do_test_finished();
handlerDone();
retries++;
response.setHeader("Retry-After", '1');
response.setStatusLine(metadata.httpVersion, 500, "Retry");
@ -27,7 +29,7 @@ function listen5xxCodeHandler(metadata, response) {
function resubscribeHandler(metadata, response) {
ok(true, "Ask for new subscription");
ok(retries == 3, "Should retry 2 times.");
do_test_finished();
handlerDone();
response.setHeader("Location",
'http://localhost:' + serverPort + '/newSubscription')
response.setHeader("Link",
@ -38,7 +40,7 @@ function resubscribeHandler(metadata, response) {
function listenSuccessHandler(metadata, response) {
do_check_true(true, "New listener point");
httpServer.stop(do_test_finished);
httpServer.stop(handlerDone);
response.setStatusLine(metadata.httpVersion, 204, "Try again");
}
@ -67,12 +69,6 @@ add_task(function* test1() {
return db.drop().then(_ => db.close());
});
do_test_pending();
do_test_pending();
do_test_pending();
do_test_pending();
do_test_pending();
var serverURL = "http://localhost:" + httpServer.identity.primaryPort;
let records = [{
@ -93,4 +89,17 @@ add_task(function* test1() {
db
});
yield handlerPromise;
let record = yield db.getByIdentifiers({
scope: 'https://example.com/page',
originAttributes: '',
});
equal(record.keyID, serverURL + '/newSubscription',
'Should update subscription URL');
equal(record.pushEndpoint, serverURL + '/newPushEndpoint',
'Should update push endpoint');
equal(record.pushReceiptEndpoint, serverURL + '/newReceiptPushEndpoint',
'Should update push receipt endpoint');
});

Просмотреть файл

@ -14,9 +14,12 @@ XPCOMUtils.defineLazyGetter(this, "serverPort", function() {
return httpServer.identity.primaryPort;
});
var handlerDone;
var handlerPromise = new Promise(r => handlerDone = after(2, r));
function resubscribeHandler(metadata, response) {
ok(true, "Ask for new subscription");
do_test_finished();
handlerDone();
response.setHeader("Location",
'http://localhost:' + serverPort + '/newSubscription')
response.setHeader("Link",
@ -27,7 +30,7 @@ function resubscribeHandler(metadata, response) {
function listenSuccessHandler(metadata, response) {
do_check_true(true, "New listener point");
httpServer.stop(do_test_finished);
httpServer.stop(handlerDone);
response.setStatusLine(metadata.httpVersion, 204, "Try again");
}
@ -55,9 +58,6 @@ add_task(function* test1() {
return db.drop().then(_ => db.close());
});
do_test_pending();
do_test_pending();
var serverURL = "http://localhost:" + httpServer.identity.primaryPort;
let records = [{
@ -88,4 +88,17 @@ add_task(function* test1() {
db
});
yield handlerPromise;
let record = yield db.getByIdentifiers({
scope: 'https://example.com/page',
originAttributes: '',
});
equal(record.keyID, serverURL + '/newSubscription',
'Should update subscription URL');
equal(record.pushEndpoint, serverURL + '/newPushEndpoint',
'Should update push endpoint');
equal(record.pushReceiptEndpoint, serverURL + '/newReceiptPushEndpoint',
'Should update push receipt endpoint');
});

Просмотреть файл

@ -40,6 +40,7 @@ namespace {
static const char* gSupportedRegistrarVersions[] = {
SERVICEWORKERREGISTRAR_VERSION,
"3",
"2"
};
@ -330,6 +331,7 @@ ServiceWorkerRegistrar::ReadData()
nsTArray<ServiceWorkerRegistrationData> tmpData;
bool overwrite = false;
bool dedupe = false;
while (hasMoreLines) {
ServiceWorkerRegistrationData* entry = tmpData.AppendElement();
@ -343,6 +345,7 @@ ServiceWorkerRegistrar::ReadData()
}
nsAutoCString line;
nsAutoCString unused;
if (version.EqualsLiteral(SERVICEWORKERREGISTRAR_VERSION)) {
nsAutoCString suffix;
GET_LINE(suffix);
@ -352,18 +355,19 @@ ServiceWorkerRegistrar::ReadData()
return NS_ERROR_INVALID_ARG;
}
GET_LINE(line);
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, line);
GET_LINE(entry->scope());
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
GET_LINE(entry->currentWorkerURL());
nsAutoCString cacheName;
GET_LINE(cacheName);
CopyUTF8toUTF16(cacheName, entry->cacheName());
} else if (version.EqualsLiteral("2")) {
} else if (version.EqualsLiteral("3")) {
overwrite = true;
dedupe = true;
nsAutoCString suffix;
GET_LINE(suffix);
@ -373,14 +377,40 @@ ServiceWorkerRegistrar::ReadData()
return NS_ERROR_INVALID_ARG;
}
GET_LINE(line);
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, line);
// principal spec is no longer used; we use scope directly instead
GET_LINE(unused);
GET_LINE(entry->scope());
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
GET_LINE(entry->currentWorkerURL());
nsAutoCString cacheName;
GET_LINE(cacheName);
CopyUTF8toUTF16(cacheName, entry->cacheName());
} else if (version.EqualsLiteral("2")) {
overwrite = true;
dedupe = true;
nsAutoCString suffix;
GET_LINE(suffix);
PrincipalOriginAttributes attrs;
if (!attrs.PopulateFromSuffix(suffix)) {
return NS_ERROR_INVALID_ARG;
}
// principal spec is no longer used; we use scope directly instead
GET_LINE(unused);
GET_LINE(entry->scope());
entry->principal() =
mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());
// scriptSpec is no more used in latest version.
nsAutoCString unused;
GET_LINE(unused);
GET_LINE(entry->currentWorkerURL());
@ -409,22 +439,32 @@ ServiceWorkerRegistrar::ReadData()
stream->Close();
// Dedupe data in file. Old profiles had many duplicates. In theory
// we can remove this in the future. (Bug 1248449)
// Copy data over to mData.
for (uint32_t i = 0; i < tmpData.Length(); ++i) {
bool match = false;
for (uint32_t j = 0; j < mData.Length(); ++j) {
// Use same comparison as RegisterServiceWorker. Scope contains
// basic origin information. Combine with any principal attributes.
if (Equivalent(tmpData[i], mData[j])) {
// Last match wins, just like legacy loading used to do in
// the ServiceWorkerManager.
mData[j] = tmpData[i];
// Dupe found, so overwrite file with reduced list.
overwrite = true;
match = true;
break;
if (dedupe) {
MOZ_ASSERT(overwrite);
// If this is an old profile, then we might need to deduplicate. In
// theory this can be removed in the future (Bug 1248449)
for (uint32_t j = 0; j < mData.Length(); ++j) {
// Use same comparison as RegisterServiceWorker. Scope contains
// basic origin information. Combine with any principal attributes.
if (Equivalent(tmpData[i], mData[j])) {
// Last match wins, just like legacy loading used to do in
// the ServiceWorkerManager.
mData[j] = tmpData[i];
// Dupe found, so overwrite file with reduced list.
match = true;
break;
}
}
} else {
#ifdef DEBUG
// Otherwise assert no duplications in debug builds.
for (uint32_t j = 0; j < mData.Length(); ++j) {
MOZ_ASSERT(!Equivalent(tmpData[i], mData[j]));
}
#endif
}
if (!match) {
mData.AppendElement(tmpData[i]);
@ -647,9 +687,6 @@ ServiceWorkerRegistrar::WriteData()
buffer.Append(suffix.get());
buffer.Append('\n');
buffer.Append(cInfo.spec());
buffer.Append('\n');
buffer.Append(data[i].scope());
buffer.Append('\n');

Просмотреть файл

@ -16,7 +16,7 @@
#include "nsTArray.h"
#define SERVICEWORKERREGISTRAR_FILE "serviceworker.txt"
#define SERVICEWORKERREGISTRAR_VERSION "3"
#define SERVICEWORKERREGISTRAR_VERSION "4"
#define SERVICEWORKERREGISTRAR_TERMINATOR "#"
#define SERVICEWORKERREGISTRAR_TRUE "true"
#define SERVICEWORKERREGISTRAR_FALSE "false"

Просмотреть файл

@ -30,16 +30,6 @@ const nsIID kWorkerRunnableIID = {
0x320cc0b5, 0xef12, 0x4084, { 0x88, 0x6e, 0xca, 0x6a, 0x81, 0xe4, 0x1d, 0x68 }
};
void
MaybeReportMainThreadException(JSContext* aCx, bool aResult)
{
AssertIsOnMainThread();
if (aCx && !aResult) {
JS_ReportPendingException(aCx);
}
}
} // namespace
#ifdef DEBUG
@ -421,7 +411,15 @@ WorkerDebuggerRunnable::PostDispatch(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
MaybeReportMainThreadException(aCx, aDispatchResult);
// The only way aDispatchResult can be false here is if either PreDispatch or
// DispatchInternal returned false.
//
// Our PreDispatch always returns true and is final. We inherit
// DispatchInternal from WorkerRunnable and don't allow overriding it in our
// subclasses. WorkerRunnable::DispatchInternal only fails if one of its
// runnable dispatching functions fails, and none of those cases can throw a
// JS exception. So we can never have a JS exception here.
MOZ_ASSERT_IF(aCx, !JS_IsExceptionPending(aCx));
}
WorkerSyncRunnable::WorkerSyncRunnable(WorkerPrivate* aWorkerPrivate,
@ -469,7 +467,18 @@ MainThreadWorkerSyncRunnable::PostDispatch(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
MaybeReportMainThreadException(aCx, aDispatchResult);
// The only way aDispatchResult can be false here is if either PreDispatch or
// DispatchInternal returned false.
//
// Our PreDispatch always returns true and is final. We inherit
// DispatchInternal from WorkerSyncRunnable and don't allow overriding it in
// our subclasses. WorkerSyncRunnable::DispatchInternal only returns false if
// if dispatch to the syncloop target fails or if calling up to
// WorkerRunnable::DispatchInternal fails. WorkerRunnable::DispatchInternal
// only fails if one of its runnable dispatching functions fails, and none of
// those cases can throw a JS exception. So we can never have a JS exception
// here.
MOZ_ASSERT_IF(aCx, !JS_IsExceptionPending(aCx));
}
StopSyncLoopRunnable::StopSyncLoopRunnable(
@ -527,7 +536,14 @@ MainThreadStopSyncLoopRunnable::PostDispatch(JSContext* aCx,
WorkerPrivate* aWorkerPrivate,
bool aDispatchResult)
{
MaybeReportMainThreadException(aCx, aDispatchResult);
// The only way aDispatchResult can be false here is if either PreDispatch or
// DispatchInternal returned false.
//
// Our PreDispatch always returns true and is final. We inherit
// DispatchInternal from StopSyncLoopRunnable, and that itself is final and
// only returns false if dispatch to the syncloop target fails. So we can
// never have a JS exception here.
MOZ_ASSERT_IF(aCx, !JS_IsExceptionPending(aCx));
}
#ifdef DEBUG

Просмотреть файл

@ -185,13 +185,22 @@ private:
}
virtual bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override final
{
AssertIsOnMainThread();
return true;
}
// We want to be able to assert in PostDispatch that no exceptions were thrown
// on aCx. We can do that if we know no one is subclassing our
// DispatchInternal to do weird things.
virtual bool
DispatchInternal() override final
{
return WorkerRunnable::DispatchInternal();
}
virtual void
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) override;
@ -213,7 +222,6 @@ protected:
virtual ~WorkerSyncRunnable();
private:
virtual bool
DispatchInternal() override;
};
@ -242,14 +250,34 @@ protected:
virtual ~MainThreadWorkerSyncRunnable()
{ }
// Hook for subclasses that want to override our PreDispatch. This override
// must be infallible and must not leave an exception hanging out on the
// JSContext. We pass the JSContext through so callees that expect to be able
// to do something with script have a way to do it. We'd pass an AutoJSAPI,
// but some of our subclasses are dispatched with a null JSContext*, so we
// can't do that sort of thing ourselves.
virtual void InfalliblePreDispatch(JSContext* aCx)
{}
private:
virtual bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override final
{
AssertIsOnMainThread();
InfalliblePreDispatch(aCx);
MOZ_ASSERT_IF(aCx, !JS_IsExceptionPending(aCx));
return true;
}
// We want to be able to assert in PostDispatch that no exceptions were thrown
// on aCx. We can do that if we know no one is subclassing our
// DispatchInternal to do weird things.
virtual bool
DispatchInternal() override final
{
return WorkerSyncRunnable::DispatchInternal();
}
virtual void
PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) override;
@ -286,8 +314,10 @@ private:
virtual bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
// If this stops being final, reevaluate the assumptions
// MainThreadWorkerSyncRunnable::PostDispatch makes.
virtual bool
DispatchInternal() override;
DispatchInternal() override final;
};
// This runnable is identical to StopSyncLoopRunnable except it is meant to be
@ -310,8 +340,10 @@ protected:
{ }
private:
// If this function stops being final, reevaluate the assumptions PostDispatch
// makes.
virtual bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override final
{
AssertIsOnMainThread();
return true;

Просмотреть файл

@ -591,8 +591,8 @@ private:
~EventRunnable()
{ }
virtual bool
PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
virtual void
InfalliblePreDispatch(JSContext* aCx) override final;
virtual bool
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
@ -1170,10 +1170,19 @@ LoadStartDetectionRunnable::HandleEvent(nsIDOMEvent* aEvent)
return NS_OK;
}
bool
EventRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
void
EventRunnable::InfalliblePreDispatch(JSContext* aCx)
{
AssertIsOnMainThread();
MOZ_ASSERT(aCx);
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
AutoJSAPI jsapi;
DebugOnly<bool> ok =
jsapi.Init(xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx)), aCx);
MOZ_ASSERT(ok);
MOZ_ASSERT(jsapi.cx() == aCx);
jsapi.TakeOwnershipOfErrorReporting();
RefPtr<nsXMLHttpRequest>& xhr = mProxy->mXHR;
MOZ_ASSERT(xhr);
@ -1244,8 +1253,6 @@ EventRunnable::PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
mReadyState = xhr->ReadyState();
xhr->GetResponseURL(mResponseURL);
return true;
}
bool

Просмотреть файл

@ -142,11 +142,11 @@ TEST(ServiceWorkerRegistrar, TestReadData)
nsAutoCString buffer(SERVICEWORKERREGISTRAR_VERSION "\n");
buffer.Append("^appId=123&inBrowser=1\n");
buffer.Append("spec 0\nscope 0\ncurrentWorkerURL 0\ncacheName 0\n");
buffer.Append("scope 0\ncurrentWorkerURL 0\ncacheName 0\n");
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
buffer.Append("\n");
buffer.Append("spec 1\nscope 1\ncurrentWorkerURL 1\ncacheName 1\n");
buffer.Append("scope 1\ncurrentWorkerURL 1\ncacheName 1\n");
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
@ -167,7 +167,7 @@ TEST(ServiceWorkerRegistrar, TestReadData)
cInfo0.attrs().CreateSuffix(suffix0);
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
ASSERT_STREQ("spec 0", cInfo0.spec().get());
ASSERT_STREQ("scope 0", cInfo0.spec().get());
ASSERT_STREQ("scope 0", data[0].scope().get());
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
@ -180,7 +180,7 @@ TEST(ServiceWorkerRegistrar, TestReadData)
cInfo1.attrs().CreateSuffix(suffix1);
ASSERT_STREQ("", suffix1.get());
ASSERT_STREQ("spec 1", cInfo1.spec().get());
ASSERT_STREQ("scope 1", cInfo1.spec().get());
ASSERT_STREQ("scope 1", data[1].scope().get());
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
@ -246,7 +246,7 @@ TEST(ServiceWorkerRegistrar, TestWriteData)
ASSERT_STREQ(expectSuffix.get(), suffix.get());
test.AppendPrintf("spec write %d", i);
test.AppendPrintf("scope write %d", i);
ASSERT_STREQ(test.get(), cInfo.spec().get());
test.Truncate();
@ -283,7 +283,7 @@ TEST(ServiceWorkerRegistrar, TestVersion2Migration)
ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail";
const nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
ASSERT_EQ((uint32_t)2, data.Length()) << "4 entries should be found";
ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found";
const mozilla::ipc::PrincipalInfo& info0 = data[0].principal();
ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
@ -293,7 +293,7 @@ TEST(ServiceWorkerRegistrar, TestVersion2Migration)
cInfo0.attrs().CreateSuffix(suffix0);
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
ASSERT_STREQ("spec 0", cInfo0.spec().get());
ASSERT_STREQ("scope 0", cInfo0.spec().get());
ASSERT_STREQ("scope 0", data[0].scope().get());
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
ASSERT_STREQ("activeCache 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
@ -306,15 +306,64 @@ TEST(ServiceWorkerRegistrar, TestVersion2Migration)
cInfo1.attrs().CreateSuffix(suffix1);
ASSERT_STREQ("", suffix1.get());
ASSERT_STREQ("spec 1", cInfo1.spec().get());
ASSERT_STREQ("scope 1", cInfo1.spec().get());
ASSERT_STREQ("scope 1", data[1].scope().get());
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
ASSERT_STREQ("activeCache 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
}
TEST(ServiceWorkerRegistrar, TestVersion3Migration)
{
nsAutoCString buffer("3" "\n");
buffer.Append("^appId=123&inBrowser=1\n");
buffer.Append("spec 0\nscope 0\ncurrentWorkerURL 0\ncacheName 0\n");
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
buffer.Append("\n");
buffer.Append("spec 1\nscope 1\ncurrentWorkerURL 1\ncacheName 1\n");
buffer.Append(SERVICEWORKERREGISTRAR_TERMINATOR "\n");
ASSERT_TRUE(CreateFile(buffer)) << "CreateFile should not fail";
RefPtr<ServiceWorkerRegistrarTest> swr = new ServiceWorkerRegistrarTest;
nsresult rv = swr->TestReadData();
ASSERT_EQ(NS_OK, rv) << "ReadData() should not fail";
const nsTArray<ServiceWorkerRegistrationData>& data = swr->TestGetData();
ASSERT_EQ((uint32_t)2, data.Length()) << "2 entries should be found";
const mozilla::ipc::PrincipalInfo& info0 = data[0].principal();
ASSERT_EQ(info0.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
const mozilla::ipc::ContentPrincipalInfo& cInfo0 = data[0].principal();
nsAutoCString suffix0;
cInfo0.attrs().CreateSuffix(suffix0);
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
ASSERT_STREQ("scope 0", cInfo0.spec().get());
ASSERT_STREQ("scope 0", data[0].scope().get());
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
const mozilla::ipc::PrincipalInfo& info1 = data[1].principal();
ASSERT_EQ(info1.type(), mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) << "First principal must be content";
const mozilla::ipc::ContentPrincipalInfo& cInfo1 = data[1].principal();
nsAutoCString suffix1;
cInfo1.attrs().CreateSuffix(suffix1);
ASSERT_STREQ("", suffix1.get());
ASSERT_STREQ("scope 1", cInfo1.spec().get());
ASSERT_STREQ("scope 1", data[1].scope().get());
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());
}
TEST(ServiceWorkerRegistrar, TestDedupe)
{
nsAutoCString buffer(SERVICEWORKERREGISTRAR_VERSION "\n");
nsAutoCString buffer("3" "\n");
// unique entries
buffer.Append("^appId=123&inBrowser=1\n");
@ -356,7 +405,7 @@ TEST(ServiceWorkerRegistrar, TestDedupe)
cInfo0.attrs().CreateSuffix(suffix0);
ASSERT_STREQ("^appId=123&inBrowser=1", suffix0.get());
ASSERT_STREQ("spec 2", cInfo0.spec().get());
ASSERT_STREQ("scope 0", cInfo0.spec().get());
ASSERT_STREQ("scope 0", data[0].scope().get());
ASSERT_STREQ("currentWorkerURL 0", data[0].currentWorkerURL().get());
ASSERT_STREQ("cacheName 0", NS_ConvertUTF16toUTF8(data[0].cacheName()).get());
@ -369,7 +418,7 @@ TEST(ServiceWorkerRegistrar, TestDedupe)
cInfo1.attrs().CreateSuffix(suffix1);
ASSERT_STREQ("", suffix1.get());
ASSERT_STREQ("spec 3", cInfo1.spec().get());
ASSERT_STREQ("scope 1", cInfo1.spec().get());
ASSERT_STREQ("scope 1", data[1].scope().get());
ASSERT_STREQ("currentWorkerURL 1", data[1].currentWorkerURL().get());
ASSERT_STREQ("cacheName 1", NS_ConvertUTF16toUTF8(data[1].cacheName()).get());

Просмотреть файл

@ -613,7 +613,8 @@ DrawTargetCairo::~DrawTargetCairo()
bool
DrawTargetCairo::IsValid() const
{
return mSurface && !cairo_surface_status(mSurface) && !cairo_surface_status(cairo_get_group_target(mContext));
return mSurface && !cairo_surface_status(mSurface) &&
mContext && !cairo_surface_status(cairo_get_group_target(mContext));
}
DrawTargetType
@ -1287,6 +1288,10 @@ DrawTargetCairo::FillGlyphs(ScaledFont *aFont,
return;
}
if (!aFont) {
gfxDevCrash(LogReason::InvalidFont) << "Invalid scaled font";
}
AutoPrepareForDrawing prep(this, mContext);
AutoClearDeviceOffset clear(aPattern);

Просмотреть файл

@ -77,6 +77,14 @@ JobScheduler::SubmitJob(Job* aJob)
GetQueueForJob(aJob)->SubmitJob(aJob);
}
void
JobScheduler::Join(SyncObject* aCompletion)
{
RefPtr<EventObject> waitForCompletion = new EventObject();
JobScheduler::SubmitJob(new SetEventJob(waitForCompletion, aCompletion));
waitForCompletion->Wait();
}
MultiThreadedJobQueue*
JobScheduler::GetQueueForJob(Job* aJob)
{

Просмотреть файл

@ -71,6 +71,12 @@ public:
/// The caller looses ownership of the task buffer.
static void SubmitJob(Job* aJobs);
/// Convenience function to block the current thread until a given SyncObject
/// is in the signaled state.
///
/// The current thread will first try to steal jobs before blocking.
static void Join(SyncObject* aCompletionSync);
/// Process commands until the command buffer needs to block on a sync object,
/// completes, yields, or encounters an error.
///

Просмотреть файл

@ -131,6 +131,7 @@ enum class LogReason : int {
InvalidRect,
CannotDraw3D, // 20
IncompatibleBasicTexturedEffect,
InvalidFont,
// End
MustBeLessThanThis = 101,
};

Просмотреть файл

@ -6,7 +6,6 @@
#ifdef MOZ_WIDGET_ANDROID
#include <set>
#include <map>
#include <android/log.h>
#include "AndroidSurfaceTexture.h"
@ -27,9 +26,57 @@ using namespace mozilla::widget::sdk;
namespace mozilla {
namespace gl {
// UGH
static std::map<int, AndroidSurfaceTexture*> sInstances;
static int sNextID = 0;
// Maintains a mapping between AndroidSurfaceTexture instances and their
// unique numerical IDs. [thread-safe]
class InstanceMap
{
typedef AndroidSurfaceTexture* InstancePtr;
typedef std::map<int, InstancePtr> MapType;
public:
InstanceMap()
: mNextId(0)
, mMonitor("AndroidSurfaceTexture::InstanceMap::mMonitor")
{}
int Add(InstancePtr aInstance)
{
MonitorAutoLock lock(mMonitor);
mInstances.insert({++mNextId, aInstance});
return mNextId;
}
void Remove(int aId)
{
MonitorAutoLock lock(mMonitor);
mInstances.erase(aId);
}
InstancePtr Get(int aId) const
{
MonitorAutoLock lock(mMonitor);
auto it = mInstances.find(aId);
if (it == mInstances.end()) {
return nullptr;
}
return it->second;
}
private:
MapType mInstances;
int mNextId;
mutable Monitor mMonitor;
};
static InstanceMap sInstances;
AndroidSurfaceTexture*
AndroidSurfaceTexture::Find(int aId)
{
return sInstances.Get(aId);
}
static bool
IsSTSupported()
@ -59,19 +106,6 @@ AndroidSurfaceTexture::Create(GLContext* aContext, GLuint aTexture)
return st.forget();
}
AndroidSurfaceTexture*
AndroidSurfaceTexture::Find(int id)
{
std::map<int, AndroidSurfaceTexture*>::iterator it;
it = sInstances.find(id);
if (it == sInstances.end())
return nullptr;
return it->second;
}
nsresult
AndroidSurfaceTexture::Attach(GLContext* aContext, PRIntervalTime aTimeout)
{
@ -170,8 +204,7 @@ AndroidSurfaceTexture::Init(GLContext* aContext, GLuint aTexture)
mSurface.Get());
MOZ_ASSERT(mNativeWindow, "Failed to create native window from surface");
mID = ++sNextID;
sInstances.insert(std::pair<int, AndroidSurfaceTexture*>(mID, this));
mID = sInstances.Add(this);
return true;
}
@ -180,15 +213,15 @@ AndroidSurfaceTexture::AndroidSurfaceTexture()
: mTexture(0)
, mSurfaceTexture()
, mSurface()
, mMonitor("AndroidSurfaceTexture::mContextMonitor")
, mAttachedContext(nullptr)
, mCanDetach(false)
, mMonitor("AndroidSurfaceTexture::mContextMonitor")
{
}
AndroidSurfaceTexture::~AndroidSurfaceTexture()
{
sInstances.erase(mID);
sInstances.Remove(mID);
mFrameAvailableCallback = nullptr;
@ -205,7 +238,7 @@ AndroidSurfaceTexture::UpdateTexImage()
}
void
AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix)
AndroidSurfaceTexture::GetTransformMatrix(gfx::Matrix4x4& aMatrix) const
{
JNIEnv* const env = jni::GetEnvForThread();

Просмотреть файл

@ -44,7 +44,7 @@ public:
// Android Jelly Bean.
static already_AddRefed<AndroidSurfaceTexture> Create();
static AndroidSurfaceTexture* Find(int id);
static AndroidSurfaceTexture* Find(int aId);
// If we are on Jelly Bean, the SurfaceTexture can be detached and reattached
// to allow consumption from different GLContexts. It is recommended to only
@ -58,19 +58,19 @@ public:
// Ability to detach is based on API version (16+), and we also block PowerVR since it has some type
// of fencing problem. Bug 1100126.
bool CanDetach() { return mCanDetach; }
bool CanDetach() const { return mCanDetach; }
GLContext* GetAttachedContext() { return mAttachedContext; }
GLContext* AttachedContext() const { return mAttachedContext; }
AndroidNativeWindow* NativeWindow() {
AndroidNativeWindow* NativeWindow() const {
return mNativeWindow;
}
// This attaches the updated data to the TEXTURE_EXTERNAL target
void UpdateTexImage();
void GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix);
int ID() { return mID; }
void GetTransformMatrix(mozilla::gfx::Matrix4x4& aMatrix) const;
int ID() const { return mID; }
void SetDefaultSize(mozilla::gfx::IntSize size);
@ -82,8 +82,8 @@ public:
// callback from the underlying SurfaceTexture instance
void NotifyFrameAvailable();
GLuint Texture() { return mTexture; }
const widget::sdk::Surface::Ref& JavaSurface() { return mSurface; }
GLuint Texture() const { return mTexture; }
const widget::sdk::Surface::Ref& JavaSurface() const { return mSurface; }
private:
AndroidSurfaceTexture();
@ -96,13 +96,14 @@ private:
widget::sdk::SurfaceTexture::GlobalRef mSurfaceTexture;
widget::sdk::Surface::GlobalRef mSurface;
Monitor mMonitor;
GLContext* mAttachedContext;
bool mCanDetach;
RefPtr<AndroidNativeWindow> mNativeWindow;
int mID;
nsCOMPtr<nsIRunnable> mFrameAvailableCallback;
mutable Monitor mMonitor;
};
}

Просмотреть файл

@ -6,6 +6,7 @@
#ifndef GFX_GLIMAGES_H
#define GFX_GLIMAGES_H
#include "AndroidSurfaceTexture.h"
#include "GLContextTypes.h"
#include "GLTypes.h"
#include "ImageContainer.h" // for Image
@ -14,9 +15,6 @@
#include "mozilla/gfx/Point.h" // for IntSize
namespace mozilla {
namespace gl {
class AndroidSurfaceTexture;
} // namespace gl
namespace layers {
class GLImage : public Image {
@ -79,7 +77,7 @@ public:
}
private:
gl::AndroidSurfaceTexture* mSurfaceTexture;
RefPtr<gl::AndroidSurfaceTexture> mSurfaceTexture;
gfx::IntSize mSize;
gl::OriginPos mOriginPos;
};

Просмотреть файл

@ -170,3 +170,10 @@ function synthesizeNativeDrag(aElement, aX, aY, aDeltaX, aDeltaY, aObserver = nu
synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_CONTACT, null, aTouchId);
return synthesizeNativeTouch(aElement, aX + aDeltaX, aY + aDeltaY, SpecialPowers.DOMWindowUtils.TOUCH_REMOVE, aObserver, aTouchId);
}
function synthesizeNativeTap(aElement, aX, aY, aObserver = null) {
var pt = coordinatesRelativeToWindow(aX, aY, aElement);
var utils = SpecialPowers.getDOMWindowUtils(aElement.ownerDocument.defaultView);
utils.sendNativeTouchTap(pt.x, pt.y, false, aObserver);
return true;
}

Просмотреть файл

@ -0,0 +1,42 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width; initial-scale=1.0">
<title>Sanity touch-tapping test</title>
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
<script type="application/javascript" src="apz_test_utils.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
<script type="application/javascript">
function clickButton() {
if (!window.TouchEvent) {
window.opener.ok(true, "Touch events are not supported on this platform, sorry!\n");
window.opener.testDone();
return;
}
document.addEventListener('click', clicked, false);
synthesizeNativeTap(document.getElementById('b'), 5, 5, function() {
dump("Finished synthesizing tap, waiting for button to be clicked...\n");
});
}
function clicked(e) {
window.opener.is(e.target, document.getElementById('b'), "Clicked on button, yay! (at " + e.clientX + "," + e.clientY + ")");
window.opener.testDone();
}
window.onload = function() {
waitForAllPaints(function() {
flushApzRepaints(clickButton);
});
}
</script>
</head>
<body>
<button id="b" style="width: 10px; height: 10px"></button>
</body>
</html>

Просмотреть файл

@ -10,6 +10,7 @@ support-files =
helper_basic_pan.html
helper_div_pan.html
helper_iframe_pan.html
helper_tap.html
tags = apz
[test_bug982141.html]
skip-if = toolkit != 'gonk' # bug 991198
@ -32,3 +33,7 @@ skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel ev
[test_scroll_subframe_scrollbar.html]
skip-if = (os == 'android') || (os == 'b2g') || (buildapp == 'mulet') # wheel events not supported on mobile; see bug 1164274 for mulet
[test_frame_reconstruction.html]
[test_tap.html]
# Windows touch injection doesn't work in automation, but this test can be run locally on a windows touch device.
# On OS X we don't support touch events at all.
skip-if = (toolkit == 'windows') || (toolkit == 'cocoa')

Просмотреть файл

@ -0,0 +1,46 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Sanity panning test</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// this page just serially loads each one of the following test helper pages in
// a new window and waits for it to call testDone()
var tests = [
'helper_tap.html',
];
var testIndex = -1;
var w = null;
function testDone() {
if (w) {
w.close();
}
testIndex++;
if (testIndex < tests.length) {
w = window.open(tests[testIndex], "_blank");
} else {
SimpleTest.finish();
}
}
window.onload = function() {
if (!SpecialPowers.getDOMWindowUtils(window).asyncPanZoomEnabled) {
ok(true, "APZ is not enabled, this test is not relevant, sorry!\n");
SimpleTest.finish();
return;
}
testDone();
};
</script>
</head>
<body>
</body>
</html>

Просмотреть файл

@ -434,7 +434,7 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
MOZ_ASSERT(!effectMask->mIs3D);
maskTransform = effectMask->mMaskTransform.As2D();
maskTransform.PreTranslate(-offset.x, -offset.y);
maskTransform.PostTranslate(-offset.x, -offset.y);
}
CompositionOp blendMode = CompositionOp::OP_OVER;

Просмотреть файл

@ -820,7 +820,8 @@ TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
MOZ_ASSERT(aAllocator->IPCOpen());
// also test the validity of aAllocator
MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
if (!aAllocator || !aAllocator->IPCOpen()) {
return nullptr;
}

Просмотреть файл

@ -91,6 +91,8 @@ public:
virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override;
protected:
virtual bool RecvSyncWithCompositor() override { return true; }
virtual bool RecvShutdown() override;
virtual bool RecvUpdate(EditArray&& cset,

Просмотреть файл

@ -123,6 +123,8 @@ parent:
async ChildAsyncMessages(AsyncChildMessageData[] aMessages);
async Shutdown();
sync SyncWithCompositor();
child:
async __delete__();
};

Просмотреть файл

@ -40,6 +40,23 @@ class Shmem;
namespace layers {
static int sShmemCreationCounter = 0;
static void ResetShmemCounter()
{
sShmemCreationCounter = 0;
}
static void ShmemAllocated(LayerTransactionChild* aProtocol)
{
sShmemCreationCounter++;
if (sShmemCreationCounter > 256) {
aProtocol->SendSyncWithCompositor();
ResetShmemCounter();
MOZ_PERFORMANCE_WARNING("gfx", "The number of shmem allocations is too damn high!");
}
}
using namespace mozilla::gfx;
using namespace mozilla::gl;
using namespace mozilla::ipc;
@ -552,6 +569,8 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies,
{
*aSent = false;
ResetShmemCounter();
MOZ_ASSERT(aId);
PROFILER_LABEL("ShadowLayerForwarder", "EndTransaction",
@ -744,6 +763,8 @@ ShadowLayerForwarder::AllocShmem(size_t aSize,
!mShadowManager->IPCOpen()) {
return false;
}
ShmemAllocated(mShadowManager);
return mShadowManager->AllocShmem(aSize, aType, aShmem);
}
bool
@ -756,6 +777,7 @@ ShadowLayerForwarder::AllocUnsafeShmem(size_t aSize,
!mShadowManager->IPCOpen()) {
return false;
}
ShmemAllocated(mShadowManager);
return mShadowManager->AllocUnsafeShmem(aSize, aType, aShmem);
}
void

Просмотреть файл

@ -374,7 +374,7 @@ public:
protected:
RefPtr<CompositorOGL> mCompositor;
mozilla::gl::AndroidSurfaceTexture* const mSurfTex;
RefPtr<gl::AndroidSurfaceTexture> const mSurfTex;
const gfx::SurfaceFormat mFormat;
const GLenum mTextureTarget;
const GLenum mWrapMode;
@ -419,7 +419,7 @@ public:
virtual const char* Name() { return "SurfaceTextureHost"; }
protected:
mozilla::gl::AndroidSurfaceTexture* const mSurfTex;
RefPtr<gl::AndroidSurfaceTexture> const mSurfTex;
const gfx::IntSize mSize;
RefPtr<CompositorOGL> mCompositor;
RefPtr<SurfaceTextureSource> mTextureSource;

Просмотреть файл

@ -145,13 +145,7 @@ void TestSchedulerJoin(uint32_t aNumThreads, uint32_t aNumCmdBuffers)
}
completion->FreezePrerequisites();
RefPtr<EventObject> waitForCompletion = new EventObject();
auto evtJob = new SetEventJob(waitForCompletion, completion);
JobScheduler::SubmitJob(evtJob);
MaybeYieldThread();
waitForCompletion->Wait();
JobScheduler::Join(completion);
MaybeYieldThread();
@ -205,13 +199,7 @@ void TestSchedulerChain(uint32_t aNumThreads, uint32_t aNumCmdBuffers)
}
completion->FreezePrerequisites();
RefPtr<EventObject> waitForCompletion = new EventObject();
auto evtJob = new SetEventJob(waitForCompletion, completion);
JobScheduler::SubmitJob(evtJob);
MaybeYieldThread();
waitForCompletion->Wait();
JobScheduler::Join(completion);
for (auto advancement : check.mAdvancements) {
EXPECT_TRUE(advancement == numJobs);

Просмотреть файл

@ -682,10 +682,11 @@ nsBMPDecoder::ReadBitfields(const char* aData, size_t aLength)
if (mDownscaler) {
// BMPs store their rows in reverse order, so the downscaler needs to
// reverse them again when writing its output.
// reverse them again when writing its output. Unless the height is
// negative!
rv = mDownscaler->BeginFrame(GetSize(), Nothing(),
mImageData, mMayHaveTransparency,
/* aFlipVertically = */ true);
/* aFlipVertically = */ mH.mHeight >= 0);
if (NS_FAILED(rv)) {
return Transition::TerminateFailure();
}

Двоичные данные
image/test/reftest/downscaling/bmp-size-16x16-24bpp.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 879 B

Просмотреть файл

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html class="reftest-wait">
<head>
<title>Image reftest wrapper</title>
<style type="text/css">
#image1 { background-color: rgb(10, 250, 100); }
</style>
<script>
// The image is loaded async after the page loads.
// Wait for it to finish loading.
function onImageLoad() {
document.documentElement.removeAttribute("class");
};
</script>
</head>
<body>
<img width="8px" id="image1">
<script>
// Use as "wrapper.html?image.png"
var imgURL = document.location.search.substr(1);
document.images[0].onload = onImageLoad;
document.images[0].onerror = onImageLoad;
document.images[0].alt = "";
document.images[0].src = imgURL;
</script>
</body>
</html>

Просмотреть файл

@ -91,8 +91,11 @@ fuzzy(20,999) fails-if(OSX>=1008&&!skiaContent) != downscale-2e.html?205,53,bott
== downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
# Non-transparent and transparent ICO images
== downscale-ff.html?ff-0RGB.ico downscale-ff.html?ff-0RGB.png
fuzzy(1,1) == downscale-ff.html?ff-ARGB.ico downscale-ff.html?ff-ARGB.png
== downscale-16px.html?ff-0RGB.ico downscale-16px.html?ff-0RGB.png
fuzzy(1,1) == downscale-16px.html?ff-ARGB.ico downscale-16px.html?ff-ARGB.png
# Upside-down (negative height) BMP
== downscale-8px.html?top-to-bottom-16x16-24bpp.bmp downscale-8px.html?bmp-size-16x16-24bpp.png
# RUN TESTS WITH DOWNSCALE-DURING-DECODE ENABLED:
# ===============================================
@ -160,5 +163,9 @@ fuzzy(20,999) != downscale-2f.html?205,53,bottom about:blank
== downscale-png.html?24,24,interlaced downscale-png.html?24,24,normal
# Non-transparent and transparent ICO images
fuzzy(1,3) == downscale-ff.html?ff-0RGB.ico downscale-ff.html?ff-0RGB.png
fuzzy(3,32) == downscale-ff.html?ff-ARGB.ico downscale-ff.html?ff-ARGB.png
fuzzy(1,3) == downscale-16px.html?ff-0RGB.ico downscale-16px.html?ff-0RGB.png
fuzzy(3,32) == downscale-16px.html?ff-ARGB.ico downscale-16px.html?ff-ARGB.png
# Upside-down (negative height) BMP
== downscale-8px.html?top-to-bottom-16x16-24bpp.bmp downscale-8px.html?bmp-size-16x16-24bpp.png

Двоичные данные
image/test/reftest/downscaling/top-to-bottom-16x16-24bpp.bmp Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 822 B

Просмотреть файл

@ -112,7 +112,7 @@ struct JS_PUBLIC_API(ShortestPaths)
BackEdge* back, bool first)
{
MOZ_ASSERT(back);
MOZ_ASSERT(traversal.visited.has(origin));
MOZ_ASSERT(origin == shortestPaths.root_ || traversal.visited.has(origin));
MOZ_ASSERT(totalPathsRecorded < totalMaxPathsToRecord);
if (first && !back->init(origin, edge))
@ -128,9 +128,7 @@ struct JS_PUBLIC_API(ShortestPaths)
// `back->clone()` in the first branch, and the `init` call in the
// second branch.
auto ptr = shortestPaths.paths_.lookupForAdd(edge.referent);
if (first) {
MOZ_ASSERT(!ptr);
BackEdgeVector paths;
if (!paths.reserve(shortestPaths.maxNumPaths_))
return false;
@ -138,16 +136,23 @@ struct JS_PUBLIC_API(ShortestPaths)
if (!cloned)
return false;
paths.infallibleAppend(mozilla::Move(cloned));
if (!shortestPaths.paths_.add(ptr, edge.referent, mozilla::Move(paths)))
if (!shortestPaths.paths_.putNew(edge.referent, mozilla::Move(paths)))
return false;
totalPathsRecorded++;
} else if (ptr->value().length() < shortestPaths.maxNumPaths_) {
MOZ_ASSERT(ptr);
BackEdge::Ptr thisBackEdge(js_new<BackEdge>());
if (!thisBackEdge || !thisBackEdge->init(origin, edge))
return false;
ptr->value().infallibleAppend(mozilla::Move(thisBackEdge));
totalPathsRecorded++;
} else {
auto ptr = shortestPaths.paths_.lookup(edge.referent);
MOZ_ASSERT(ptr,
"This isn't the first time we have seen the target node `edge.referent`. "
"We should have inserted it into shortestPaths.paths_ the first time we "
"saw it.");
if (ptr->value().length() < shortestPaths.maxNumPaths_) {
BackEdge::Ptr thisBackEdge(js_new<BackEdge>());
if (!thisBackEdge || !thisBackEdge->init(origin, edge))
return false;
ptr->value().infallibleAppend(mozilla::Move(thisBackEdge));
totalPathsRecorded++;
}
}
MOZ_ASSERT(totalPathsRecorded <= totalMaxPathsToRecord);
@ -251,7 +256,7 @@ struct JS_PUBLIC_API(ShortestPaths)
Handler handler(paths);
Traversal traversal(rt, handler, noGC);
traversal.wantNames = true;
if (!traversal.init() || !traversal.addStartVisited(root) || !traversal.traverse())
if (!traversal.init() || !traversal.addStart(root) || !traversal.traverse())
return mozilla::Nothing();
// Take ownership of the back edges we created while traversing the

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше