Merge m-c to fx-team, a=merge

This commit is contained in:
Wes Kocher 2015-05-20 18:31:52 -07:00
commit 9e727e51d3
139 changed files with 2083 additions and 1213 deletions

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="f92a936f2aa97526d4593386754bdbf02db07a12"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="6e47ff2790f5656b5b074407829ceecf3e6188c4"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="22664edc4c73e5fe8f5095ff1d5549db78a2bc10"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="e862ab9177af664f00b4522e2350f4cb13866d73">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<!-- Stock Android things -->
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" revision="95bb5b66b3ec5769c3de8d3f25d681787418e7d2"/>
<project groups="linux" name="platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" path="prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" revision="ebdad82e61c16772f6cd47e9f11936bf6ebe9aa0"/>

View File

@ -1,9 +1,9 @@
{
"git": {
"git_revision": "b290c77ccb7ab0af599b3d8287b71b9970d8dcb0",
"git_revision": "5a7f87b1505ba89b586372cbbbe9507d1016c40c",
"remote": "https://git.mozilla.org/releases/gaia.git",
"branch": ""
},
"revision": "87d96f3c66f704247d1996570748de07ca1aff07",
"revision": "85b4fb5a2fd0040b3726a4f1e4218f2dbfd4edce",
"repo_path": "integration/gaia-central"
}

View File

@ -17,10 +17,10 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="46da1a05ac04157669685246d70ac59d48699c9e"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<!-- Stock Android things -->

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="61e82f99bb8bc78d52b5717e9a2481ec7267fa33">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="b290c77ccb7ab0af599b3d8287b71b9970d8dcb0"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="5a7f87b1505ba89b586372cbbbe9507d1016c40c"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="fffc68521ebb1501d6b015c6d1c4a17a04fdb2e2"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
@ -23,7 +23,7 @@
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
<project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
<project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="d75bd30437ac1465cdb8a35d21079a14cbf63c2d"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="deb1d684da56376a10d900e08d3f4139f3ace885"/>
<!-- Stock Android things -->
<project groups="pdk,linux" name="platform/prebuilts/clang/linux-x86/host/3.5" path="prebuilts/clang/linux-x86/host/3.5" revision="ffc05a232799fe8fcb3e47b7440b52b1fb4244c0"/>
<project groups="pdk,linux,arm" name="platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" path="prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.8" revision="337e0ef5e40f02a1ae59b90db0548976c70a7226"/>

View File

@ -5,7 +5,6 @@ no_sccache=1
ac_add_options --enable-valgrind
ac_add_options --disable-jemalloc
ac_add_options --enable-optimize="-g -O -freorder-blocks"
ac_add_options --disable-install-strip
# Include the override mozconfig again (even though the above includes it)

View File

@ -5,7 +5,6 @@ no_sccache=1
ac_add_options --enable-valgrind
ac_add_options --disable-jemalloc
ac_add_options --enable-optimize="-g -O -freorder-blocks"
ac_add_options --disable-install-strip
# Include the override mozconfig again (even though the above includes it)

View File

@ -68,10 +68,18 @@ Activity::Initialize(nsPIDOMWindow* aWindow,
mProxy = do_CreateInstance("@mozilla.org/dom/activities/proxy;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
// We're about the pass the dictionary to a JS-implemented component, so
// rehydrate it in a system scode so that security wrappers don't get in the
// way. See bug 1161748 comment 16.
bool ok;
JS::Rooted<JS::Value> optionsValue(aCx);
if (!ToJSValue(aCx, aOptions, &optionsValue)) {
return NS_ERROR_FAILURE;
{
JSAutoCompartment ac(aCx, xpc::PrivilegedJunkScope());
ok = ToJSValue(aCx, aOptions, &optionsValue);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
}
ok = JS_WrapValue(aCx, &optionsValue);
NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
mProxy->StartActivity(static_cast<nsIDOMDOMRequest*>(this), optionsValue, aWindow);
return NS_OK;

View File

@ -201,6 +201,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAudioChannelManager)
#endif
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCameraManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaDevices)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessagesManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageStores)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTimeManager)
@ -307,6 +308,7 @@ Navigator::Invalidate()
#endif
mCameraManager = nullptr;
mMediaDevices = nullptr;
if (mMessagesManager) {
mMessagesManager = nullptr;

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<body>
<script>
// This should not leak.
var a = navigator;
navigator.mediaDevices._ = null;
</script>
</body>

View File

@ -202,3 +202,4 @@ load xhr_empty_datauri.html
load xhr_html_nullresponse.html
load structured_clone_container_throws.html
load 1154598.xhtml
load 1157995.html

View File

@ -203,16 +203,23 @@ TelephonyListener::HandleCallInfo(nsITelephonyCallInfo* aInfo, bool aSend)
uint32_t callIndex;
uint16_t callState;
nsAutoString number;
nsAutoString disconnectedReason;
bool isOutgoing;
bool isConference;
aInfo->GetCallIndex(&callIndex);
aInfo->GetCallState(&callState);
aInfo->GetNumber(number);
aInfo->GetDisconnectedReason(disconnectedReason);
aInfo->GetIsOutgoing(&isOutgoing);
aInfo->GetIsConference(&isConference);
hfp->HandleCallStateChanged(callIndex, callState, EmptyString(), number,
// The disconnectedReason of a disconnected call must be nonempty no matter
// the call is disconnected for a normal reason or an error.
MOZ_ASSERT((callState != nsITelephonyService::CALL_STATE_DISCONNECTED ||
!disconnectedReason.IsEmpty()),
"disconnectedReason of an disconnected call must be nonempty.");
hfp->HandleCallStateChanged(callIndex, callState, disconnectedReason, number,
isOutgoing, isConference, aSend);
return NS_OK;
}
@ -233,30 +240,6 @@ TelephonyListener::EnumerateCallState(nsITelephonyCallInfo* aInfo)
return HandleCallInfo(aInfo, false);
}
NS_IMETHODIMP
TelephonyListener::NotifyError(uint32_t aServiceId,
int32_t aCallIndex,
const nsAString& aError)
{
BluetoothHfpManager* hfp = BluetoothHfpManager::Get();
NS_ENSURE_TRUE(hfp, NS_ERROR_FAILURE);
if (aCallIndex > 0) {
// In order to not miss any related call state transition.
// It's possible that 3G network signal lost for unknown reason.
// If a call is released abnormally, NotifyError() will be called,
// instead of CallStateChanged(). We need to reset the call array state
// via setting CALL_STATE_DISCONNECTED
hfp->HandleCallStateChanged(aCallIndex,
nsITelephonyService::CALL_STATE_DISCONNECTED,
aError, EmptyString(), false, false, true);
BT_WARNING("Reset the call state due to call transition ends abnormally");
}
BT_WARNING(NS_ConvertUTF16toUTF8(aError).get());
return NS_OK;
}
NS_IMETHODIMP
TelephonyListener::ConferenceCallStateChanged(uint16_t aCallState)
{

174
dom/cache/DBSchema.cpp vendored
View File

@ -181,7 +181,7 @@ static void AppendListParamsToQuery(nsACString& aQuery,
static nsresult BindListParamsToQuery(mozIStorageStatement* aState,
const nsTArray<EntryId>& aEntryIdList,
uint32_t aPos, int32_t aLen);
static nsresult BindId(mozIStorageStatement* aState, uint32_t aPos,
static nsresult BindId(mozIStorageStatement* aState, const nsACString& aName,
const nsID* aId);
static nsresult ExtractId(mozIStorageStatement* aState, uint32_t aPos,
nsID* aIdOut);
@ -412,11 +412,11 @@ DeleteCacheId(mozIStorageConnection* aConn, CacheId aCacheId,
// Delete the remainder of the cache using cascade semantics.
nsCOMPtr<mozIStorageStatement> state;
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM caches WHERE id=?1;"
"DELETE FROM caches WHERE id=:id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -438,11 +438,11 @@ IsCacheOrphaned(mozIStorageConnection* aConn, CacheId aCacheId,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT COUNT(*) FROM storage WHERE cache_id=?1;"
"SELECT COUNT(*) FROM storage WHERE cache_id=:cache_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -646,11 +646,11 @@ StorageMatch(mozIStorageConnection* aConn,
nsCOMPtr<mozIStorageStatement> state;
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT cache_id FROM storage WHERE namespace=?1 ORDER BY rowid;"
"SELECT cache_id FROM storage WHERE namespace=:namespace ORDER BY rowid;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsAutoTArray<CacheId, 32> cacheIdList;
@ -693,14 +693,15 @@ StorageGetCacheId(mozIStorageConnection* aConn, Namespace aNamespace,
// Use IS for matching the key since an EmptryString() key maps to NULL.
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT cache_id FROM storage WHERE namespace=?1 AND key IS ?2 ORDER BY rowid;"
"SELECT cache_id FROM storage WHERE namespace=:namespace AND key IS :key "
"ORDER BY rowid;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringAsBlobParameter(1, aKey);
rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -727,17 +728,18 @@ StoragePutCache(mozIStorageConnection* aConn, Namespace aNamespace,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"INSERT INTO storage (namespace, key, cache_id) VALUES(?1, ?2, ?3);"
"INSERT INTO storage (namespace, key, cache_id) "
"VALUES (:namespace, :key, :cache_id);"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringAsBlobParameter(1, aKey);
rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(2, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -756,14 +758,14 @@ StorageForgetCache(mozIStorageConnection* aConn, Namespace aNamespace,
// Use IS for matching the key since an EmptryString() key maps to NULL.
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM storage WHERE namespace=?1 AND key IS ?2;"
"DELETE FROM storage WHERE namespace=:namespace AND key IS :key;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringAsBlobParameter(1, aKey);
rv = state->BindStringAsBlobByName(NS_LITERAL_CSTRING("key"), aKey);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -781,11 +783,11 @@ StorageGetKeys(mozIStorageConnection* aConn, Namespace aNamespace,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT key FROM storage WHERE namespace=?1 ORDER BY rowid;"
"SELECT key FROM storage WHERE namespace=:namespace ORDER BY rowid;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aNamespace);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("namespace"), aNamespace);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -811,11 +813,11 @@ QueryAll(mozIStorageConnection* aConn, CacheId aCacheId,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT id FROM entries WHERE cache_id=?1 ORDER BY id;"
"SELECT id FROM entries WHERE cache_id=:cache_id ORDER BY id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -851,7 +853,7 @@ QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
"FROM entries "
"LEFT OUTER JOIN response_headers ON entries.id=response_headers.entry_id "
"AND response_headers.name='vary' "
"WHERE entries.cache_id=?1 "
"WHERE entries.cache_id=:cache_id "
"AND entries."
);
@ -864,16 +866,16 @@ QueryCache(mozIStorageConnection* aConn, CacheId aCacheId,
query.AppendLiteral("request_url");
}
query.AppendLiteral("=?2 GROUP BY entries.id ORDER BY entries.id;");
query.AppendLiteral("=:url GROUP BY entries.id ORDER BY entries.id;");
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(query, getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(0, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(1, urlToMatch);
rv = state->BindStringByName(NS_LITERAL_CSTRING("url"), urlToMatch);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -919,11 +921,11 @@ MatchByVaryHeader(mozIStorageConnection* aConn,
nsCOMPtr<mozIStorageStatement> state;
nsresult rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT value FROM response_headers "
"WHERE name='vary' AND entry_id=?1;"
"WHERE name='vary' AND entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsAutoTArray<nsCString, 8> varyValues;
@ -943,11 +945,11 @@ MatchByVaryHeader(mozIStorageConnection* aConn,
state->Reset();
rv = aConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT name, value FROM request_headers "
"WHERE entry_id=?1;"
"WHERE entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
nsRefPtr<InternalHeaders> cachedHeaders =
@ -1138,71 +1140,101 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"response_body_id, "
"response_security_info, "
"cache_id "
") VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19)"
") VALUES ("
":request_method, "
":request_url, "
":request_url_no_query, "
":request_referrer, "
":request_headers_guard, "
":request_mode, "
":request_credentials, "
":request_contentpolicytype, "
":request_context, "
":request_cache, "
":request_body_id, "
":response_type, "
":response_url, "
":response_status, "
":response_status_text, "
":response_headers_guard, "
":response_body_id, "
":response_security_info, "
":cache_id "
");"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(0, aRequest.method());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("request_method"),
aRequest.method());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(1, aRequest.url());
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_url"),
aRequest.url());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(2, aRequest.urlWithoutQuery());
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_url_no_query"),
aRequest.urlWithoutQuery());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(3, aRequest.referrer());
rv = state->BindStringByName(NS_LITERAL_CSTRING("request_referrer"),
aRequest.referrer());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(4,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_headers_guard"),
static_cast<int32_t>(aRequest.headersGuard()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(5, static_cast<int32_t>(aRequest.mode()));
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_mode"),
static_cast<int32_t>(aRequest.mode()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(6,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_credentials"),
static_cast<int32_t>(aRequest.credentials()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(7,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_contentpolicytype"),
static_cast<int32_t>(aRequest.contentPolicyType()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(8,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_context"),
static_cast<int32_t>(aRequest.context()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(9,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("request_cache"),
static_cast<int32_t>(aRequest.requestCache()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = BindId(state, 10, aRequestBodyId);
rv = BindId(state, NS_LITERAL_CSTRING("request_body_id"), aRequestBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(11, static_cast<int32_t>(aResponse.type()));
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_type"),
static_cast<int32_t>(aResponse.type()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindStringParameter(12, aResponse.url());
rv = state->BindStringByName(NS_LITERAL_CSTRING("response_url"),
aResponse.url());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(13, aResponse.status());
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_status"),
aResponse.status());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(14, aResponse.statusText());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("response_status_text"),
aResponse.statusText());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(15,
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_headers_guard"),
static_cast<int32_t>(aResponse.headersGuard()));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = BindId(state, 16, aResponseBodyId);
rv = BindId(state, NS_LITERAL_CSTRING("response_body_id"), aResponseBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringAsBlobParameter(17, aResponse.securityInfo());
rv = state->BindUTF8StringAsBlobByName(NS_LITERAL_CSTRING("response_security_info"),
aResponse.securityInfo());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt64Parameter(18, aCacheId);
rv = state->BindInt64ByName(NS_LITERAL_CSTRING("cache_id"), aCacheId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -1226,19 +1258,21 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"name, "
"value, "
"entry_id "
") VALUES (?1, ?2, ?3)"
") VALUES (:name, :value, :entry_id)"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
const nsTArray<HeadersEntry>& requestHeaders = aRequest.headers();
for (uint32_t i = 0; i < requestHeaders.Length(); ++i) {
rv = state->BindUTF8StringParameter(0, requestHeaders[i].name());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("name"),
requestHeaders[i].name());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(1, requestHeaders[i].value());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("value"),
requestHeaders[i].value());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(2, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -1250,19 +1284,21 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
"name, "
"value, "
"entry_id "
") VALUES (?1, ?2, ?3)"
") VALUES (:name, :value, :entry_id)"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
const nsTArray<HeadersEntry>& responseHeaders = aResponse.headers();
for (uint32_t i = 0; i < responseHeaders.Length(); ++i) {
rv = state->BindUTF8StringParameter(0, responseHeaders[i].name());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("name"),
responseHeaders[i].name());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindUTF8StringParameter(1, responseHeaders[i].value());
rv = state->BindUTF8StringByName(NS_LITERAL_CSTRING("value"),
responseHeaders[i].value());
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(2, entryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), entryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->Execute();
@ -1291,11 +1327,11 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
"response_body_id, "
"response_security_info "
"FROM entries "
"WHERE id=?1;"
"WHERE id=:id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -1342,11 +1378,11 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
"name, "
"value "
"FROM response_headers "
"WHERE entry_id=?1;"
"WHERE entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
@ -1387,11 +1423,11 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
"request_cache, "
"request_body_id "
"FROM entries "
"WHERE id=?1;"
"WHERE id=:id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
bool hasMoreData = false;
@ -1460,11 +1496,11 @@ ReadRequest(mozIStorageConnection* aConn, EntryId aEntryId,
"name, "
"value "
"FROM request_headers "
"WHERE entry_id=?1;"
"WHERE entry_id=:entry_id;"
), getter_AddRefs(state));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = state->BindInt32Parameter(0, aEntryId);
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("entry_id"), aEntryId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
while (NS_SUCCEEDED(state->ExecuteStep(&hasMoreData)) && hasMoreData) {
@ -1506,28 +1542,28 @@ BindListParamsToQuery(mozIStorageStatement* aState,
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT((aPos + aLen) <= aEntryIdList.Length());
for (int32_t i = aPos; i < aLen; ++i) {
nsresult rv = aState->BindInt32Parameter(i, aEntryIdList[i]);
nsresult rv = aState->BindInt32ByIndex(i, aEntryIdList[i]);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
nsresult
BindId(mozIStorageStatement* aState, uint32_t aPos, const nsID* aId)
BindId(mozIStorageStatement* aState, const nsACString& aName, const nsID* aId)
{
MOZ_ASSERT(!NS_IsMainThread());
MOZ_ASSERT(aState);
nsresult rv;
if (!aId) {
rv = aState->BindNullParameter(aPos);
rv = aState->BindNullByName(aName);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
return rv;
}
char idBuf[NSID_LENGTH];
aId->ToProvidedString(idBuf);
rv = aState->BindUTF8StringParameter(aPos, nsAutoCString(idBuf));
rv = aState->BindUTF8StringByName(aName, nsAutoCString(idBuf));
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
return rv;

View File

@ -465,15 +465,7 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
return NS_OK;
}
// Kick off the geo device, if it isn't already running
nsRefPtr<nsGeolocationService> gs = nsGeolocationService::GetGeolocationService();
nsresult rv = gs->StartDevice(GetPrincipal());
if (NS_FAILED(rv)) {
// Location provider error
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
return NS_OK;
}
bool canUseCache = false;
CachedPositionAndAccuracy lastPosition = gs->GetCachedPosition();
@ -497,6 +489,15 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
// getCurrentPosition requests serviced by the cache
// will now be owned by the RequestSendLocationEvent
Update(lastPosition.position);
} else {
// Kick off the geo device, if it isn't already running
nsresult rv = gs->StartDevice(GetPrincipal());
if (NS_FAILED(rv)) {
// Location provider error
NotifyError(nsIDOMGeoPositionError::POSITION_UNAVAILABLE);
return NS_OK;
}
}
if (mIsWatchPositionRequest || !canUseCache) {
@ -957,7 +958,9 @@ nsGeolocationService::Observe(nsISupports* aSubject,
NS_IMETHODIMP
nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
{
SetCachedPosition(aSomewhere);
if (aSomewhere) {
SetCachedPosition(aSomewhere);
}
for (uint32_t i = 0; i< mGeolocators.Length(); i++) {
mGeolocators[i]->Update(aSomewhere);

View File

@ -193,7 +193,9 @@ let FormAssistant = {
addEventListener("focus", this, true, false);
addEventListener("blur", this, true, false);
addEventListener("resize", this, true, false);
addEventListener("submit", this, true, false);
// We should not blur the fucus if the submit event is cancelled,
// therefore we are binding our event listener in the bubbling phase here.
addEventListener("submit", this, false, false);
addEventListener("pagehide", this, true, false);
addEventListener("beforeunload", this, true, false);
addEventListener("input", this, true, false);
@ -399,7 +401,7 @@ let FormAssistant = {
}
// fall through
case "submit":
if (this.focusedElement) {
if (this.focusedElement && !evt.defaultPrevented) {
this.focusedElement.blur();
}
break;

View File

@ -64,56 +64,6 @@ SetUpSandboxEnvironment()
return;
}
}
#if defined(NIGHTLY_BUILD)
static void
CleanUpOldSandboxEnvironment()
{
// Temporary code to clean up the old low integrity temp directories.
// The removal of this is tracked by bug 1165818.
nsCOMPtr<nsIFile> lowIntegrityMozilla;
nsresult rv = NS_GetSpecialDirectory(NS_WIN_LOCAL_APPDATA_LOW_DIR,
getter_AddRefs(lowIntegrityMozilla));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
rv = lowIntegrityMozilla->Append(NS_LITERAL_STRING(MOZ_USER_DIR));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
nsCOMPtr<nsISimpleEnumerator> iter;
rv = lowIntegrityMozilla->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
bool more;
nsCOMPtr<nsISupports> elem;
while (NS_SUCCEEDED(iter->HasMoreElements(&more)) && more) {
rv = iter->GetNext(getter_AddRefs(elem));
if (NS_FAILED(rv)) {
break;
}
nsCOMPtr<nsIFile> file = do_QueryInterface(elem);
if (!file) {
continue;
}
nsAutoString leafName;
rv = file->GetLeafName(leafName);
if (NS_FAILED(rv)) {
continue;
}
if (leafName.Find(NS_LITERAL_STRING("MozTemp-{")) == 0) {
file->Remove(/* aRecursive */ true);
}
}
}
#endif
#endif
void
@ -138,12 +88,11 @@ ContentProcess::Init()
return true;
}
// Note: CleanUp() never gets called in non-debug builds because we exit early
// in ContentChild::ActorDestroy().
void
ContentProcess::CleanUp()
{
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX) && defined(NIGHTLY_BUILD)
CleanUpOldSandboxEnvironment();
#endif
mXREEmbed.Stop();
}

View File

@ -14,9 +14,9 @@ skip-if = buildapp == 'b2g' || buildapp == 'mulet' || e10s || toolkit == 'androi
[test_cpow_cookies.html]
skip-if = buildapp == 'b2g' || buildapp == 'mulet'
[test_NuwaProcessCreation.html]
skip-if = toolkit != 'gonk'
skip-if = true # bug 1166923
[test_NuwaProcessDeadlock.html]
skip-if = toolkit != 'gonk'
skip-if = true # bug 1166923
[test_child_docshell.html]
skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
[test_CrashService_crash.html]

View File

@ -0,0 +1,185 @@
/* 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/. */
/*
* ManifestImageObjectProcessor
* Implementation of Image Object processing algorithms from:
* http://www.w3.org/2008/webapps/manifest/#image-object-and-its-members
*
* This is intended to be used in conjunction with ManifestProcessor.jsm
*
* Creates an object to process Image Objects as defined by the
* W3C specification. This is used to process things like the
* icon member and the splash_screen member.
*
* Usage:
*
* .process(aManifest, aBaseURL, aMemberName, console);
*
*/
/*exported EXPORTED_SYMBOLS */
/*globals extractValue, Components*/
'use strict';
this.EXPORTED_SYMBOLS = ['ManifestImageObjectProcessor']; // jshint ignore:line
const imports = {};
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']
.getService(Ci.mozIJSSubScriptLoader);
scriptLoader.loadSubScript(
'resource://gre/modules/manifestValueExtractor.js',
this); // jshint ignore:line
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.importGlobalProperties(['URL']);
imports.netutil = Cc['@mozilla.org/network/util;1']
.getService(Ci.nsINetUtil);
imports.DOMUtils = Cc['@mozilla.org/inspector/dom-utils;1']
.getService(Ci.inIDOMUtils);
function ManifestImageObjectProcessor() {}
// Static getters
Object.defineProperties(ManifestImageObjectProcessor, {
'decimals': {
get: function() {
return /^\d+$/;
}
},
'anyRegEx': {
get: function() {
return new RegExp('any', 'i');
}
}
});
ManifestImageObjectProcessor.process = function(
aManifest, aBaseURL, aMemberName, console
) {
const spec = {
objectName: 'manifest',
object: aManifest,
property: aMemberName,
expectedType: 'array',
trim: false
};
const images = [];
const value = extractValue(spec, console);
if (Array.isArray(value)) {
// Filter out images whose "src" is not useful.
value.filter(item => !!processSrcMember(item, aBaseURL))
.map(toImageObject)
.forEach(image => images.push(image));
}
return images;
function toImageObject(aImageSpec) {
return {
'src': processSrcMember(aImageSpec, aBaseURL),
'type': processTypeMember(aImageSpec),
'sizes': processSizesMember(aImageSpec),
'density': processDensityMember(aImageSpec),
'background_color': processBackgroundColorMember(aImageSpec)
};
}
function processTypeMember(aImage) {
const charset = {};
const hadCharset = {};
const spec = {
objectName: 'image',
object: aImage,
property: 'type',
expectedType: 'string',
trim: true
};
let value = extractValue(spec, console);
if (value) {
value = imports.netutil.parseContentType(value, charset, hadCharset);
}
return value || undefined;
}
function processDensityMember(aImage) {
const value = parseFloat(aImage.density);
const validNum = Number.isNaN(value) || value === +Infinity || value <=
0;
return (validNum) ? 1.0 : value;
}
function processSrcMember(aImage, aBaseURL) {
const spec = {
objectName: 'image',
object: aImage,
property: 'src',
expectedType: 'string',
trim: false
};
const value = extractValue(spec, console);
let url;
if (value && value.length) {
try {
url = new URL(value, aBaseURL).href;
} catch (e) {}
}
return url;
}
function processSizesMember(aImage) {
const sizes = new Set();
const spec = {
objectName: 'image',
object: aImage,
property: 'sizes',
expectedType: 'string',
trim: true
};
const value = extractValue(spec, console);
if (value) {
// Split on whitespace and filter out invalid values.
value.split(/\s+/)
.filter(isValidSizeValue)
.forEach(size => sizes.add(size));
}
return sizes;
// Implementation of HTML's link@size attribute checker.
function isValidSizeValue(aSize) {
const size = aSize.toLowerCase();
if (ManifestImageObjectProcessor.anyRegEx.test(aSize)) {
return true;
}
if (!size.includes('x') || size.indexOf('x') !== size.lastIndexOf('x')) {
return false;
}
// Split left of x for width, after x for height.
const widthAndHeight = size.split('x');
const w = widthAndHeight.shift();
const h = widthAndHeight.join('x');
const validStarts = !w.startsWith('0') && !h.startsWith('0');
const validDecimals = ManifestImageObjectProcessor.decimals.test(w + h);
return (validStarts && validDecimals);
}
}
function processBackgroundColorMember(aImage) {
const spec = {
objectName: 'image',
object: aImage,
property: 'background_color',
expectedType: 'string',
trim: true
};
const value = extractValue(spec, console);
let color;
if (imports.DOMUtils.isValidCSSColor(value)) {
color = value;
} else {
const msg = `background_color: ${value} is not a valid CSS color.`;
console.warn(msg);
}
return color;
}
};
this.ManifestImageObjectProcessor = ManifestImageObjectProcessor; // jshint ignore:line

View File

@ -1,7 +1,7 @@
/* 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/. */
/*
/*
* ManifestProcessor
* Implementation of processing algorithms from:
* http://www.w3.org/2008/webapps/manifest/
@ -12,54 +12,38 @@
*
* .process({jsonText,manifestURL,docURL});
*
* Depends on ManifestImageObjectProcessor to process things like
* icons and splash_screens.
*
* TODO: The constructor should accept the UA's supported orientations.
* TODO: The constructor should accept the UA's supported display modes.
* TODO: hook up developer tools to console. (1086997).
*/
/*exported EXPORTED_SYMBOLS */
/*JSLint options in comment below: */
/*globals Components, XPCOMUtils*/
/*globals Components, XPCOMUtils, extractValue*/
'use strict';
this.EXPORTED_SYMBOLS = ['ManifestProcessor'];
this.EXPORTED_SYMBOLS = ['ManifestProcessor']; // jshint ignore:line
const imports = {};
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']
.getService(Ci.mozIJSSubScriptLoader);
//Add extractValue() helper to this context.
scriptLoader.loadSubScript(
'resource://gre/modules/manifestValueExtractor.js',
this); // jshint ignore:line
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.importGlobalProperties(['URL']);
XPCOMUtils.defineLazyModuleGetter(imports, 'Services',
'resource://gre/modules/Services.jsm');
imports.netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil);
// Helper function extracts values from manifest members
// and reports conformance violations.
function extractValue({
objectName,
object,
property,
expectedType,
trim
}, console) {
const value = object[property];
const isArray = Array.isArray(value);
// We need to special-case "array", as it's not a JS primitive.
const type = (isArray) ? 'array' : typeof value;
if (type !== expectedType) {
if (type !== 'undefined') {
let msg = `Expected the ${objectName}'s ${property} `;
msg += `member to a be a ${expectedType}.`;
console.log(msg);
}
return undefined;
}
// Trim string and returned undefined if the empty string.
const shouldTrim = expectedType === 'string' && value && trim;
if (shouldTrim) {
return value.trim() || undefined;
}
return value;
}
XPCOMUtils.defineLazyModuleGetter(imports, 'ManifestImageObjectProcessor',
'resource://gre/modules/ManifestImageObjectProcessor.jsm');
imports.netutil = Cc['@mozilla.org/network/util;1']
.getService(Ci.nsINetUtil);
const displayModes = new Set(['fullscreen', 'standalone', 'minimal-ui',
'browser'
]);
@ -93,13 +77,12 @@ Object.defineProperties(ManifestProcessor, {
});
ManifestProcessor.prototype = {
// process method: processes json text into a clean manifest
// process method: processes JSON text into a clean manifest
// that conforms with the W3C specification. Takes an object
// expecting the following dictionary items:
// * jsonText: the JSON string to be processd.
// * manifestURL: the URL of the manifest, to resolve URLs.
// * docURL: the URL of the owner doc, for security checks.
// * aJsonText: the JSON string to be processed.
// * aManifestURL: the URL of the manifest, to resolve URLs.
// * aDocURL: the URL of the owner doc, for security checks.
process({
jsonText: aJsonText,
manifestURL: aManifestURL,
@ -120,15 +103,20 @@ ManifestProcessor.prototype = {
rawManifest = {};
}
const processedManifest = {
start_url: processStartURLMember(rawManifest, manifestURL, docURL),
display: processDisplayMember(rawManifest),
orientation: processOrientationMember(rawManifest),
name: processNameMember(rawManifest),
icons: IconsProcessor.process(rawManifest, manifestURL, console),
short_name: processShortNameMember(rawManifest),
'start_url': processStartURLMember(rawManifest, manifestURL, docURL),
'display': processDisplayMember(rawManifest),
'orientation': processOrientationMember(rawManifest),
'name': processNameMember(rawManifest),
'icons': imports.ManifestImageObjectProcessor.process(
rawManifest, manifestURL, 'icons', console
),
'splash_screens': imports.ManifestImageObjectProcessor.process(
rawManifest, manifestURL, 'splash_screens', console
),
'short_name': processShortNameMember(rawManifest),
};
processedManifest.scope = processScopeMember(rawManifest, manifestURL,
docURL, new URL(processedManifest.start_url));
docURL, new URL(processedManifest['start_url'])); // jshint ignore:line
return processedManifest;
@ -251,126 +239,4 @@ ManifestProcessor.prototype = {
}
}
};
this.ManifestProcessor = ManifestProcessor;
function IconsProcessor() {}
// Static getters
Object.defineProperties(IconsProcessor, {
'onlyDecimals': {
get: function() {
return /^\d+$/;
}
},
'anyRegEx': {
get: function() {
return new RegExp('any', 'i');
}
}
});
IconsProcessor.process = function(aManifest, aBaseURL, console) {
const spec = {
objectName: 'manifest',
object: aManifest,
property: 'icons',
expectedType: 'array',
trim: false
};
const icons = [];
const value = extractValue(spec, console);
if (Array.isArray(value)) {
// Filter out icons whose "src" is not useful.
value.filter(item => !!processSrcMember(item, aBaseURL))
.map(toIconObject)
.forEach(icon => icons.push(icon));
}
return icons;
function toIconObject(aIconData) {
return {
src: processSrcMember(aIconData, aBaseURL),
type: processTypeMember(aIconData),
sizes: processSizesMember(aIconData),
density: processDensityMember(aIconData)
};
}
function processTypeMember(aIcon) {
const charset = {};
const hadCharset = {};
const spec = {
objectName: 'icon',
object: aIcon,
property: 'type',
expectedType: 'string',
trim: true
};
let value = extractValue(spec, console);
if (value) {
value = imports.netutil.parseContentType(value, charset, hadCharset);
}
return value || undefined;
}
function processDensityMember(aIcon) {
const value = parseFloat(aIcon.density);
const validNum = Number.isNaN(value) || value === +Infinity || value <=
0;
return (validNum) ? 1.0 : value;
}
function processSrcMember(aIcon, aBaseURL) {
const spec = {
objectName: 'icon',
object: aIcon,
property: 'src',
expectedType: 'string',
trim: false
};
const value = extractValue(spec, console);
let url;
if (value && value.length) {
try {
url = new URL(value, aBaseURL).href;
} catch (e) {}
}
return url;
}
function processSizesMember(aIcon) {
const sizes = new Set(),
spec = {
objectName: 'icon',
object: aIcon,
property: 'sizes',
expectedType: 'string',
trim: true
},
value = extractValue(spec, console);
if (value) {
// Split on whitespace and filter out invalid values.
value.split(/\s+/)
.filter(isValidSizeValue)
.forEach(size => sizes.add(size));
}
return sizes;
// Implementation of HTML's link@size attribute checker.
function isValidSizeValue(aSize) {
const size = aSize.toLowerCase();
if (IconsProcessor.anyRegEx.test(aSize)) {
return true;
}
if (!size.includes('x') || size.indexOf('x') !== size.lastIndexOf('x')) {
return false;
}
// Split left of x for width, after x for height.
const widthAndHeight = size.split('x');
const w = widthAndHeight.shift();
const h = widthAndHeight.join('x');
const validStarts = !w.startsWith('0') && !h.startsWith('0');
const validDecimals = IconsProcessor.onlyDecimals.test(w + h);
return (validStarts && validDecimals);
}
}
};
this.ManifestProcessor = ManifestProcessor; // jshint ignore:line

View File

@ -0,0 +1,34 @@
/* 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/. */
/*
* Helper function extracts values from manifest members
* and reports conformance violations.
*/
function extractValue({
objectName,
object,
property,
expectedType,
trim
}, console) {
const value = object[property];
const isArray = Array.isArray(value);
// We need to special-case "array", as it's not a JS primitive.
const type = (isArray) ? 'array' : typeof value;
if (type !== expectedType) {
if (type !== 'undefined') {
let msg = `Expected the ${objectName}'s ${property} `;
msg += `member to be a ${expectedType}.`;
console.log(msg);
}
return undefined;
}
// Trim string and returned undefined if the empty string.
const shouldTrim = expectedType === 'string' && value && trim;
if (shouldTrim) {
return value.trim() || undefined;
}
return value;
}

View File

@ -5,9 +5,11 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
'ManifestImageObjectProcessor.jsm',
'ManifestObtainer.jsm',
'ManifestProcessor.jsm',
'manifestValueExtractor.js'
]
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']

View File

@ -4,14 +4,16 @@ support-files =
resource.sjs
manifestLoader.html
[test_IconsProcessor_density.html]
[test_IconsProcessor_sizes.html]
[test_IconsProcessor_src.html]
[test_IconsProcessor_type.html]
[test_ImageObjectProcessor_background_color.html]
[test_ImageObjectProcessor_density.html]
[test_ImageObjectProcessor_sizes.html]
[test_ImageObjectProcessor_src.html]
[test_ImageObjectProcessor_type.html]
[test_ManifestProcessor_display.html]
[test_ManifestProcessor_icons.html]
[test_ManifestProcessor_JSON.html]
[test_ManifestProcessor_name_and_short_name.html]
[test_ManifestProcessor_orientation.html]
[test_ManifestProcessor_start_url.html]
[test_ManifestProcessor_scope.html]
[test_ManifestProcessor_scope.html]
[test_ManifestProcessor_splash_screens.html]

View File

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1162808
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1162808</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script src="common.js"></script>
<script type="application/javascript">
/**
* Image object's type member
* https://w3c.github.io/manifest/#type-member
*
* Checks that invalid and valid colors are processed correctly.
**/
/*globals data, processor, is*/
'use strict';
var testIcon = {
icons: [{
src: 'test',
'background_color': undefined
}]
};
// Test invalid colors.
var invalidColors = [
'marooon',
'f000000',
'#ff00000',
'rgb(255 0 0)',
'rgb(100, 0%, 0%)',
'rgb(255,0)',
'rgb(300 0 0)',
'rbg(255,-10,0)',
'rgb(110, 0%, 0%)',
'(255,0,0) }',
'rgba(255)',
' rgb(100%,0%,0%) }',
'hsl 120, 100%, 50%',
'hsla{120, 100%, 50%, 1}'
];
invalidColors.forEach((invalidColor) => {
var expected = `Treat invalid color (${invalidColor}) as undefined.`;
testIcon.icons[0].background_color = invalidColor;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
is(result.icons[0].background_color, undefined, expected);
});
// Test valid colors.
var validColors = [
'maroon',
'#f00',
'#ff0000',
'rgb(255,0,0)',
'rgb(100%, 0%, 0%)',
'rgb(255,0,0)',
'rgb(300,0,0)',
'rgb(255,-10,0)',
'rgb(110%, 0%, 0%)',
'rgb(255,0,0)',
'rgba(255,0,0,1)',
'rgb(100%,0%,0%)',
'rgba(100%,0%,0%,1)',
'rgba(0,0,255,0.5)',
'rgba(100%, 50%, 0%, 0.1)',
'hsl(120, 100%, 50%)',
'hsla(120, 100%, 50%, 1)'
];
validColors.forEach((color) => {
var expected = `Treat valid CSS color (${color}) as valid input.`;
testIcon.icons[0].background_color = color;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
is(result.icons[0].background_color, color, expected);
});
</script>
</head>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1162808">Mozilla Bug 1162808</a>

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's density member
* Image object density member
* https://w3c.github.io/manifest/#density-member
**/
'use strict';

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's sizes property
* Image object's sizes member
* https://w3c.github.io/manifest/#sizes-member
**/
'use strict';

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's src member
* Image object's src member
* https://w3c.github.io/manifest/#src-member
**/
'use strict';

View File

@ -11,7 +11,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
<script src="common.js"></script>
<script>
/**
* icon member's type property
* Image object's type property
* https://w3c.github.io/manifest/#type-member
**/

View File

@ -0,0 +1,29 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1162808
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1162808</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* Manifest splash_screens member
* http://www.w3.org/TR/appmanifest/#splash_screens-member
**/
'use strict';
typeTests.forEach((type) => {
var expected = `Expect non-array splash_screens to be empty: ${typeof type}.`;
data.jsonText = JSON.stringify({
splash_screens: type
});
var result = processor.process(data);
is(result.splash_screens.length, 0, expected);
});
</script>
</head>

View File

@ -47,9 +47,10 @@ MediaStreamPlayback.prototype = {
startMedia : function(isResume) {
var canPlayThroughFired = false;
// If we're initially running this media, check that the time is zero
// If we're playing this media element for the first time,
// check that the time is zero.
if (!isResume) {
is(this.mediaStream.currentTime, 0,
is(this.mediaElement.currentTime, 0,
"Before starting the media element, currentTime = 0");
}

View File

@ -14,13 +14,13 @@ skip-if = toolkit == "gonk"
[test_tcpsocket_enabled_with_perm.html]
skip-if = toolkit == "gonk" || e10s
[test_networkstats_alarms.html]
skip-if = true # Bug 958689
skip-if = toolkit != "gonk"
[test_networkstats_basics.html]
skip-if = true # Bug 958689, bug 858005
skip-if = toolkit != "gonk"
[test_networkstats_disabled.html]
skip-if = toolkit != "gonk"
[test_networkstats_enabled_no_perm.html]
skip-if = true # Bug 958689
skip-if = toolkit != "gonk"
[test_networkstats_enabled_perm.html]
skip-if = toolkit != "gonk"
[test_udpsocket.html]

View File

@ -149,7 +149,6 @@ var steps = [
},
function () {
ok(true, "all done!\n");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
return;
}
@ -170,21 +169,23 @@ function next() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.addPermission("networkstats-manage", true, document);
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 1, 'context': window.document }],
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
test();
test();
});
});
</script>

View File

@ -301,7 +301,6 @@ var steps = [
},
function () {
ok(true, "all done!\n");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
return;
}
@ -322,21 +321,23 @@ function next() {
SimpleTest.waitForExplicitFinish();
SpecialPowers.addPermission("networkstats-manage", true, document);
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 1, 'context': window.document }],
function() {
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
test();
test();
});
});
</script>

View File

@ -15,10 +15,12 @@
// Test to ensure NetworkStats is enabled but mozNetworkStats.getAvailableNetworks
// does not work in content because mozNetworkStats is null when no permission.
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({"set": [['dom.mozNetworkStats.enabled', true]]}, runTest);
function runTest() {
SpecialPowers.removePermission("networkstats-manage", document);
SpecialPowers.pushPrefEnv({"set": [['dom.mozNetworkStats.enabled', true]]},
function() {
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 0, 'context': window.document }], runTest);
});
function runTest() {
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");

View File

@ -16,23 +16,25 @@
SimpleTest.waitForExplicitFinish();
// Test to ensure NetworkStats is not accessible when it is disabled
SpecialPowers.addPermission("networkstats-manage", true, document);
// Test to ensure NetworkStats is not accessible when it is disabled.
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]},
function(){
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
function() {
SpecialPowers.pushPermissions([{ 'type': 'networkstats-manage', 'allow': 1, 'context': window.document }],
function() {
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");
ok(SpecialPowers.hasPermission("networkstats-manage", document),
"Has permission 'networkstats-manage'.");
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
ok(SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled"),
"Preference 'dom.mozNetworkStats.enabled' is true.");
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
SimpleTest.finish();
});
});
</script>

View File

@ -194,21 +194,64 @@ let SNEP = (function() {
function toggleNFC(enabled) {
let deferred = Promise.defer();
let promise;
if (enabled) {
promise = nfc.startPoll();
} else {
promise = nfc.powerOff();
}
// In bug 1109592, nfcd will only run when nfc is enabled.
// The way we activate/deactivate nfcd is by using set property "ctl.start" & "ctl.stop".
// In emulator it seems sometimes enable/disable NFC too quick will cause nfcd won't starat,
// So here we use a simple workaround to delay enable or disable for 100ms, bug 1164786 is
// created to track this issue.
setTimeout(function() {
let promise;
if (enabled) {
promise = nfc.startPoll();
} else {
promise = nfc.powerOff();
}
promise.then(() => {
promise.then(() => {
deferred.resolve();
}).catch(() => {
ok(false, 'operation failed, error ' + req.error.name);
deferred.reject();
finish();
});
}, 100);
return deferred.promise;
}
function activateAndwaitForTechDiscovered(re) {
let deferred = Promise.defer();
sysMsgHelper.waitForTechDiscovered(function() {
deferred.resolve();
}).catch(() => {
ok(false, 'operation failed, error ' + req.error.name);
deferred.reject();
finish();
});
NCI.activateRE(re);
return deferred.promise;
}
function deactivateAndWaitForTechLost() {
let deferred = Promise.defer();
sysMsgHelper.waitForTechLost(function() {
deferred.resolve();
});
NCI.deactivate();
return deferred.promise;
}
function deactivateAndWaitForPeerLost() {
let deferred = Promise.defer();
nfc.onpeerlost = function() {
deferred.resolve();
};
NCI.deactivate();
return deferred.promise;
}

View File

@ -6,7 +6,7 @@
/* globals log, is, ok, runTests, toggleNFC, runNextTest,
SpecialPowers, nfc */
const MARIONETTE_TIMEOUT = 30000;
const MARIONETTE_TIMEOUT = 60000;
const MARIONETTE_HEAD_JS = 'head.js';
const MANIFEST_URL = 'app://system.gaiamobile.org/manifest.webapp';
@ -18,7 +18,7 @@ const FAKE_MANIFEST_URL = 'app://fake.gaiamobile.org/manifest.webapp';
*/
function testNoTargetNoSessionToken() {
log('testNoTargetNoSessionToken');
fireCheckP2PReg(MANIFEST_URL)
nfc.checkP2PRegistration(MANIFEST_URL)
.then((result) => {
is(result, false, 'No target, no sesionToken, result should be false');
runNextTest();
@ -33,7 +33,7 @@ function testNoTargetNoSessionToken() {
function testWithTargetNoSessionToken() {
log('testWithTargetNoSessionToken');
registerOnpeerready()
.then(() => fireCheckP2PReg(MANIFEST_URL))
.then(() => nfc.checkP2PRegistration(MANIFEST_URL))
.then((result) => {
is(result, false,
'session token is available and it shouldnt be');
@ -50,13 +50,13 @@ function testWithTargetNoSessionToken() {
function testWithSessionTokenWithTarget() {
log('testWithSessionTokenWithTarget');
toggleNFC(true)
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
.then(registerOnpeerready)
.then(() => fireCheckP2PReg(MANIFEST_URL))
.then(() => nfc.checkP2PRegistration(MANIFEST_URL))
.then((result) => {
is(result, true, 'should be true, onpeerready reg, sessionToken set');
nfc.onpeerready = null;
return toggleNFC(false);
return deactivateAndWaitForTechLost().then(() => toggleNFC(false));
})
.then(runNextTest)
.catch(handleRejectedPromiseWithNfcOn);
@ -69,12 +69,12 @@ function testWithSessionTokenWithTarget() {
function testWithSessionTokenNoTarget() {
log('testWithSessionTokenNoTarget');
toggleNFC(true)
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
.then(() => fireCheckP2PReg(MANIFEST_URL))
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
.then(() => nfc.checkP2PRegistration(MANIFEST_URL))
.then((result) => {
is(result, false,
'session token avilable but onpeerready not registered');
return toggleNFC(false);
return deactivateAndWaitForTechLost().then(() => toggleNFC(false));
})
.then(runNextTest)
.catch(handleRejectedPromiseWithNfcOn);
@ -87,13 +87,13 @@ function testWithSessionTokenNoTarget() {
function testWithSessionTokenWrongTarget() {
log('testWithSessionTokenWrongTarget');
toggleNFC(true)
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
.then(registerOnpeerready)
.then(() => fireCheckP2PReg(FAKE_MANIFEST_URL))
.then(() => nfc.checkP2PRegistration(FAKE_MANIFEST_URL))
.then((result) => {
is(result, false, 'should be false, fake manifest, sessionToken set');
nfc.onpeerready = null;
return toggleNFC(false);
return deactivateAndWaitForTechLost().then(() => toggleNFC(false));
})
.then(runNextTest)
.catch(handleRejectedPromiseWithNfcOn);
@ -108,21 +108,6 @@ function registerOnpeerready() {
return d.promise;
}
function fireCheckP2PReg(manifestUrl) {
let deferred = Promise.defer();
let promise = nfc.checkP2PRegistration(manifestUrl);
promise.then(() => {
ok(true, 'checkP2PRegistration allways results in success');
deferred.resolve(request.result);
}).catch(() => {
ok(false, 'see NfcContentHelper.handleCheckP2PRegistrationResponse');
deferred.reject();
});
return deferred.promise;
}
function handleRejectedPromise() {
ok(false, 'Promise rejected. This should not happen');
nfc.onpeerready = null;

View File

@ -25,8 +25,9 @@ let nfcPeers = [];
function testNfcNotEnabledError() {
log('testNfcNotEnabledError');
toggleNFC(true)
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
.then(registerAndFireOnpeerready)
.then(() => deactivateAndWaitForPeerLost())
.then(() => toggleNFC(false))
.then(() => sendNDEFExpectError(nfcPeers[0]))
.then(endTest)
@ -43,13 +44,14 @@ function testNfcNotEnabledError() {
function testNfcBadSessionIdError() {
log('testNfcBadSessionIdError');
toggleNFC(true)
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
.then(registerAndFireOnpeerready)
.then(() => NCI.deactivate())
.then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0))
.then(() => activateAndwaitForTechDiscovered(emulator.P2P_RE_INDEX_0))
.then(registerAndFireOnpeerready)
// we have 2 peers in nfcPeers array, peer0 has old/invalid session token
.then(() => sendNDEFExpectError(nfcPeers[0]))
.then(() => deactivateAndWaitForPeerLost())
.then(() => toggleNFC(false))
.then(endTest)
.catch(handleRejectedPromise);
@ -65,7 +67,7 @@ function testNoErrorInTechMsg() {
let techDiscoveredHandler = function(msg) {
ok('Message handler for nfc-manager-tech-discovered');
is(msg.type, 'techDiscovered');
ok(msg.peer, 'check for correct tech type');
is(msg.errorMsg, undefined, 'Should not get error msg in tech discovered');
setAndFireTechLostHandler()
@ -108,13 +110,13 @@ function registerAndFireOnpeerready() {
function sendNDEFExpectError(peer) {
let deferred = Promise.defer();
try {
peer.sendNDEF(NDEF_MESSAGE);
peer.sendNDEF(NDEF_MESSAGE)
.then(() => {
deferred.reject();
} catch (e) {
}).catch((e) => {
ok(true, 'this should happen ' + e);
deferred.resolve();
}
});
return deferred.promise;
}
@ -124,7 +126,6 @@ function setAndFireTechLostHandler() {
let techLostHandler = function(msg) {
ok('Message handler for nfc-manager-tech-lost');
is(msg.type, 'techLost');
is(msg.errorMsg, undefined, 'Should not get error msg in tech lost');
deferred.resolve();
@ -139,7 +140,8 @@ function setAndFireTechLostHandler() {
let tests = [
testNfcNotEnabledError,
testNfcBadSessionIdError,
// This testcase is temporarily removed due to Bug 1055959, will reopen when it is fixed
// testNfcBadSessionIdError
testNoErrorInTechMsg
];

View File

@ -1,14 +1,13 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
function handleTechnologyDiscoveredRE0(msg) {
log('Received \'nfc-manager-tech-discovered\'');
is(msg.type, 'techDiscovered', 'check for correct message type');
is(msg.isP2P, 'P2P', 'check for correct tech type');
toggleNFC(false).then(runNextTest);
ok(msg.peer, 'check for correct tech type');
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
}
function testActivateRE0() {

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = 'head.js';
let tnf = NDEF.TNF_WELL_KNOWN;
@ -18,13 +18,12 @@ function handleSnep(msg) {
type: NfcUtils.fromUTF8(type),
payload: NfcUtils.fromUTF8(payload)})];
NDEF.compare(ndef, msg.records);
toggleNFC(false).then(runNextTest);
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
}
function handleTechnologyDiscoveredRE0(msg) {
log("Received 'nfc-manager-tech-discovered'");
is(msg.type, "techDiscovered", "check for correct message type");
is(msg.isP2P, "P2P", "check for correct tech type");
ok(msg.peer, "check for correct tech type");
sysMsgHelper.waitForTechDiscovered(handleSnep);
SNEP.put(SNEP.SAP_NDEF, SNEP.SAP_NDEF, 0, tnf, btoa(type), btoa(id), btoa(payload));

View File

@ -6,15 +6,14 @@ MARIONETTE_HEAD_JS = 'head.js';
function handleTechnologyLost(msg) {
log('Received \'nfc-manager-tech-lost\'');
is(msg.type, 'techLost', 'check for correct message type');
ok(true);
toggleNFC(false).then(runNextTest)
}
function handleTechnologyDiscoveredRE0(msg) {
log('Received \'nfc-manager-tech-discovered\'');
is(msg.type, 'techDiscovered', 'check for correct message type');
is(msg.isP2P, 'P2P', 'check for correct tech type');
ok(msg.peer, 'check for correct tech type');
NCI.deactivate();
}

View File

@ -28,8 +28,7 @@ function peerLostCb(evt) {
function handleTechnologyDiscoveredRE0(msg) {
log("Received \'nfc-manager-tech-discovered\'");
is(msg.type, "techDiscovered", "check for correct message type");
is(msg.isP2P, "P2P", "check for correct tech type");
ok(msg.peer, "check for correct tech type");
nfc.onpeerready = peerReadyCb;
nfc.onpeerlost = peerLostCb;
@ -39,19 +38,13 @@ function handleTechnologyDiscoveredRE0(msg) {
function handleTechnologyDiscoveredRE0ForP2PRegFailure(msg) {
log("Received \'nfc-manager-tech-discovered\'");
is(msg.type, "techDiscovered", "check for correct message type");
is(msg.isP2P, "P2P", "check for correct tech type");
ok(msg.peer, "check for correct tech type");
nfc.onpeerready = peerReadyCb;
let promise = nfc.checkP2PRegistration(INCORRECT_MANIFEST_URL);
promise.then(evt => {
is(request.result, false, "check for P2P registration result");
nfc.onpeerready = null;
NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
}).catch(() => {
ok(false, "checkP2PRegistration failed.");
nfc.checkP2PRegistration(INCORRECT_MANIFEST_URL)
.then((result) => {
is(result, false, "check for P2P registration result");
nfc.onpeerready = null;
NCI.deactivate().then(() => toggleNFC(false)).then(runNextTest);
@ -150,19 +143,19 @@ function testPeerShouldThrow() {
nfc.onpeerlost = function () {
log("testPeerShouldThrow peerlost");
try {
peer.sendNDEF(ndef);
peer.sendNDEF(ndef)
.then(() => {
ok(false, "sendNDEF should throw error");
} catch (e) {
}).catch((e) => {
ok(true, "Exception expected " + e);
}
});
try {
peer.sendFile(new Blob());
peer.sendFile(new Blob())
.then(() => {
ok(false, "sendfile should throw error");
} catch (e) {
}).catch((e) => {
ok(true, "Exception expected" + e);
}
});
nfc.onpeerready = null;
nfc.onpeerlost = null;

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
let MANIFEST_URL = "app://system.gaiamobile.org/manifest.webapp";
@ -23,16 +23,14 @@ function testSendFile() {
};
sysMsgHelper.waitForTechDiscovered(function(msg) {
let request = nfc.checkP2PRegistration(MANIFEST_URL);
request.onsuccess = function(evt) {
is(request.result, true, "check for P2P registration result");
nfc.notifyUserAcceptedP2P(MANIFEST_URL);
}
request.onerror = function() {
ok(false, "checkP2PRegistration failed.");
toggleNFC(false).then(runNextTest);
}
nfc.checkP2PRegistration(MANIFEST_URL).then(result => {
if (result) {
nfc.notifyUserAcceptedP2P(MANIFEST_URL);
} else {
ok(false, "checkP2PRegistration failed.");
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
}
});
});
toggleNFC(true).then(() => NCI.activateRE(emulator.P2P_RE_INDEX_0));
@ -43,6 +41,5 @@ let tests = [
];
SpecialPowers.pushPermissions(
[{"type": "nfc", "allow": true,
"read": true, 'write': true, context: document},
[{"type": "nfc-share", "allow": true, context: document},
{"type": "nfc-manager", 'allow': true, context: document}], runTests);

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
let url = "https://www.example.com";
@ -21,18 +21,17 @@ function sendNDEF(peer) {
emulator.run(cmd, function(result) {
is(result.pop(), "OK", "check SNEP PUT result");
NDEF.compare(ndef, NDEF.parseString(result.pop()));
toggleNFC(false).then(runNextTest);
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
});
}).catch(() => {
ok(false, "Failed to send NDEF message, error \'" + this.error + "\'");
toggleNFC(false).then(runNextTest);
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
});
}
function handleTechnologyDiscoveredRE0(msg) {
log("Received \'nfc-manager-tech-discovered\' " + JSON.stringify(msg));
is(msg.type, "techDiscovered", "check for correct message type");
is(msg.isP2P, "check for \'P2P\' in tech list");
ok(msg.peer, "techDiscovered", "check for correct message type");
sendNDEF(msg.peer);
}

View File

@ -1,7 +1,7 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
MARIONETTE_TIMEOUT = 30000;
MARIONETTE_TIMEOUT = 60000;
MARIONETTE_HEAD_JS = "head.js";
let url = "http://www.mozilla.org";
@ -16,16 +16,16 @@ function testUrlTagDiscover(re) {
sysMsgHelper.waitForTechDiscovered(function(msg) {
log("Received \'nfc-manager-tech-ndiscovered\'");
is(msg.type, "techDiscovered", "check for correct message type");
ok(msg.peer === undefined, "peer object should be undefined");
let records = Cu.waiveXrays(msg.records);
let records = msg.records;
ok(records.length > 0);
is(tnf, records[0].tnf, "check for TNF field in NDEF");
is(type, NfcUtils.toUTF8(records[0].type), "check for type field in NDEF");
is(payload, NfcUtils.toUTF8(records[0].payload), "check for payload field in NDEF");
is(type, NfcUtils.toUTF8(Cu.waiveXrays(records[0].type)), "check for type field in NDEF");
is(payload, NfcUtils.toUTF8(Cu.waiveXrays(records[0].payload)), "check for payload field in NDEF");
toggleNFC(false).then(runNextTest);
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
});
toggleNFC(true)
@ -38,12 +38,12 @@ function testEmptyTagDiscover(re) {
sysMsgHelper.waitForTechDiscovered(function(msg) {
log("Received \'nfc-manager-tech-ndiscovered\'");
is(msg.type, "techDiscovered", "check for correct message type");
ok(msg.peer === undefined, "peer object should be undefined");
let records = msg.records;
ok(records == null);
toggleNFC(false).then(runNextTest);
deactivateAndWaitForTechLost().then(() => toggleNFC(false)).then(runNextTest);
});
toggleNFC(true)

View File

@ -35,4 +35,5 @@ FINAL_LIBRARY = 'xul'
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']

View File

@ -1,7 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
[DEFAULT]
[browser_monitorUncaught.js]

View File

@ -4,6 +4,8 @@
"use strict";
const { utils: Cu } = Components;
Cu.import("resource://gre/modules/Timer.jsm", this);
add_task(function* test_globals() {
@ -18,7 +20,7 @@ add_task(function* test_promiseID() {
let promise = [p1, p2, p3];
let identifiers = promise.map(PromiseDebugging.getPromiseID);
info("Identifiers: " + JSON.stringify(identifiers));
do_print("Identifiers: " + JSON.stringify(identifiers));
let idSet = new Set(identifiers);
Assert.equal(idSet.size, identifiers.length,
"PromiseDebugging.getPromiseID returns a distinct id per promise");
@ -42,7 +44,7 @@ add_task(function* test_observe_uncaught() {
};
CallbackResults.prototype = {
observe: function(promise) {
info(this.name + " observing Promise " + names.get(promise));
do_print(this.name + " observing Promise " + names.get(promise));
Assert.equal(PromiseDebugging.getState(promise).state, "rejected",
this.name + " observed a rejected Promise");
if (!this.expected.has(promise)) {
@ -62,8 +64,8 @@ add_task(function* test_observe_uncaught() {
if (this.expected.size == 0) {
this.resolve();
} else {
info(this.name + " is still waiting for " + this.expected.size + " observations:");
info(JSON.stringify([names.get(x) for (x of this.expected.values())]));
do_print(this.name + " is still waiting for " + this.expected.size + " observations:");
do_print(JSON.stringify([names.get(x) for (x of this.expected.values())]));
}
},
};
@ -117,7 +119,7 @@ add_task(function* test_observe_uncaught() {
// Reject a promise now, consume it later.
let p = Promise.reject("Reject now, consume later");
setTimeout(() => p.then(null, () => {
info("Consumed promise");
do_print("Consumed promise");
}), 200);
yield {
promise: p,
@ -190,7 +192,7 @@ add_task(function* test_observe_uncaught() {
let samples = [];
for (let s of makeSamples()) {
samples.push(s);
info("Promise '" + s.name + "' has id " + PromiseDebugging.getPromiseID(s.promise));
do_print("Promise '" + s.name + "' has id " + PromiseDebugging.getPromiseID(s.promise));
}
PromiseDebugging.addUncaughtRejectionObserver(observer);
@ -205,17 +207,17 @@ add_task(function* test_observe_uncaught() {
}
}
info("Test setup, waiting for callbacks.");
do_print("Test setup, waiting for callbacks.");
yield onLeftUncaught.blocker;
info("All calls to onLeftUncaught are complete.");
do_print("All calls to onLeftUncaught are complete.");
if (onConsumed.expected.size != 0) {
info("onConsumed is still waiting for the following Promise:");
info(JSON.stringify([names.get(x) for (x of onConsumed.expected.values())]));
do_print("onConsumed is still waiting for the following Promise:");
do_print(JSON.stringify([names.get(x) for (x of onConsumed.expected.values())]));
yield onConsumed.blocker;
}
info("All calls to onConsumed are complete.");
do_print("All calls to onConsumed are complete.");
let removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
Assert.ok(removed, "removeUncaughtRejectionObserver succeeded");
removed = PromiseDebugging.removeUncaughtRejectionObserver(observer);
@ -246,21 +248,23 @@ add_task(function* test_uninstall_observer() {
},
};
info("Adding an observer.");
do_print("Adding an observer.");
let deactivate = new Observer();
Promise.reject("I am an uncaught rejection.");
yield deactivate.blocker;
Assert.ok(true, "The observer has observed an uncaught Promise.");
deactivate.active = false;
info("Removing the observer, it should not observe any further uncaught Promise.");
do_print("Removing the observer, it should not observe any further uncaught Promise.");
info("Rejecting a Promise and waiting a little to give a chance to observers.");
do_print("Rejecting a Promise and waiting a little to give a chance to observers.");
let wait = new Observer();
Promise.reject("I am another uncaught rejection.");
yield wait.blocker;
yield new Promise(resolve => setTimeout(resolve, 100));
// Normally, `deactivate` should not be notified of the uncaught rejection.
wait.active = false;
});
function run_test() {
run_next_test();
}

View File

@ -0,0 +1,5 @@
[DEFAULT]
head =
tail =
[test_monitor_uncaught.js]

View File

@ -12,10 +12,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=678695
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678695">Mozilla Bug 678695</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SpecialPowers.addPermission("settings-api-read", true, document);
SpecialPowers.addPermission("settings-api-write", true, document);
SpecialPowers.addPermission("settings-read", true, document);
SpecialPowers.addPermission("settings-write", true, document);
/** Test for Bug 678695 **/

View File

@ -649,6 +649,17 @@ NetworkService.prototype = {
});
},
stopDhcp: function(interfaceName, callback) {
let params = {
cmd: "stopDhcp",
ifname: interfaceName
};
this.controlMessage(params, function(result) {
callback.nativeCommandResult(!result.error);
});
},
enableInterface: function(interfaceName, callback) {
let params = {
cmd: "enableInterface",

View File

@ -1615,6 +1615,7 @@ void NetworkUtils::ExecuteCommand(NetworkParams aOptions)
BUILD_ENTRY(updateUpStream),
BUILD_ENTRY(configureInterface),
BUILD_ENTRY(dhcpRequest),
BUILD_ENTRY(stopDhcp),
BUILD_ENTRY(enableInterface),
BUILD_ENTRY(disableInterface),
BUILD_ENTRY(resetConnections),
@ -1833,6 +1834,11 @@ CommandResult NetworkUtils::configureInterface(NetworkParams& aOptions)
);
}
CommandResult NetworkUtils::stopDhcp(NetworkParams& aOptions)
{
return mNetUtils->do_dhcp_stop(GET_CHAR(mIfname));
}
CommandResult NetworkUtils::dhcpRequest(NetworkParams& aOptions) {
mozilla::dom::NetworkResultOptions result;

View File

@ -287,6 +287,7 @@ private:
*/
CommandResult configureInterface(NetworkParams& aOptions);
CommandResult dhcpRequest(NetworkParams& aOptions);
CommandResult stopDhcp(NetworkParams& aOptions);
CommandResult enableInterface(NetworkParams& aOptions);
CommandResult disableInterface(NetworkParams& aOptions);
CommandResult resetConnections(NetworkParams& aOptions);

View File

@ -159,7 +159,7 @@ interface nsIDhcpRequestCallback : nsISupports
/**
* Provide network services.
*/
[scriptable, uuid(8216224c-a4e0-43fa-9662-3f2446b500c6)]
[scriptable, uuid(214c0810-fd41-11e4-b939-0800200c9a66)]
interface nsINetworkService : nsISupports
{
const long MODIFY_ROUTE_ADD = 0;
@ -417,6 +417,18 @@ interface nsINetworkService : nsISupports
void dhcpRequest(in DOMString interfaceName,
in nsIDhcpRequestCallback callback);
/**
* Stop Dhcp daemon.
*
* @param ifname
* Target interface.
*
* @param callback
* Callback to notify the result of stopping dhcp request.
*/
void stopDhcp(in DOMString ifname,
in nsINativeCommandCallback callback);
/**
* Enable a network interface.
*

View File

@ -375,10 +375,14 @@ Telephony::HandleCallInfo(nsITelephonyCallInfo* aInfo)
nsRefPtr<TelephonyCallId> id = call->Id();
id->UpdateNumber(number);
nsAutoString disconnectedReason;
aInfo->GetDisconnectedReason(disconnectedReason);
// State changed.
if (call->CallState() != callState) {
if (callState == nsITelephonyService::CALL_STATE_DISCONNECTED) {
call->ChangeStateInternal(callState, true);
call->UpdateDisconnectedReason(disconnectedReason);
call->ChangeState(nsITelephonyService::CALL_STATE_DISCONNECTED);
return NS_OK;
}
@ -687,26 +691,6 @@ Telephony::SupplementaryServiceNotification(uint32_t aServiceId,
return NS_OK;
}
NS_IMETHODIMP
Telephony::NotifyError(uint32_t aServiceId,
int32_t aCallIndex,
const nsAString& aError)
{
nsRefPtr<TelephonyCall> callToNotify =
GetCallFromEverywhere(aServiceId, aCallIndex);
if (!callToNotify) {
NS_ERROR("Don't call me with a bad call index!");
return NS_ERROR_UNEXPECTED;
}
// Set the call state to 'disconnected' and remove it from the calls list.
callToNotify->UpdateDisconnectedReason(aError);
callToNotify->NotifyError(aError);
callToNotify->ChangeState(nsITelephonyService::CALL_STATE_DISCONNECTED);
return NS_OK;
}
NS_IMETHODIMP
Telephony::NotifyCdmaCallWaiting(uint32_t aServiceId, const nsAString& aNumber,
uint16_t aNumberPresentation,

View File

@ -119,7 +119,6 @@ TelephonyCall::ChangeStateInternal(uint16_t aCallState, bool aFireEvents)
} else {
mTelephony->RemoveCall(this);
}
UpdateDisconnectedReason(NS_LITERAL_STRING("NormalCallClearingError"));
} else if (!mLive) {
mLive = true;
if (mGroup) {
@ -196,16 +195,23 @@ TelephonyCall::NotifyError(const nsAString& aError)
void
TelephonyCall::UpdateDisconnectedReason(const nsAString& aDisconnectedReason)
{
NS_ASSERTION(Substring(aDisconnectedReason, aDisconnectedReason.Length() - 5).EqualsLiteral("Error"),
NS_ASSERTION(Substring(aDisconnectedReason,
aDisconnectedReason.Length() - 5).EqualsLiteral("Error"),
"Disconnected reason should end with 'Error'");
if (mDisconnectedReason.IsNull()) {
// There is no 'Error' suffix in the corresponding enum. We should skip
// that part for comparison.
CONVERT_STRING_TO_NULLABLE_ENUM(
Substring(aDisconnectedReason, 0, aDisconnectedReason.Length() - 5),
TelephonyCallDisconnectedReason,
mDisconnectedReason);
if (!mDisconnectedReason.IsNull()) {
return;
}
// There is no 'Error' suffix in the corresponding enum. We should skip
// that part for comparison.
CONVERT_STRING_TO_NULLABLE_ENUM(
Substring(aDisconnectedReason, 0, aDisconnectedReason.Length() - 5),
TelephonyCallDisconnectedReason,
mDisconnectedReason);
if (!aDisconnectedReason.EqualsLiteral("NormalCallClearingError")) {
NotifyError(aDisconnectedReason);
}
}

View File

@ -15,10 +15,13 @@ NS_IMPL_ISUPPORTS(TelephonyCallInfo, nsITelephonyCallInfo)
TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId,
uint32_t aCallIndex,
uint16_t aCallState,
const nsAString& aDisconnectedReason,
const nsAString& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation,
bool aIsOutgoing,
bool aIsEmergency,
bool aIsConference,
@ -27,10 +30,13 @@ TelephonyCallInfo::TelephonyCallInfo(uint32_t aClientId,
: mClientId(aClientId),
mCallIndex(aCallIndex),
mCallState(aCallState),
mDisconnectedReason(aDisconnectedReason),
mNumber(aNumber),
mNumberPresentation(aNumberPresentation),
mName(aName),
mNamePresentation(aNamePresentation),
mIsOutgoing(aIsOutgoing),
mIsEmergency(aIsEmergency),
mIsConference(aIsConference),
@ -60,6 +66,13 @@ TelephonyCallInfo::GetCallState(uint16_t* aCallState)
return NS_OK;
}
NS_IMETHODIMP
TelephonyCallInfo::GetDisconnectedReason(nsAString& aDisconnectedReason)
{
aDisconnectedReason = mDisconnectedReason;
return NS_OK;
}
NS_IMETHODIMP
TelephonyCallInfo::GetNumber(nsAString& aNumber)
{

View File

@ -21,12 +21,21 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSITELEPHONYCALLINFO
TelephonyCallInfo(uint32_t aClientId, uint32_t aCallIndex,
uint16_t aCallState, const nsAString& aNumber,
uint16_t aNumberPresentation, const nsAString& aName,
uint16_t aNamePresentation, bool aIsOutgoing,
bool aIsEmergency, bool aIsConference,
bool aIsSwitchable, bool aIsMergeable);
TelephonyCallInfo(uint32_t aClientId,
uint32_t aCallIndex,
uint16_t aCallState,
const nsAString& aDisconnectedReason,
const nsAString& aNumber,
uint16_t aNumberPresentation,
const nsAString& aName,
uint16_t aNamePresentation,
bool aIsOutgoing,
bool aIsEmergency,
bool aIsConference,
bool aIsSwitchable,
bool aIsMergeable);
private:
// Don't try to use the default constructor.
@ -37,10 +46,13 @@ private:
uint32_t mClientId;
uint32_t mCallIndex;
uint16_t mCallState;
nsString mDisconnectedReason;
nsString mNumber;
uint16_t mNumberPresentation;
nsString mName;
uint16_t mNamePresentation;
bool mIsOutgoing;
bool mIsEmergency;
bool mIsConference;

View File

@ -124,10 +124,13 @@ function TelephonyCallInfo(aCall) {
this.clientId = aCall.clientId;
this.callIndex = aCall.callIndex;
this.callState = aCall.state;
this.disconnectedReason = aCall.disconnectedReason || "";
this.number = aCall.number;
this.numberPresentation = aCall.numberPresentation;
this.name = aCall.name;
this.namePresentation = aCall.namePresentation;
this.isOutgoing = aCall.isOutgoing;
this.isEmergency = aCall.isEmergency;
this.isConference = aCall.isConference;
@ -148,10 +151,13 @@ TelephonyCallInfo.prototype = {
clientId: 0,
callIndex: 0,
callState: nsITelephonyService.CALL_STATE_UNKNOWN,
disconnectedReason: "",
number: "",
numberPresentation: nsITelephonyService.CALL_PRESENTATION_ALLOWED,
name: "",
namePresentation: nsITelephonyService.CALL_PRESENTATION_ALLOWED,
isOutgoing: true,
isEmergency: false,
isConference: false,
@ -1438,10 +1444,6 @@ TelephonyService.prototype = {
* calls being disconnected as well.
*
* @return Array a list of calls we need to fire callStateChange
*
* TODO: The list currently doesn't contain calls that we fire notifyError
* for them. However, after Bug 1147736, notifyError is replaced by
* callStateChanged and those calls should be included in the list.
*/
_disconnectCalls: function(aClientId, aCalls,
aFailCause = RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) {
@ -1465,7 +1467,7 @@ TelephonyService.prototype = {
disconnectedCalls.forEach(call => {
call.state = nsITelephonyService.CALL_STATE_DISCONNECTED;
call.failCause = aFailCause;
call.disconnectedReason = aFailCause;
if (call.parentId) {
let parentCall = this._currentCalls[aClientId][call.parentId];
@ -1474,13 +1476,7 @@ TelephonyService.prototype = {
this._notifyCallEnded(call);
if (call.hangUpLocal || !call.failCause ||
call.failCause === RIL.GECKO_CALL_ERROR_NORMAL_CALL_CLEARING) {
callsForStateChanged.push(call);
} else {
this._notifyAllListeners("notifyError",
[aClientId, call.callIndex, call.failCause]);
}
callsForStateChanged.push(call);
delete this._currentCalls[aClientId][call.callIndex];
});

View File

@ -125,8 +125,6 @@ sync protocol PTelephony {
manages PTelephonyRequest;
child:
NotifyCallError(uint32_t aClientId, int32_t aCallIndex, nsString aError);
NotifyCallStateChanged(nsTelephonyCallInfo[] aAllInfo);
NotifyCdmaCallWaiting(uint32_t aClientId, IPCCdmaWaitingCallData aData);

View File

@ -47,17 +47,6 @@ TelephonyChild::DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor)
return true;
}
bool
TelephonyChild::RecvNotifyCallError(const uint32_t& aClientId,
const int32_t& aCallIndex,
const nsString& aError)
{
MOZ_ASSERT(mService);
mService->NotifyError(aClientId, aCallIndex, aError);
return true;
}
bool
TelephonyChild::RecvNotifyCallStateChanged(nsTArray<nsITelephonyCallInfo*>&& aAllInfo)
{

View File

@ -34,10 +34,6 @@ protected:
virtual bool
DeallocPTelephonyRequestChild(PTelephonyRequestChild* aActor) override;
virtual bool
RecvNotifyCallError(const uint32_t& aClientId, const int32_t& aCallIndex,
const nsString& aError) override;
virtual bool
RecvNotifyCallStateChanged(nsTArray<nsITelephonyCallInfo*>&& aAllInfo) override;

View File

@ -37,10 +37,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
uint32_t clientId;
uint32_t callIndex;
uint16_t callState;
nsString disconnectedReason;
nsString number;
uint16_t numberPresentation;
nsString name;
uint16_t namePresentation;
bool isOutgoing;
bool isEmergency;
bool isConference;
@ -50,10 +53,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
aParam->GetClientId(&clientId);
aParam->GetCallIndex(&callIndex);
aParam->GetCallState(&callState);
aParam->GetDisconnectedReason(disconnectedReason);
aParam->GetNumber(number);
aParam->GetNumberPresentation(&numberPresentation);
aParam->GetName(name);
aParam->GetNamePresentation(&namePresentation);
aParam->GetIsOutgoing(&isOutgoing);
aParam->GetIsEmergency(&isEmergency);
aParam->GetIsConference(&isConference);
@ -63,10 +69,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
WriteParam(aMsg, clientId);
WriteParam(aMsg, callIndex);
WriteParam(aMsg, callState);
WriteParam(aMsg, disconnectedReason);
WriteParam(aMsg, number);
WriteParam(aMsg, numberPresentation);
WriteParam(aMsg, name);
WriteParam(aMsg, namePresentation);
WriteParam(aMsg, isOutgoing);
WriteParam(aMsg, isEmergency);
WriteParam(aMsg, isConference);
@ -90,10 +99,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
uint32_t clientId;
uint32_t callIndex;
uint16_t callState;
nsString disconnectedReason;
nsString number;
uint16_t numberPresentation;
nsString name;
uint16_t namePresentation;
bool isOutgoing;
bool isEmergency;
bool isConference;
@ -104,10 +116,13 @@ struct ParamTraits<nsITelephonyCallInfo*>
if (!(ReadParam(aMsg, aIter, &clientId) &&
ReadParam(aMsg, aIter, &callIndex) &&
ReadParam(aMsg, aIter, &callState) &&
ReadParam(aMsg, aIter, &disconnectedReason) &&
ReadParam(aMsg, aIter, &number) &&
ReadParam(aMsg, aIter, &numberPresentation) &&
ReadParam(aMsg, aIter, &name) &&
ReadParam(aMsg, aIter, &namePresentation) &&
ReadParam(aMsg, aIter, &isOutgoing) &&
ReadParam(aMsg, aIter, &isEmergency) &&
ReadParam(aMsg, aIter, &isConference) &&
@ -117,10 +132,21 @@ struct ParamTraits<nsITelephonyCallInfo*>
}
nsCOMPtr<nsITelephonyCallInfo> info =
new TelephonyCallInfo(clientId, callIndex, callState, number,
numberPresentation, name, namePresentation,
isOutgoing, isEmergency, isConference,
isSwitchable, isMergeable);
new TelephonyCallInfo(clientId,
callIndex,
callState,
disconnectedReason,
number,
numberPresentation,
name,
namePresentation,
isOutgoing,
isEmergency,
isConference,
isSwitchable,
isMergeable);
info.forget(aResult);

View File

@ -421,16 +421,6 @@ TelephonyIPCService::NotifyConferenceError(const nsAString& aName,
return NS_OK;
}
NS_IMETHODIMP
TelephonyIPCService::NotifyError(uint32_t aClientId, int32_t aCallIndex,
const nsAString& aError)
{
for (uint32_t i = 0; i < mListeners.Length(); i++) {
mListeners[i]->NotifyError(aClientId, aCallIndex, aError);
}
return NS_OK;
}
NS_IMETHODIMP
TelephonyIPCService::SupplementaryServiceNotification(uint32_t aClientId,
int32_t aCallIndex,

View File

@ -331,17 +331,6 @@ TelephonyParent::NotifyConferenceError(const nsAString& aName,
: NS_ERROR_FAILURE;
}
NS_IMETHODIMP
TelephonyParent::NotifyError(uint32_t aClientId,
int32_t aCallIndex,
const nsAString& aError)
{
NS_ENSURE_TRUE(!mActorDestroyed, NS_ERROR_FAILURE);
return SendNotifyCallError(aClientId, aCallIndex, nsString(aError))
? NS_OK : NS_ERROR_FAILURE;
}
NS_IMETHODIMP
TelephonyParent::SupplementaryServiceNotification(uint32_t aClientId,
int32_t aCallIndex,
@ -431,14 +420,6 @@ TelephonyRequestParent::NotifyConferenceError(const nsAString& aName,
MOZ_CRASH("Not a TelephonyParent!");
}
NS_IMETHODIMP
TelephonyRequestParent::NotifyError(uint32_t aClientId,
int32_t aCallIndex,
const nsAString& aError)
{
MOZ_CRASH("Not a TelephonyParent!");
}
NS_IMETHODIMP
TelephonyRequestParent::SupplementaryServiceNotification(uint32_t aClientId,
int32_t aCallIndex,

View File

@ -4,7 +4,7 @@
#include "nsISupports.idl"
[scriptable, uuid(3ea2d155-8ea2-42be-85d7-bd8ede8afc40)]
[scriptable, uuid(e5e1be26-a3d4-49b3-8d9f-c1df5192b364)]
interface nsITelephonyCallInfo : nsISupports
{
/**
@ -22,6 +22,14 @@ interface nsITelephonyCallInfo : nsISupports
*/
readonly attribute unsigned short callState;
/**
* The disconnectedReason of a call is defualt to an empty string when the
* call is "not disconnected", but once the call becomes "disconnected" the
* disconnectedReason should be a non-empty string no matter the call is
* disconnected for a noraml reason or an error.
*/
readonly attribute DOMString disconnectedReason;
/**
* Number of the other party.
*/

View File

@ -7,7 +7,7 @@
interface nsIMobileCallForwardingOptions;
interface nsITelephonyCallInfo;
[scriptable, uuid(37fb45bb-ae10-4cfd-b24e-d656a9787a0a)]
[scriptable, uuid(80faf34e-286b-4487-bd55-135bd92668b9)]
interface nsITelephonyListener : nsISupports
{
/**
@ -54,20 +54,6 @@ interface nsITelephonyListener : nsISupports
in long callIndex,
in unsigned short notification);
/**
* Called when RIL error occurs.
*
* @param clientId
Indicate the RIL client, 0 ~ (number of client - 1).
* @param callIndex
* Call identifier assigned by the RIL. -1 if no connection
* @param error
* Error from RIL.
*/
void notifyError(in unsigned long clientId,
in long callIndex,
in AString error);
/**
* Called when a waiting call comes in CDMA networks.
*

View File

@ -53,9 +53,6 @@ NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistrationBase, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationBase)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationBase,
DOMEventTargetHelper, mCCDummy);
ServiceWorkerRegistrationBase::ServiceWorkerRegistrationBase(nsPIDOMWindow* aWindow,
const nsAString& aScope)
: DOMEventTargetHelper(aWindow)

View File

@ -66,8 +66,6 @@ class ServiceWorkerRegistrationBase : public DOMEventTargetHelper
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistrationBase,
DOMEventTargetHelper)
IMPL_EVENT_HANDLER(updatefound)
@ -91,8 +89,6 @@ protected:
{ }
const nsString mScope;
private:
nsCOMPtr<nsISupports> mCCDummy;
};
class ServiceWorkerRegistrationMainThread final : public ServiceWorkerRegistrationBase,
@ -120,10 +116,10 @@ public:
already_AddRefed<workers::ServiceWorker>
GetWaiting() override;
already_AddRefed<workers::ServiceWorker>
GetActive() override;
already_AddRefed<PushManager>
GetPushManager(ErrorResult& aRv);

View File

@ -969,7 +969,8 @@ GLBlitHelper::BlitFramebufferToTexture(GLuint srcFB, GLuint destTex,
GLenum destTarget,
bool internalFBs)
{
MOZ_ASSERT(!srcFB || mGL->fIsFramebuffer(srcFB));
// On the Android 4.3 emulator, IsFramebuffer may return false incorrectly.
MOZ_ASSERT_IF(mGL->Renderer() != GLRenderer::AndroidEmulator, !srcFB || mGL->fIsFramebuffer(srcFB));
MOZ_ASSERT(mGL->fIsTexture(destTex));
if (mGL->IsSupported(GLFeature::framebuffer_blit)) {

View File

@ -417,7 +417,7 @@ LayerManagerComposite::RenderDebugOverlay(const Rect& aBounds)
// Draw a translation delay warning overlay
int width;
int border;
if ((now - mWarnTime).ToMilliseconds() < kVisualWarningDuration) {
if (!mWarnTime.IsNull() && (now - mWarnTime).ToMilliseconds() < kVisualWarningDuration) {
EffectChain effects;
// Black blorder

View File

@ -14,6 +14,10 @@
#include "gfx2DGlue.h"
#include "SharedSurfaceGralloc.h"
#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
#include <ui/Fence.h>
#endif
namespace mozilla {
namespace layers {

View File

@ -0,0 +1,57 @@
/* -*- 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/. */
#include "gtest/gtest.h"
#include "GfxDriverInfo.h"
#include "nsVersionComparator.h"
using namespace mozilla::widget;
TEST(GfxWidgets, Split) {
char aStr[8], bStr[8], cStr[8], dStr[8];
ASSERT_TRUE(SplitDriverVersion("33.4.3.22", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 33 && atoi(bStr) == 4 && atoi(cStr) == 3 && atoi(dStr) == 22);
ASSERT_TRUE(SplitDriverVersion("28.74.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 28 && atoi(bStr) == 74 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("132.0.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 132 && atoi(bStr) == 0 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("2.3.0.0", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 2 && atoi(bStr) == 3 && atoi(cStr) == 0 && atoi(dStr) == 0);
ASSERT_TRUE(SplitDriverVersion("25.4.0.8", aStr, bStr, cStr, dStr));
ASSERT_TRUE(atoi(aStr) == 25 && atoi(bStr) == 4 && atoi(cStr) == 0 && atoi(dStr) == 8);
}
TEST(GfxWidgets, Versioning) {
ASSERT_TRUE(mozilla::Version("0") < mozilla::Version("41.0a1"));
ASSERT_TRUE(mozilla::Version("39.0.5b7") < mozilla::Version("41.0a1"));
ASSERT_TRUE(mozilla::Version("18.0.5b7") < mozilla::Version("18.2"));
ASSERT_TRUE(mozilla::Version("30.0.5b7") < mozilla::Version("41.0b9"));
ASSERT_TRUE(mozilla::Version("100") > mozilla::Version("43.0a1"));
ASSERT_FALSE(mozilla::Version("42.0") < mozilla::Version("42.0"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("42.0"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("42"));
ASSERT_TRUE(mozilla::Version("42.0b2") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0.5") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.1") < mozilla::Version("43.0a1"));
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42"));
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42.0.5"));
ASSERT_TRUE(mozilla::Version("42.0b7") < mozilla::Version("42.0.5"));
ASSERT_TRUE(mozilla::Version("") == mozilla::Version("0"));
// Note these two; one would expect for 42.0b1 and 42b1 to compare the
// same, but they do not. If this ever changes, we want to know, so
// leave the test here to fail.
ASSERT_TRUE(mozilla::Version("42.0a1") < mozilla::Version("42.0b2"));
ASSERT_FALSE(mozilla::Version("42.0a1") < mozilla::Version("42b2"));
}

View File

@ -13,6 +13,7 @@ UNIFIED_SOURCES += [
'TestColorNames.cpp',
'TestCompositor.cpp',
'TestGfxPrefs.cpp',
'TestGfxWidgets.cpp',
'TestLayers.cpp',
'TestRegion.cpp',
'TestSkipChars.cpp',

78
image/ImageCacheKey.cpp Normal file
View File

@ -0,0 +1,78 @@
/* -*- 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/. */
#include "ImageCacheKey.h"
#include "mozilla/Move.h"
#include "File.h"
#include "ImageURL.h"
#include "nsHostObjectProtocolHandler.h"
#include "nsString.h"
namespace mozilla {
using namespace dom;
namespace image {
ImageCacheKey::ImageCacheKey(nsIURI* aURI)
: mURI(new ImageURL(aURI))
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
mHash = ComputeHash(mURI);
}
ImageCacheKey::ImageCacheKey(ImageURL* aURI)
: mURI(aURI)
{
MOZ_ASSERT(mURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
mHash = ComputeHash(mURI);
}
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
: mURI(aOther.mURI)
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
: mURI(Move(aOther.mURI))
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
bool
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
{
return *mURI == *aOther.mURI;
}
const char*
ImageCacheKey::Spec() const
{
return mURI->Spec();
}
/* static */ uint32_t
ImageCacheKey::ComputeHash(ImageURL* aURI)
{
// Since we frequently call Hash() several times in a row on the same
// ImageCacheKey, as an optimization we compute our hash once and store it.
nsAutoCString spec;
aURI->GetSpec(spec);
return HashString(spec);
}
} // namespace image
} // namespace mozilla

55
image/ImageCacheKey.h Normal file
View File

@ -0,0 +1,55 @@
/* -*- 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/. */
/**
* ImageCacheKey is the key type for the image cache (see imgLoader.h).
*/
#ifndef mozilla_image_src_ImageCacheKey_h
#define mozilla_image_src_ImageCacheKey_h
class nsIURI;
namespace mozilla {
namespace image {
class ImageURL;
/**
* An ImageLib cache entry key.
*
* We key the cache on the initial URI (before any redirects), with some
* canonicalization applied. See ComputeHash() for the details.
*/
class ImageCacheKey final
{
public:
explicit ImageCacheKey(nsIURI* aURI);
explicit ImageCacheKey(ImageURL* aURI);
ImageCacheKey(const ImageCacheKey& aOther);
ImageCacheKey(ImageCacheKey&& aOther);
bool operator==(const ImageCacheKey& aOther) const;
uint32_t Hash() const { return mHash; }
/// A weak pointer to the URI spec for this cache entry. For logging only.
const char* Spec() const;
/// Is this cache entry for a chrome image?
bool IsChrome() const { return mIsChrome; }
private:
static uint32_t ComputeHash(ImageURL* aURI);
nsRefPtr<ImageURL> mURI;
uint32_t mHash;
bool mIsChrome;
};
} // namespace image
} // namespace mozilla
#endif // mozilla_image_src_ImageCacheKey_h

View File

@ -44,6 +44,9 @@ public:
return NS_OK;
}
/// A weak pointer to the URI spec for this ImageURL. For logging only.
const char* Spec() const { return mSpec.get(); }
nsresult GetScheme(nsACString& result)
{
result = mScheme;
@ -74,6 +77,13 @@ public:
return newURI.forget();
}
bool operator==(const ImageURL& aOther) const
{
// Note that we don't need to consider mScheme and mRef, because they're
// already represented in mSpec.
return mSpec == aOther.mSpec;
}
private:
// Since this is a basic storage class, no duplication of spec parsing is
// included in the functionality. Instead, the class depends upon the

View File

@ -549,9 +549,10 @@ nsProgressNotificationProxy::GetInterface(const nsIID& iid,
static void
NewRequestAndEntry(bool aForcePrincipalCheckForCacheEntry, imgLoader* aLoader,
const ImageCacheKey& aKey,
imgRequest** aRequest, imgCacheEntry** aEntry)
{
nsRefPtr<imgRequest> request = new imgRequest(aLoader);
nsRefPtr<imgRequest> request = new imgRequest(aLoader, aKey);
nsRefPtr<imgCacheEntry> entry =
new imgCacheEntry(aLoader, request, aForcePrincipalCheckForCacheEntry);
aLoader->AddToUncachedImages(request);
@ -894,18 +895,12 @@ void
imgCacheEntry::SetHasNoProxies(bool hasNoProxies)
{
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<ImageURL> uri;
mRequest->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
if (uri) {
uri->GetSpec(spec);
}
if (hasNoProxies) {
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgCacheEntry::SetHasNoProxies true",
"uri", spec.get());
"uri", mRequest->CacheKey().Spec());
} else {
LOG_FUNC_WITH_PARAM(GetImgLog(), "imgCacheEntry::SetHasNoProxies false",
"uri", spec.get());
"uri", mRequest->CacheKey().Spec());
}
}
@ -1078,15 +1073,11 @@ imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry)
nsRefPtr<imgCacheEntry> kungFuDeathGrip(entry);
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<imgRequest> req(entry->GetRequest());
nsRefPtr<imgRequest> req = entry->GetRequest();
if (req) {
nsRefPtr<ImageURL> uri;
req->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_FUNC_WITH_PARAM(GetImgLog(),
"imgCacheExpirationTracker::NotifyExpired",
"entry", spec.get());
"entry", req->CacheKey().Spec());
}
}
@ -1100,60 +1091,6 @@ imgCacheExpirationTracker::NotifyExpired(imgCacheEntry* entry)
}
///////////////////////////////////////////////////////////////////////////////
// ImageCacheKey
///////////////////////////////////////////////////////////////////////////////
ImageCacheKey::ImageCacheKey(nsIURI* aURI)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
aURI->GetSpec(mSpec);
mHash = ComputeHash(mSpec);
}
ImageCacheKey::ImageCacheKey(ImageURL* aURI)
{
MOZ_ASSERT(aURI);
bool isChrome;
mIsChrome = NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome;
aURI->GetSpec(mSpec);
mHash = ComputeHash(mSpec);
}
ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
: mSpec(aOther.mSpec)
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
: mSpec(Move(aOther.mSpec))
, mHash(aOther.mHash)
, mIsChrome(aOther.mIsChrome)
{ }
bool
ImageCacheKey::operator==(const ImageCacheKey& aOther) const
{
return mSpec == aOther.mSpec;
}
/* static */ uint32_t
ImageCacheKey::ComputeHash(const nsACString& aSpec)
{
// Since we frequently call Hash() several times in a row on the same
// ImageCacheKey, as an optimization we compute our hash once and store it.
return HashString(aSpec);
}
///////////////////////////////////////////////////////////////////////////////
// imgLoader
///////////////////////////////////////////////////////////////////////////////
@ -1513,15 +1450,9 @@ imgLoader::PutIntoCache(const ImageCacheKey& aKey, imgCacheEntry* entry)
bool
imgLoader::SetHasNoProxies(imgRequest* aRequest, imgCacheEntry* aEntry)
{
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<ImageURL> uri;
aRequest->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::SetHasNoProxies", "uri", spec.get());
}
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::SetHasNoProxies", "uri",
aRequest->CacheKey().Spec());
aEntry->SetHasNoProxies(true);
@ -1552,10 +1483,7 @@ imgLoader::SetHasProxies(imgRequest* aRequest)
{
VerifyCacheSizes();
nsRefPtr<ImageURL> uri;
aRequest->GetURI(getter_AddRefs(uri));
ImageCacheKey key(uri);
const ImageCacheKey& key = aRequest->CacheKey();
imgCacheTable& cache = GetCache(key);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
@ -1606,15 +1534,11 @@ imgLoader::CheckCacheLimits(imgCacheTable& cache, imgCacheQueue& queue)
NS_ASSERTION(entry, "imgLoader::CheckCacheLimits -- NULL entry pointer");
if (PR_LOG_TEST(GetImgLog(), PR_LOG_DEBUG)) {
nsRefPtr<imgRequest> req(entry->GetRequest());
nsRefPtr<imgRequest> req = entry->GetRequest();
if (req) {
nsRefPtr<ImageURL> uri;
req->GetURI(getter_AddRefs(uri));
nsAutoCString spec;
uri->GetSpec(spec);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::CheckCacheLimits",
"entry", spec.get());
"entry", req->CacheKey().Spec());
}
}
@ -1932,36 +1856,30 @@ imgLoader::RemoveFromCache(imgCacheEntry* entry)
nsRefPtr<imgRequest> request = entry->GetRequest();
if (request) {
nsRefPtr<ImageURL> uri;
if (NS_SUCCEEDED(request->GetURI(getter_AddRefs(uri))) && uri) {
ImageCacheKey key(uri);
const ImageCacheKey& key = request->CacheKey();
imgCacheTable& cache = GetCache(key);
imgCacheQueue& queue = GetCacheQueue(key);
imgCacheTable& cache = GetCache(key);
imgCacheQueue& queue = GetCacheQueue(key);
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::RemoveFromCache", "entry's uri",
key.Spec());
#ifdef DEBUG
LOG_STATIC_FUNC_WITH_PARAM(GetImgLog(),
"imgLoader::RemoveFromCache", "entry's uri",
key.Spec());
#endif
cache.Remove(key);
cache.Remove(key);
if (entry->HasNoProxies()) {
LOG_STATIC_FUNC(GetImgLog(),
"imgLoader::RemoveFromCache removing from tracker");
if (mCacheTracker) {
mCacheTracker->RemoveObject(entry);
}
queue.Remove(entry);
if (entry->HasNoProxies()) {
LOG_STATIC_FUNC(GetImgLog(),
"imgLoader::RemoveFromCache removing from tracker");
if (mCacheTracker) {
mCacheTracker->RemoveObject(entry);
}
entry->SetEvicted(true);
request->SetIsInCache(false);
AddToUncachedImages(request);
return true;
queue.Remove(entry);
}
entry->SetEvicted(true);
request->SetIsInCache(false);
AddToUncachedImages(request);
return true;
}
return false;
@ -2243,7 +2161,8 @@ imgLoader::LoadImage(nsIURI* aURI,
MOZ_ASSERT(NS_UsePrivateBrowsing(newChannel) == mRespectPrivacy);
NewRequestAndEntry(forcePrincipalCheck, this, getter_AddRefs(request),
NewRequestAndEntry(forcePrincipalCheck, this, key,
getter_AddRefs(request),
getter_AddRefs(entry));
PR_LOG(GetImgLog(), PR_LOG_DEBUG,
@ -2494,16 +2413,24 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
requestFlags, _retval);
static_cast<imgRequestProxy*>(*_retval)->NotifyListener();
} else {
// Default to doing a principal check because we don't know who
// started that load and whether their principal ended up being
// inherited on the channel.
NewRequestAndEntry(true, this, getter_AddRefs(request),
getter_AddRefs(entry));
// We use originalURI here to fulfil the imgIRequest contract on GetURI.
nsCOMPtr<nsIURI> originalURI;
channel->GetOriginalURI(getter_AddRefs(originalURI));
// XXX(seth): We should be able to just use |key| here, except that |key| is
// constructed above with the *current URI* and not the *original URI*. I'm
// pretty sure this is a bug, and it's preventing us from ever getting a
// cache hit in LoadImageWithChannel when redirects are involved.
ImageCacheKey originalURIKey(originalURI);
// Default to doing a principal check because we don't know who
// started that load and whether their principal ended up being
// inherited on the channel.
NewRequestAndEntry(/* aForcePrincipalCheckForCacheEntry = */ true,
this, originalURIKey,
getter_AddRefs(request),
getter_AddRefs(entry));
// No principal specified here, because we're not passed one.
// In LoadImageWithChannel, the redirects that may have been
// assoicated with this load would have gone through necko.
@ -2521,7 +2448,7 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
pl.forget(listener);
// Try to add the new request into the cache.
PutIntoCache(ImageCacheKey(originalURI), entry);
PutIntoCache(originalURIKey, entry);
rv = CreateNewProxyForRequest(request, loadGroup, aObserver,
requestFlags, _retval);
@ -2773,6 +2700,7 @@ imgCacheValidator::imgCacheValidator(nsProgressNotificationProxy* progress,
mHadInsecureRedirect(false)
{
NewRequestAndEntry(forcePrincipalCheckForCacheEntry, loader,
mRequest->CacheKey(),
getter_AddRefs(mNewRequest),
getter_AddRefs(mNewEntry));
}
@ -2901,7 +2829,7 @@ imgCacheValidator::OnStartRequest(nsIRequest* aRequest, nsISupports* ctxt)
// Try to add the new request into the cache. Note that the entry must be in
// the cache before the proxies' ownership changes, because adding a proxy
// changes the caching behaviour for imgRequests.
mImgLoader->PutIntoCache(ImageCacheKey(originalURI), mNewEntry);
mImgLoader->PutIntoCache(mNewRequest->CacheKey(), mNewEntry);
uint32_t count = mProxies.Count();
for (int32_t i = count-1; i>=0; i--) {

View File

@ -17,6 +17,7 @@
#include "nsRefPtrHashtable.h"
#include "nsExpirationTracker.h"
#include "nsAutoPtr.h"
#include "ImageCacheKey.h"
#include "imgRequest.h"
#include "nsIProgressEventSink.h"
#include "nsIChannel.h"
@ -214,38 +215,6 @@ enum class AcceptedMimeTypes : uint8_t {
IMAGES_AND_DOCUMENTS,
};
/**
* An ImageLib cache entry key.
*
* We key the cache on the initial URI (before any redirects), with some
* canonicalization applied. See ComputeHash() for the details.
*/
class ImageCacheKey final
{
public:
explicit ImageCacheKey(nsIURI* aURI);
explicit ImageCacheKey(mozilla::image::ImageURL* aURI);
ImageCacheKey(const ImageCacheKey& aOther);
ImageCacheKey(ImageCacheKey&& aOther);
bool operator==(const ImageCacheKey& aOther) const;
uint32_t Hash() const { return mHash; }
/// A weak pointer to the URI spec for this cache entry. For logging only.
const char* Spec() const { return mSpec.get(); }
/// Is this cache entry for a chrome image?
bool IsChrome() const { return mIsChrome; }
private:
static uint32_t ComputeHash(const nsACString& aSpec);
nsCString mSpec;
uint32_t mHash;
bool mIsChrome;
};
class imgLoader final : public imgILoader,
public nsIContentSniffer,
public imgICache,
@ -255,6 +224,7 @@ class imgLoader final : public imgILoader,
virtual ~imgLoader();
public:
typedef mozilla::image::ImageCacheKey ImageCacheKey;
typedef mozilla::image::ImageURL ImageURL;
typedef nsRefPtrHashtable<nsGenericHashKey<ImageCacheKey>,
imgCacheEntry> imgCacheTable;

View File

@ -60,8 +60,10 @@ NS_IMPL_ISUPPORTS(imgRequest,
nsIInterfaceRequestor,
nsIAsyncVerifyRedirectCallback)
imgRequest::imgRequest(imgLoader* aLoader)
imgRequest::imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey)
: mLoader(aLoader)
, mCacheKey(aCacheKey)
, mLoadId(nullptr)
, mValidator(nullptr)
, mInnerWindowId(0)
, mCORSMode(imgIRequest::CORS_NONE)

View File

@ -21,6 +21,7 @@
#include "nsIAsyncVerifyRedirectCallback.h"
#include "mozilla/Mutex.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "ImageCacheKey.h"
class imgCacheValidator;
class imgLoader;
@ -49,12 +50,13 @@ class imgRequest final : public nsIStreamListener,
public nsIAsyncVerifyRedirectCallback
{
typedef mozilla::image::Image Image;
typedef mozilla::image::ImageCacheKey ImageCacheKey;
typedef mozilla::image::ImageURL ImageURL;
typedef mozilla::image::ProgressTracker ProgressTracker;
typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
public:
explicit imgRequest(imgLoader* aLoader);
imgRequest(imgLoader* aLoader, const ImageCacheKey& aCacheKey);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISTREAMLISTENER
@ -143,6 +145,9 @@ public:
// Get the current principal of the image. No AddRefing.
inline nsIPrincipal* GetPrincipal() const { return mPrincipal.get(); }
/// Get the ImageCacheKey associated with this request.
const ImageCacheKey& CacheKey() const { return mCacheKey; }
// Resize the cache entry to 0 if it exists
void ResetCacheEntry();
@ -246,6 +251,9 @@ private:
/* we hold on to this to this so long as we have observers */
nsRefPtr<imgCacheEntry> mCacheEntry;
/// The key under which this imgRequest is stored in the image cache.
ImageCacheKey mCacheKey;
void* mLoadId;
imgCacheValidator* mValidator;

View File

@ -34,6 +34,7 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'imglib2'
EXPORTS += [
'ImageCacheKey.h',
'ImageLogging.h',
'ImageOps.h',
'ImageRegion.h',
@ -53,6 +54,7 @@ UNIFIED_SOURCES += [
'FrameAnimator.cpp',
'FrozenImage.cpp',
'Image.cpp',
'ImageCacheKey.cpp',
'ImageFactory.cpp',
'ImageMetadata.cpp',
'ImageOps.cpp',

View File

@ -21,7 +21,12 @@ ParseContext<ParseHandler>::init(TokenStream& ts)
if (!frontend::GenerateBlockId(ts, this, this->bodyid))
return false;
return decls_.init() && lexdeps.ensureMap(sc->context);
if (!decls_.init() || !lexdeps.ensureMap(sc->context)) {
ReportOutOfMemory(sc->context);
return false;
}
return true;
}
template <typename ParseHandler>

View File

@ -1123,6 +1123,7 @@ inline uintptr_t
ArenaHeader::address() const
{
uintptr_t addr = reinterpret_cast<uintptr_t>(this);
MOZ_ASSERT(addr);
MOZ_ASSERT(!(addr & ArenaMask));
MOZ_ASSERT(Chunk::withinArenasRange(addr));
return addr;
@ -1186,7 +1187,8 @@ ArenaHeader::setNextDelayedMarking(ArenaHeader* aheader)
MOZ_ASSERT(!(uintptr_t(aheader) & ArenaMask));
MOZ_ASSERT(!auxNextLink && !hasDelayedMarking);
hasDelayedMarking = 1;
auxNextLink = aheader->arenaAddress() >> ArenaShift;
if (aheader)
auxNextLink = aheader->arenaAddress() >> ArenaShift;
}
inline void
@ -1209,7 +1211,8 @@ ArenaHeader::setNextAllocDuringSweep(ArenaHeader* aheader)
{
MOZ_ASSERT(!auxNextLink && !allocatedDuringIncremental);
allocatedDuringIncremental = 1;
auxNextLink = aheader->arenaAddress() >> ArenaShift;
if (aheader)
auxNextLink = aheader->arenaAddress() >> ArenaShift;
}
inline void

View File

@ -1948,8 +1948,10 @@ js::TenuringTracer::traceObjectSlots(NativeObject* nobj, uint32_t start, uint32_
HeapSlot* dynStart;
HeapSlot* dynEnd;
nobj->getSlotRange(start, length, &fixedStart, &fixedEnd, &dynStart, &dynEnd);
traceSlots(fixedStart->unsafeGet(), fixedEnd->unsafeGet());
traceSlots(dynStart->unsafeGet(), dynEnd->unsafeGet());
if (fixedStart)
traceSlots(fixedStart->unsafeGet(), fixedEnd->unsafeGet());
if (dynStart)
traceSlots(dynStart->unsafeGet(), dynEnd->unsafeGet());
}
void

View File

@ -397,9 +397,9 @@ js::TenuringTracer::~TenuringTracer()
runtime()->setNeedsIncrementalBarrier(savedRuntimeNeedBarrier);
}
#define TIME_START(name) int64_t timstampStart_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_END(name) int64_t timstampEnd_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_TOTAL(name) (timstampEnd_##name - timstampStart_##name)
#define TIME_START(name) int64_t timestampStart_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_END(name) int64_t timestampEnd_##name = enableProfiling_ ? PRMJ_Now() : 0
#define TIME_TOTAL(name) (timestampEnd_##name - timestampStart_##name)
void
js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList* pretenureGroups)
@ -427,7 +427,7 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
TraceMinorGCStart();
TIME_START(total);
int64_t timestampStart_total = PRMJ_Now();
AutoTraceSession session(rt, MinorCollecting);
AutoStopVerifyingBarriers av(rt, false);
@ -554,11 +554,14 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList
if (rt->gc.usage.gcBytes() >= rt->gc.tunables.gcMaxBytes())
disable();
TIME_END(total);
int64_t totalTime = PRMJ_Now() - timestampStart_total;
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_US, totalTime);
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON, reason);
if (totalTime > 1000)
rt->addTelemetry(JS_TELEMETRY_GC_MINOR_REASON_LONG, reason);
TraceMinorGCEnd();
int64_t totalTime = TIME_TOTAL(total);
if (enableProfiling_ && totalTime >= profileThreshold_) {
static bool printedHeader = false;
if (!printedHeader) {

View File

@ -397,7 +397,7 @@ struct AllPhaseIterator {
size_t activeSlot;
mozilla::Vector<Phase>::Range descendants;
explicit AllPhaseIterator(int64_t (*table)[PHASE_LIMIT])
explicit AllPhaseIterator(Statistics::PhaseTimeTable table)
: current(0)
, baseLevel(0)
, activeSlot(PHASE_DAG_NONE)
@ -444,7 +444,7 @@ struct AllPhaseIterator {
};
static void
FormatPhaseTimes(StatisticsSerializer& ss, const char* name, int64_t (*times)[PHASE_LIMIT])
FormatPhaseTimes(StatisticsSerializer& ss, const char* name, Statistics::PhaseTimeTable times)
{
ss.beginObject(name);
@ -585,8 +585,55 @@ Join(const FragmentVector& fragments) {
return UniqueChars(joined);
}
static int64_t
SumChildTimes(size_t phaseSlot, Phase phase, Statistics::PhaseTimeTable phaseTimes)
{
// Sum the contributions from single-parented children.
int64_t total = 0;
for (unsigned i = 0; i < PHASE_LIMIT; i++) {
if (phases[i].parent == phase)
total += phaseTimes[phaseSlot][i];
}
// Sum the contributions from multi-parented children.
size_t dagSlot = phaseExtra[phase].dagSlot;
if (dagSlot != PHASE_DAG_NONE) {
for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
if (dagChildEdges[i].parent == phase) {
Phase child = dagChildEdges[i].child;
total += phaseTimes[dagSlot][child];
}
}
}
return total;
}
UniqueChars
Statistics::formatDescription()
Statistics::formatDetailedMessage()
{
FragmentVector fragments;
if (!fragments.append(formatDetailedDescription()))
return UniqueChars(nullptr);
if (slices.length() > 1) {
for (unsigned i = 0; i < slices.length(); i++) {
if (!fragments.append(formatDetailedSliceDescription(i, slices[i])))
return UniqueChars(nullptr);
if (!fragments.append(formatDetailedPhaseTimes(slices[i].phaseTimes)))
return UniqueChars(nullptr);
}
}
if (!fragments.append(formatDetailedTotals()))
return UniqueChars(nullptr);
if (!fragments.append(formatDetailedPhaseTimes(phaseTimes)))
return UniqueChars(nullptr);
return Join(fragments);
}
UniqueChars
Statistics::formatDetailedDescription()
{
const double bytesPerMiB = 1024 * 1024;
@ -632,7 +679,7 @@ Statistics::formatDescription()
}
UniqueChars
Statistics::formatSliceDescription(unsigned i, const SliceData& slice)
Statistics::formatDetailedSliceDescription(unsigned i, const SliceData& slice)
{
char budgetDescription[200];
slice.budget.describe(budgetDescription, sizeof(budgetDescription) - 1);
@ -656,48 +703,7 @@ Statistics::formatSliceDescription(unsigned i, const SliceData& slice)
}
UniqueChars
Statistics::formatTotals()
{
int64_t total, longest;
gcDuration(&total, &longest);
const char* format =
"\
---- Totals ----\n\
Total Time: %.3fms\n\
Max Pause: %.3fms\n\
";
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
JS_snprintf(buffer, sizeof(buffer), format, t(total), t(longest));
return make_string_copy(buffer);
}
static int64_t
SumChildTimes(size_t phaseSlot, Phase phase, int64_t (*phaseTimes)[PHASE_LIMIT])
{
// Sum the contributions from single-parented children.
int64_t total = 0;
for (unsigned i = 0; i < PHASE_LIMIT; i++) {
if (phases[i].parent == phase)
total += phaseTimes[phaseSlot][i];
}
// Sum the contributions from multi-parented children.
size_t dagSlot = phaseExtra[phase].dagSlot;
if (dagSlot != PHASE_DAG_NONE) {
for (size_t i = 0; i < mozilla::ArrayLength(dagChildEdges); i++) {
if (dagChildEdges[i].parent == phase) {
Phase child = dagChildEdges[i].child;
total += phaseTimes[dagSlot][child];
}
}
}
return total;
}
UniqueChars
Statistics::formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT])
Statistics::formatDetailedPhaseTimes(PhaseTimeTable phaseTimes)
{
static const char* LevelToIndent[] = { "", " ", " ", " " };
static const int64_t MaxUnaccountedChildTimeUS = 50;
@ -732,27 +738,21 @@ Statistics::formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT])
}
UniqueChars
Statistics::formatDetailedMessage()
Statistics::formatDetailedTotals()
{
FragmentVector fragments;
int64_t total, longest;
gcDuration(&total, &longest);
if (!fragments.append(formatDescription()))
return UniqueChars(nullptr);
if (slices.length() > 1) {
for (unsigned i = 0; i < slices.length(); i++) {
if (!fragments.append(formatSliceDescription(i, slices[i])))
return UniqueChars(nullptr);
if (!fragments.append(formatPhaseTimes(slices[i].phaseTimes)))
return UniqueChars(nullptr);
}
}
if (!fragments.append(formatTotals()))
return UniqueChars(nullptr);
if (!fragments.append(formatPhaseTimes(phaseTimes)))
return UniqueChars(nullptr);
return Join(fragments);
const char* format =
"\
---- Totals ----\n\
Total Time: %.3fms\n\
Max Pause: %.3fms\n\
";
char buffer[1024];
memset(buffer, 0, sizeof(buffer));
JS_snprintf(buffer, sizeof(buffer), format, t(total), t(longest));
return make_string_copy(buffer);
}
char16_t*
@ -775,7 +775,6 @@ Statistics::Statistics(JSRuntime* rt)
: runtime(rt),
startupTime(PRMJ_Now()),
fp(nullptr),
fullFormat(false),
gcDepth(0),
nonincrementalReason_(nullptr),
timedGCStart(0),
@ -840,36 +839,30 @@ Statistics::Statistics(JSRuntime* rt)
}
char* env = getenv("MOZ_GCTIMER");
if (!env || strcmp(env, "none") == 0) {
fp = nullptr;
return;
}
if (strcmp(env, "stdout") == 0) {
fullFormat = false;
fp = stdout;
} else if (strcmp(env, "stderr") == 0) {
fullFormat = false;
fp = stderr;
} else {
fullFormat = true;
fp = fopen(env, "a");
MOZ_ASSERT(fp);
if (env) {
if (strcmp(env, "none") == 0) {
fp = nullptr;
} else if (strcmp(env, "stdout") == 0) {
fp = stdout;
} else if (strcmp(env, "stderr") == 0) {
fp = stderr;
} else {
fp = fopen(env, "a");
if (!fp)
MOZ_CRASH("Failed to open MOZ_GCTIMER log file.");
}
}
}
Statistics::~Statistics()
{
if (fp) {
if (fullFormat) {
StatisticsSerializer ss(StatisticsSerializer::AsText);
FormatPhaseTimes(ss, "", phaseTotals);
char* msg = ss.finishCString();
if (msg) {
fprintf(fp, "TOTALS\n%s\n\n-------\n", msg);
js_free(msg);
}
StatisticsSerializer ss(StatisticsSerializer::AsText);
FormatPhaseTimes(ss, "", phaseTotals);
char* msg = ss.finishCString();
if (msg) {
fprintf(fp, "TOTALS\n%s\n\n-------\n", msg);
js_free(msg);
}
if (fp != stdout && fp != stderr)
@ -900,7 +893,7 @@ Statistics::getMaxGCPauseSinceClear()
}
static int64_t
SumPhase(Phase phase, int64_t (*times)[PHASE_LIMIT])
SumPhase(Phase phase, Statistics::PhaseTimeTable times)
{
int64_t sum = 0;
for (size_t i = 0; i < Statistics::MAX_MULTIPARENT_PHASES + 1; i++)
@ -912,26 +905,11 @@ void
Statistics::printStats()
{
if (aborted) {
if (fullFormat)
fprintf(fp, "OOM during GC statistics collection. The report is unavailable for this GC.\n");
fflush(fp);
return;
}
if (fullFormat) {
fprintf(fp, "OOM during GC statistics collection. The report is unavailable for this GC.\n");
} else {
UniqueChars msg = formatDetailedMessage();
if (msg)
fprintf(fp, "GC(T+%.3fs) %s\n", t(slices[0].start - startupTime) / 1000.0, msg.get());
} else {
int64_t total, longest;
gcDuration(&total, &longest);
int64_t markTotal = SumPhase(PHASE_MARK, phaseTimes);
fprintf(fp, "%f %f %f\n",
t(total),
t(markTotal),
t(phaseTimes[PHASE_DAG_NONE][PHASE_SWEEP]));
MOZ_ASSERT(phaseExtra[PHASE_SWEEP].dagSlot == PHASE_DAG_NONE);
}
fflush(fp);
}

View File

@ -232,13 +232,16 @@ struct Statistics
SliceRange sliceRange() const { return slices.all(); }
size_t slicesLength() const { return slices.length(); }
/* Create a convenient typedef for referring tables of phase times. */
typedef int64_t (*PhaseTimeTable)[PHASE_LIMIT];
private:
JSRuntime* runtime;
int64_t startupTime;
/* File pointer used for MOZ_GCTIMER output. */
FILE* fp;
bool fullFormat;
/*
* GCs can't really nest, but a second GC can be triggered from within the
@ -311,10 +314,10 @@ struct Statistics
void printStats();
bool formatData(StatisticsSerializer& ss, uint64_t timestamp);
UniqueChars formatDescription();
UniqueChars formatSliceDescription(unsigned i, const SliceData& slice);
UniqueChars formatTotals();
UniqueChars formatPhaseTimes(int64_t (*phaseTimes)[PHASE_LIMIT]);
UniqueChars formatDetailedDescription();
UniqueChars formatDetailedSliceDescription(unsigned i, const SliceData& slice);
UniqueChars formatDetailedPhaseTimes(PhaseTimeTable phaseTimes);
UniqueChars formatDetailedTotals();
double computeMMU(int64_t resolution);
};

View File

@ -107,8 +107,10 @@ BaselineCompiler::compile()
if (!emitOutOfLinePostBarrierSlot())
return Method_Error;
if (masm.oom())
if (masm.oom()) {
ReportOutOfMemory(cx);
return Method_Error;
}
Linker linker(masm);
AutoFlushICache afc("Baseline");
@ -170,8 +172,10 @@ BaselineCompiler::compile()
previousOffset = entry.nativeOffset;
}
if (pcEntries.oom())
if (pcEntries.oom()) {
ReportOutOfMemory(cx);
return Method_Error;
}
prologueOffset_.fixup(&masm);
epilogueOffset_.fixup(&masm);
@ -282,6 +286,7 @@ BaselineCompiler::compile()
JitcodeGlobalTable* globalTable = cx->runtime()->jitRuntime()->getJitcodeGlobalTable();
if (!globalTable->addEntry(entry, cx->runtime())) {
entry.destroy();
ReportOutOfMemory(cx);
return Method_Error;
}
@ -936,8 +941,10 @@ BaselineCompiler::emitBody()
bool addIndexEntry = (pc == script->code() || lastOpUnreachable || emittedOps > 100);
if (addIndexEntry)
emittedOps = 0;
if (!addPCMappingEntry(addIndexEntry))
if (!addPCMappingEntry(addIndexEntry)) {
ReportOutOfMemory(cx);
return Method_Error;
}
// Emit traps for breakpoints and step mode.
if (compileDebugInstrumentation_ && !emitDebugTrap())

View File

@ -228,14 +228,19 @@ jit::BaselineCompile(JSContext* cx, JSScript* script, bool forceDebugInstrumenta
LifoAlloc alloc(TempAllocator::PreferredLifoChunkSize);
TempAllocator* temp = alloc.new_<TempAllocator>(&alloc);
if (!temp)
if (!temp) {
ReportOutOfMemory(cx);
return Method_Error;
}
JitContext jctx(cx, temp);
BaselineCompiler compiler(cx, *temp, script);
if (!compiler.init())
if (!compiler.init()) {
ReportOutOfMemory(cx);
return Method_Error;
}
if (forceDebugInstrumentation)
compiler.setCompileDebugInstrumentation();

View File

@ -264,7 +264,7 @@ class RepatchIonCache::RepatchStubAppender : public IonCache::StubAttacher
public:
explicit RepatchStubAppender(RepatchIonCache& cache)
: StubAttacher(cache.rejoinLabel()),
: StubAttacher(cache.rejoinLabel_),
cache_(cache)
{
}
@ -302,6 +302,9 @@ RepatchIonCache::emitInitialJump(MacroAssembler& masm, AddCacheState& addState)
{
initialJump_ = masm.jumpWithPatch(&addState.repatchEntry);
lastJump_ = initialJump_;
Label label;
masm.bind(&label);
rejoinLabel_ = CodeOffsetLabel(label.offset());
}
void
@ -316,6 +319,7 @@ RepatchIonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm)
IonCache::updateBaseAddress(code, masm);
initialJump_.repoint(code, &masm);
lastJump_.repoint(code, &masm);
rejoinLabel_.repoint(code, &masm);
}
class DispatchIonCache::DispatchStubPrepender : public IonCache::StubAttacher

View File

@ -354,26 +354,7 @@ class RepatchIonCache : public IonCache
CodeLocationJump initialJump_;
CodeLocationJump lastJump_;
// Offset from the initial jump to the rejoin label.
#ifdef JS_CODEGEN_ARM
static const size_t REJOIN_LABEL_OFFSET = 4;
#elif defined(JS_CODEGEN_MIPS)
// The size of jump created by MacroAssemblerMIPSCompat::jumpWithPatch.
static const size_t REJOIN_LABEL_OFFSET = 4 * sizeof(void*);
#else
static const size_t REJOIN_LABEL_OFFSET = 0;
#endif
CodeLocationLabel rejoinLabel() const {
uint8_t* ptr = initialJump_.raw();
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
uint32_t i = 0;
while (i < REJOIN_LABEL_OFFSET)
ptr = Assembler::NextInstruction(ptr, &i);
#endif
return CodeLocationLabel(ptr);
}
CodeLocationLabel rejoinLabel_;
public:
RepatchIonCache()
@ -395,7 +376,7 @@ class RepatchIonCache : public IonCache
void updateBaseAddress(JitCode* code, MacroAssembler& masm) override;
virtual void* rejoinAddress() override {
return rejoinLabel().raw();
return rejoinLabel_.raw();
}
};

View File

@ -373,13 +373,10 @@ class JitFrameLayout : public CommonFrameLayout
return offsetof(JitFrameLayout, numActualArgs_);
}
static size_t offsetOfThis() {
JitFrameLayout* base = nullptr;
return reinterpret_cast<size_t>(&base->argv()[0]);
return sizeof(JitFrameLayout);
}
static size_t offsetOfActualArgs() {
JitFrameLayout* base = nullptr;
// +1 to skip |this|.
return reinterpret_cast<size_t>(&base->argv()[1]);
return offsetOfThis() + sizeof(Value);
}
static size_t offsetOfActualArg(size_t arg) {
return offsetOfActualArgs() + arg * sizeof(Value);

View File

@ -888,6 +888,20 @@ template void
MacroAssembler::loadUnboxedProperty(BaseIndex address, JSValueType type,
TypedOrValueRegister output);
static void
StoreUnboxedFailure(MacroAssembler& masm, Label* failure)
{
// Storing a value to an unboxed property is a fallible operation and
// the caller must provide a failure label if a particular unboxed store
// might fail. Sometimes, however, a store that cannot succeed (such as
// storing a string to an int32 property) will be marked as infallible.
// This can only happen if the code involved is unreachable.
if (failure)
masm.jump(failure);
else
masm.assumeUnreachable("Incompatible write to unboxed property");
}
template <typename T>
void
MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
@ -899,12 +913,12 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isBoolean())
store8(Imm32(value.value().toBoolean()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_Boolean)
store8(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure)
branchTestBoolean(Assembler::NotEqual, value.reg().valueReg(), failure);
@ -917,12 +931,12 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isInt32())
store32(Imm32(value.value().toInt32()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_Int32)
store32(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure)
branchTestInt32(Assembler::NotEqual, value.reg().valueReg(), failure);
@ -936,7 +950,7 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
loadConstantDouble(value.value().toNumber(), ScratchDoubleReg);
storeDouble(ScratchDoubleReg, address);
} else {
jump(failure);
StoreUnboxedFailure(*this, failure);
}
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_Int32) {
@ -945,7 +959,7 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
} else if (value.reg().type() == MIRType_Double) {
storeDouble(value.reg().typedReg().fpu(), address);
} else {
jump(failure);
StoreUnboxedFailure(*this, failure);
}
} else {
ValueOperand reg = value.reg().valueReg();
@ -967,13 +981,13 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isObjectOrNull())
storePtr(ImmGCPtr(value.value().toObjectOrNull()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
MOZ_ASSERT(value.reg().type() != MIRType_Null);
if (value.reg().type() == MIRType_Object)
storePtr(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure) {
Label ok;
@ -990,12 +1004,12 @@ MacroAssembler::storeUnboxedProperty(T address, JSValueType type,
if (value.value().isString())
storePtr(ImmGCPtr(value.value().toString()), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else if (value.reg().hasTyped()) {
if (value.reg().type() == MIRType_String)
storePtr(value.reg().typedReg().gpr(), address);
else
jump(failure);
StoreUnboxedFailure(*this, failure);
} else {
if (failure)
branchTestString(Assembler::NotEqual, value.reg().valueReg(), failure);

View File

@ -81,8 +81,10 @@ class BaselineCompilerShared
return nullptr;
// Create the entry and add it to the vector.
if (!icEntries_.append(ICEntry(script->pcToOffset(pc), kind)))
if (!icEntries_.append(ICEntry(script->pcToOffset(pc), kind))) {
ReportOutOfMemory(cx);
return nullptr;
}
ICEntry& vecEntry = icEntries_.back();
// Set the first stub for the IC entry to the fallback stub

Some files were not shown because too many files have changed in this diff Show More