зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to fx-team
This commit is contained in:
Коммит
d8189ee58f
|
@ -120,6 +120,16 @@ this.FxAccountsMgmtService = {
|
|||
}
|
||||
).then(null, Components.utils.reportError);
|
||||
break;
|
||||
case "resendVerificationEmail":
|
||||
FxAccountsManager.resendVerificationEmail().then(
|
||||
() => {
|
||||
self._onFulfill(msg.id);
|
||||
},
|
||||
reason => {
|
||||
self._onReject(msg.id, reason);
|
||||
}
|
||||
).then(null, Components.utils.reportError);
|
||||
break;
|
||||
case "signIn":
|
||||
case "signUp":
|
||||
case "refreshAuthentication":
|
||||
|
|
|
@ -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="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="65fba428f8d76336b33ddd9e15900357953600ba">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
|
|
|
@ -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="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="ca283b9db2b151d465cfd2e19346cf58fe89e413"/>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
|
||||
|
@ -119,7 +119,7 @@
|
|||
<!-- Flame specific things -->
|
||||
<project name="device/generic/armv7-a-neon" path="device/generic/armv7-a-neon" revision="e8a318f7690092e639ba88891606f4183e846d3f"/>
|
||||
<project name="device/qcom/common" path="device/qcom/common" revision="234ed34543345f58c0d4dcb1aa012de68802b9dc"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="2a3f4c782daad9740f1b78766b636e0e00a0ff30"/>
|
||||
<project name="device-flame" path="device/t2m/flame" remote="b2g" revision="ecc08b2f0efea93c778e3525553bcd4bd5f2cf49"/>
|
||||
<project name="kernel/msm" path="kernel" revision="1f47f3a180ed8b070f3cf3c4d11ff2523cca6c8a"/>
|
||||
<project name="platform/bootable/recovery" path="bootable/recovery" revision="f2914eacee9120680a41463708bb6ee8291749fc"/>
|
||||
<project name="platform/external/bluetooth/bluedroid" path="external/bluetooth/bluedroid" revision="fa892235a9bd8983f8b591129fc1a9398f64e514"/>
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"remote": "",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "18441d7d35b6a96732575fb5c28cedfed8269fb2",
|
||||
"revision": "5476e49adf00cafde6cb68e876f0514dac4b993d",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -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="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ce95d372e6d285725b96490afdaaf489ad8f9ca9"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="3691614d0045f7968addce45d4140fb360c3ceaf"/>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="4f352142a54f7f7ae2c460aad9049eda4b0edb14"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="15ac34804eb8b3c9b2582d7cf754c57e23182df6"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="f313e6d3aaaefe8c82eaed15912a09b120fb7260"/>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1f6a1fe07f81c5bc5e1d079c9b60f7f78ca2bf4f"/>
|
||||
|
|
|
@ -250,17 +250,6 @@ class B2GRemoteAutomation(Automation):
|
|||
if 'b2g' not in session:
|
||||
raise Exception("bad session value %s returned by start_session" % session)
|
||||
|
||||
if self._is_emulator:
|
||||
# Disable offline status management (bug 777145), otherwise the network
|
||||
# will be 'offline' when the mochitests start. Presumably, the network
|
||||
# won't be offline on a real device, so we only do this for emulators.
|
||||
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
|
||||
self.marionette.execute_script("""
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Services.io.manageOfflineStatus = false;
|
||||
Services.io.offline = false;
|
||||
""")
|
||||
|
||||
if self.context_chrome:
|
||||
self.marionette.set_context(self.marionette.CONTEXT_CHROME)
|
||||
else:
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "mozilla/dom/MediaStreamBinding.h"
|
||||
#include "mozilla/dom/MediaStreamTrackBinding.h"
|
||||
#include "mozilla/dom/GetUserMediaRequestBinding.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "MediaTrackConstraints.h"
|
||||
|
||||
#include "Latency.h"
|
||||
|
@ -730,7 +731,7 @@ static SourceSet *
|
|||
GetSources(MediaEngine *engine,
|
||||
ConstraintsType &aConstraints,
|
||||
void (MediaEngine::* aEnumerate)(nsTArray<nsRefPtr<SourceType> >*),
|
||||
char* media_device_name = nullptr)
|
||||
const char* media_device_name = nullptr)
|
||||
{
|
||||
ScopedDeletePtr<SourceSet> result(new SourceSet);
|
||||
|
||||
|
@ -748,7 +749,6 @@ static SourceSet *
|
|||
* to.
|
||||
*/
|
||||
for (uint32_t len = sources.Length(), i = 0; i < len; i++) {
|
||||
#ifdef DEBUG
|
||||
sources[i]->GetName(deviceName);
|
||||
if (media_device_name && strlen(media_device_name) > 0) {
|
||||
if (deviceName.EqualsASCII(media_device_name)) {
|
||||
|
@ -756,11 +756,8 @@ static SourceSet *
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
candidateSet.AppendElement(MediaDevice::Create(sources[i]));
|
||||
#ifdef DEBUG
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1143,8 @@ public:
|
|||
const MediaStreamConstraints& aConstraints,
|
||||
already_AddRefed<nsIGetUserMediaDevicesSuccessCallback> aSuccess,
|
||||
already_AddRefed<nsIDOMGetUserMediaErrorCallback> aError,
|
||||
uint64_t aWindowId, char* aAudioLoopbackDev, char* aVideoLoopbackDev)
|
||||
uint64_t aWindowId, nsACString& aAudioLoopbackDev,
|
||||
nsACString& aVideoLoopbackDev)
|
||||
: mConstraints(aConstraints)
|
||||
, mSuccess(aSuccess)
|
||||
, mError(aError)
|
||||
|
@ -1171,14 +1169,14 @@ public:
|
|||
VideoTrackConstraintsN constraints(GetInvariant(mConstraints.mVideo));
|
||||
ScopedDeletePtr<SourceSet> s(GetSources(backend, constraints,
|
||||
&MediaEngine::EnumerateVideoDevices,
|
||||
mLoopbackVideoDevice));
|
||||
mLoopbackVideoDevice.get()));
|
||||
final->MoveElementsFrom(*s);
|
||||
}
|
||||
if (IsOn(mConstraints.mAudio)) {
|
||||
AudioTrackConstraintsN constraints(GetInvariant(mConstraints.mAudio));
|
||||
ScopedDeletePtr<SourceSet> s (GetSources(backend, constraints,
|
||||
&MediaEngine::EnumerateAudioDevices,
|
||||
mLoopbackAudioDevice));
|
||||
mLoopbackAudioDevice.get()));
|
||||
final->MoveElementsFrom(*s);
|
||||
}
|
||||
NS_DispatchToMainThread(new DeviceSuccessCallbackRunnable(mWindowId,
|
||||
|
@ -1199,8 +1197,8 @@ private:
|
|||
// Audio & Video loopback devices to be used based on
|
||||
// the preference settings. This is currently used for
|
||||
// automated media tests only.
|
||||
char* mLoopbackAudioDevice;
|
||||
char* mLoopbackVideoDevice;
|
||||
nsCString mLoopbackAudioDevice;
|
||||
nsCString mLoopbackVideoDevice;
|
||||
};
|
||||
|
||||
MediaManager::MediaManager()
|
||||
|
@ -1584,22 +1582,12 @@ MediaManager::GetUserMediaDevices(nsPIDOMWindow* aWindow,
|
|||
|
||||
nsCOMPtr<nsIGetUserMediaDevicesSuccessCallback> onSuccess(aOnSuccess);
|
||||
nsCOMPtr<nsIDOMGetUserMediaErrorCallback> onError(aOnError);
|
||||
char* loopbackAudioDevice = nullptr;
|
||||
char* loopbackVideoDevice = nullptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
nsresult rv;
|
||||
|
||||
// Check if the preference for using loopback devices is enabled.
|
||||
nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs);
|
||||
if (branch) {
|
||||
branch->GetCharPref("media.audio_loopback_dev", &loopbackAudioDevice);
|
||||
branch->GetCharPref("media.video_loopback_dev", &loopbackVideoDevice);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nsAdoptingCString loopbackAudioDevice =
|
||||
Preferences::GetCString("media.audio_loopback_dev");
|
||||
nsAdoptingCString loopbackVideoDevice =
|
||||
Preferences::GetCString("media.video_loopback_dev");
|
||||
|
||||
nsCOMPtr<nsIRunnable> gUMDRunnable = new GetUserMediaDevicesRunnable(
|
||||
aConstraints, onSuccess.forget(), onError.forget(),
|
||||
|
|
|
@ -8,6 +8,16 @@ var Cr = SpecialPowers.Cr;
|
|||
|
||||
// Specifies whether we are using fake streams to run this automation
|
||||
var FAKE_ENABLED = true;
|
||||
try {
|
||||
var audioDevice = SpecialPowers.getCharPref('media.audio_loopback_dev');
|
||||
var videoDevice = SpecialPowers.getCharPref('media.video_loopback_dev');
|
||||
dump('TEST DEVICES: Using media devices:\n');
|
||||
dump('audio: ' + audioDevice + '\nvideo: ' + videoDevice + '\n');
|
||||
FAKE_ENABLED = false;
|
||||
} catch (e) {
|
||||
dump('TEST DEVICES: No test devices found (in media.{audio,video}_loopback_dev, using fake streams.\n');
|
||||
FAKE_ENABLED = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -97,7 +107,7 @@ function createMediaElement(type, label) {
|
|||
* The error callback if the stream fails to be retrieved
|
||||
*/
|
||||
function getUserMedia(constraints, onSuccess, onError) {
|
||||
if (!("fake" in constraints)) {
|
||||
if (!("fake" in constraints) && FAKE_ENABLED) {
|
||||
constraints["fake"] = FAKE_ENABLED;
|
||||
}
|
||||
|
||||
|
|
|
@ -737,6 +737,7 @@ static const dom::ConstantSpec gWinProperties[] =
|
|||
INT_CONSTANT(DACL_SECURITY_INFORMATION),
|
||||
|
||||
// Errors
|
||||
INT_CONSTANT(ERROR_SUCCESS),
|
||||
INT_CONSTANT(ERROR_INVALID_HANDLE),
|
||||
INT_CONSTANT(ERROR_ACCESS_DENIED),
|
||||
INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
|
||||
|
@ -746,6 +747,7 @@ static const dom::ConstantSpec gWinProperties[] =
|
|||
INT_CONSTANT(ERROR_NO_MORE_FILES),
|
||||
INT_CONSTANT(ERROR_PATH_NOT_FOUND),
|
||||
INT_CONSTANT(ERROR_BAD_ARGUMENTS),
|
||||
INT_CONSTANT(ERROR_SHARING_VIOLATION),
|
||||
INT_CONSTANT(ERROR_NOT_SUPPORTED),
|
||||
|
||||
PROP_END
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/telephony/TelephonyChild.h"
|
||||
#include "TelephonyChild.h"
|
||||
#include "TelephonyIPCProvider.h"
|
||||
|
||||
USING_TELEPHONY_NAMESPACE
|
||||
|
||||
|
@ -11,16 +12,23 @@ USING_TELEPHONY_NAMESPACE
|
|||
* TelephonyChild
|
||||
******************************************************************************/
|
||||
|
||||
TelephonyChild::TelephonyChild(nsITelephonyListener* aListener)
|
||||
: mListener(aListener)
|
||||
TelephonyChild::TelephonyChild(TelephonyIPCProvider* aProvider)
|
||||
: mProvider(aProvider)
|
||||
{
|
||||
MOZ_ASSERT(aProvider);
|
||||
}
|
||||
|
||||
TelephonyChild::~TelephonyChild()
|
||||
{
|
||||
MOZ_ASSERT(aListener);
|
||||
}
|
||||
|
||||
void
|
||||
TelephonyChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
mListener = nullptr;
|
||||
if (mProvider) {
|
||||
mProvider->NoteActorDestroyed();
|
||||
mProvider = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
PTelephonyRequestChild*
|
||||
|
@ -41,9 +49,9 @@ TelephonyChild::RecvNotifyCallError(const uint32_t& aClientId,
|
|||
const int32_t& aCallIndex,
|
||||
const nsString& aError)
|
||||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mProvider);
|
||||
|
||||
mListener->NotifyError(aClientId, aCallIndex, aError);
|
||||
mProvider->NotifyError(aClientId, aCallIndex, aError);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -51,9 +59,9 @@ bool
|
|||
TelephonyChild::RecvNotifyCallStateChanged(const uint32_t& aClientId,
|
||||
const IPCCallStateData& aData)
|
||||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mProvider);
|
||||
|
||||
mListener->CallStateChanged(aClientId,
|
||||
mProvider->CallStateChanged(aClientId,
|
||||
aData.callIndex(),
|
||||
aData.callState(),
|
||||
aData.number(),
|
||||
|
@ -70,18 +78,18 @@ bool
|
|||
TelephonyChild::RecvNotifyCdmaCallWaiting(const uint32_t& aClientId,
|
||||
const nsString& aNumber)
|
||||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mProvider);
|
||||
|
||||
mListener->NotifyCdmaCallWaiting(aClientId, aNumber);
|
||||
mProvider->NotifyCdmaCallWaiting(aClientId, aNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TelephonyChild::RecvNotifyConferenceCallStateChanged(const uint16_t& aCallState)
|
||||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mProvider);
|
||||
|
||||
mListener->ConferenceCallStateChanged(aCallState);
|
||||
mProvider->ConferenceCallStateChanged(aCallState);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -89,9 +97,9 @@ bool
|
|||
TelephonyChild::RecvNotifyConferenceError(const nsString& aName,
|
||||
const nsString& aMessage)
|
||||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mProvider);
|
||||
|
||||
mListener->NotifyConferenceError(aName, aMessage);
|
||||
mProvider->NotifyConferenceError(aName, aMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -100,9 +108,9 @@ TelephonyChild::RecvNotifySupplementaryService(const uint32_t& aClientId,
|
|||
const int32_t& aCallIndex,
|
||||
const uint16_t& aNotification)
|
||||
{
|
||||
MOZ_ASSERT(mListener);
|
||||
MOZ_ASSERT(mProvider);
|
||||
|
||||
mListener->SupplementaryServiceNotification(aClientId, aCallIndex,
|
||||
mProvider->SupplementaryServiceNotification(aClientId, aCallIndex,
|
||||
aNotification);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,15 @@
|
|||
|
||||
BEGIN_TELEPHONY_NAMESPACE
|
||||
|
||||
class TelephonyIPCProvider;
|
||||
|
||||
class TelephonyChild : public PTelephonyChild
|
||||
{
|
||||
public:
|
||||
TelephonyChild(nsITelephonyListener* aListener);
|
||||
TelephonyChild(TelephonyIPCProvider* aProvider);
|
||||
|
||||
protected:
|
||||
virtual ~TelephonyChild() {}
|
||||
virtual ~TelephonyChild();
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
|
||||
|
@ -55,7 +57,7 @@ protected:
|
|||
const uint16_t& aNotification) MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsITelephonyListener> mListener;
|
||||
nsRefPtr<TelephonyIPCProvider> mProvider;
|
||||
};
|
||||
|
||||
class TelephonyRequestChild : public PTelephonyRequestChild
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* 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 "ipc/TelephonyIPCProvider.h"
|
||||
#include "TelephonyIPCProvider.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/telephony/TelephonyChild.h"
|
||||
|
@ -53,7 +53,17 @@ TelephonyIPCProvider::TelephonyIPCProvider()
|
|||
|
||||
TelephonyIPCProvider::~TelephonyIPCProvider()
|
||||
{
|
||||
mPTelephonyChild->Send__delete__(mPTelephonyChild);
|
||||
if (mPTelephonyChild) {
|
||||
mPTelephonyChild->Send__delete__(mPTelephonyChild);
|
||||
mPTelephonyChild = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TelephonyIPCProvider::NoteActorDestroyed()
|
||||
{
|
||||
MOZ_ASSERT(mPTelephonyChild);
|
||||
|
||||
mPTelephonyChild = nullptr;
|
||||
}
|
||||
|
||||
|
@ -94,6 +104,11 @@ TelephonyIPCProvider::RegisterListener(nsITelephonyListener *aListener)
|
|||
{
|
||||
MOZ_ASSERT(!mListeners.Contains(aListener));
|
||||
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// nsTArray doesn't fail.
|
||||
mListeners.AppendElement(aListener);
|
||||
|
||||
|
@ -108,6 +123,11 @@ TelephonyIPCProvider::UnregisterListener(nsITelephonyListener *aListener)
|
|||
{
|
||||
MOZ_ASSERT(mListeners.Contains(aListener));
|
||||
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// We always have the element here, so it can't fail.
|
||||
mListeners.RemoveElement(aListener);
|
||||
|
||||
|
@ -122,6 +142,11 @@ TelephonyIPCProvider::SendRequest(nsITelephonyListener *aListener,
|
|||
nsITelephonyCallback *aCallback,
|
||||
const IPCTelephonyRequest& aRequest)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Life time of newly allocated TelephonyRequestChild instance is managed by
|
||||
// IPDL itself.
|
||||
TelephonyRequestChild* actor = new TelephonyRequestChild(aListener, aCallback);
|
||||
|
@ -146,6 +171,11 @@ TelephonyIPCProvider::Dial(uint32_t aClientId, const nsAString& aNumber,
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendHangUpCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -153,6 +183,11 @@ TelephonyIPCProvider::HangUp(uint32_t aClientId, uint32_t aCallIndex)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::AnswerCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendAnswerCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -160,6 +195,11 @@ TelephonyIPCProvider::AnswerCall(uint32_t aClientId, uint32_t aCallIndex)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::RejectCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendRejectCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -167,6 +207,11 @@ TelephonyIPCProvider::RejectCall(uint32_t aClientId, uint32_t aCallIndex)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::HoldCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendHoldCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -174,6 +219,11 @@ TelephonyIPCProvider::HoldCall(uint32_t aClientId, uint32_t aCallIndex)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::ResumeCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendResumeCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -181,6 +231,11 @@ TelephonyIPCProvider::ResumeCall(uint32_t aClientId, uint32_t aCallIndex)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::ConferenceCall(uint32_t aClientId)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendConferenceCall(aClientId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -188,6 +243,11 @@ TelephonyIPCProvider::ConferenceCall(uint32_t aClientId)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::SeparateCall(uint32_t aClientId, uint32_t aCallIndex)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendSeparateCall(aClientId, aCallIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -195,6 +255,11 @@ TelephonyIPCProvider::SeparateCall(uint32_t aClientId, uint32_t aCallIndex)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::HoldConference(uint32_t aClientId)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendHoldConference(aClientId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -202,6 +267,11 @@ TelephonyIPCProvider::HoldConference(uint32_t aClientId)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::ResumeConference(uint32_t aClientId)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendResumeConference(aClientId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -209,6 +279,11 @@ TelephonyIPCProvider::ResumeConference(uint32_t aClientId)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::StartTone(uint32_t aClientId, const nsAString& aDtmfChar)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendStartTone(aClientId, nsString(aDtmfChar));
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -216,6 +291,11 @@ TelephonyIPCProvider::StartTone(uint32_t aClientId, const nsAString& aDtmfChar)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::StopTone(uint32_t aClientId)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendStopTone(aClientId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -223,6 +303,11 @@ TelephonyIPCProvider::StopTone(uint32_t aClientId)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendGetMicrophoneMuted(aMuted);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -230,6 +315,11 @@ TelephonyIPCProvider::GetMicrophoneMuted(bool* aMuted)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendSetMicrophoneMuted(aMuted);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -237,6 +327,11 @@ TelephonyIPCProvider::SetMicrophoneMuted(bool aMuted)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendGetSpeakerEnabled(aEnabled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -244,6 +339,11 @@ TelephonyIPCProvider::GetSpeakerEnabled(bool* aEnabled)
|
|||
NS_IMETHODIMP
|
||||
TelephonyIPCProvider::SetSpeakerEnabled(bool aEnabled)
|
||||
{
|
||||
if (!mPTelephonyChild) {
|
||||
NS_WARNING("TelephonyProvider used after shutdown has begun!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mPTelephonyChild->SendSetSpeakerEnabled(aEnabled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -28,10 +28,11 @@ public:
|
|||
|
||||
TelephonyIPCProvider();
|
||||
|
||||
protected:
|
||||
virtual ~TelephonyIPCProvider();
|
||||
void NoteActorDestroyed();
|
||||
|
||||
private:
|
||||
~TelephonyIPCProvider();
|
||||
|
||||
nsTArray<nsCOMPtr<nsITelephonyListener> > mListeners;
|
||||
PTelephonyChild* mPTelephonyChild;
|
||||
uint32_t mDefaultServiceId;
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "nsMimeTypes.h"
|
||||
|
||||
#include "Image.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace image {
|
||||
|
@ -128,6 +130,26 @@ ImageResource::SetAnimationModeInternal(uint16_t aAnimationMode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
ImageResource::HadRecentRefresh(const TimeStamp& aTime)
|
||||
{
|
||||
// Our threshold for "recent" is 1/2 of the default refresh-driver interval.
|
||||
// This ensures that we allow for frame rates at least as fast as the
|
||||
// refresh driver's default rate.
|
||||
static TimeDuration recentThreshold =
|
||||
TimeDuration::FromMilliseconds(nsRefreshDriver::DefaultInterval() / 2.0);
|
||||
|
||||
if (!mLastRefreshTime.IsNull() &&
|
||||
aTime - mLastRefreshTime < recentThreshold) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// else, we can proceed with a refresh.
|
||||
// But first, update our last refresh time:
|
||||
mLastRefreshTime = aTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
ImageResource::EvaluateAnimation()
|
||||
{
|
||||
|
|
|
@ -186,6 +186,17 @@ protected:
|
|||
nsresult GetAnimationModeInternal(uint16_t *aAnimationMode);
|
||||
nsresult SetAnimationModeInternal(uint16_t aAnimationMode);
|
||||
|
||||
/**
|
||||
* Helper for RequestRefresh.
|
||||
*
|
||||
* If we've had a "recent" refresh (i.e. if this image is being used in
|
||||
* multiple documents & some other document *just* called RequestRefresh() on
|
||||
* this image with a timestamp close to aTime), this method returns true.
|
||||
*
|
||||
* Otherwise, this method updates mLastRefreshTime to aTime & returns false.
|
||||
*/
|
||||
bool HadRecentRefresh(const mozilla::TimeStamp& aTime);
|
||||
|
||||
/**
|
||||
* Decides whether animation should or should not be happening,
|
||||
* and makes sure the right thing is being done.
|
||||
|
@ -206,6 +217,7 @@ protected:
|
|||
// Member data shared by all implementations of this abstract class
|
||||
nsRefPtr<imgStatusTracker> mStatusTracker;
|
||||
nsRefPtr<ImageURL> mURI;
|
||||
TimeStamp mLastRefreshTime;
|
||||
uint64_t mInnerWindowId;
|
||||
uint32_t mAnimationConsumers;
|
||||
uint16_t mAnimationMode; // Enum values in imgIContainer
|
||||
|
|
|
@ -543,6 +543,10 @@ RasterImage::Init(const char* aMimeType,
|
|||
NS_IMETHODIMP_(void)
|
||||
RasterImage::RequestRefresh(const mozilla::TimeStamp& aTime)
|
||||
{
|
||||
if (HadRecentRefresh(aTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EvaluateAnimation();
|
||||
|
||||
if (!mAnimating) {
|
||||
|
|
|
@ -527,6 +527,10 @@ VectorImage::GetWidth(int32_t* aWidth)
|
|||
NS_IMETHODIMP_(void)
|
||||
VectorImage::RequestRefresh(const mozilla::TimeStamp& aTime)
|
||||
{
|
||||
if (HadRecentRefresh(aTime)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EvaluateAnimation();
|
||||
|
||||
mSVGDocumentWrapper->TickRefreshDriver();
|
||||
|
|
|
@ -47,6 +47,8 @@ class TestActorPunningPunnedParent :
|
|||
public:
|
||||
TestActorPunningPunnedParent() {}
|
||||
virtual ~TestActorPunningPunnedParent() {}
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
};
|
||||
|
||||
class TestActorPunningSubParent :
|
||||
|
@ -55,6 +57,8 @@ class TestActorPunningSubParent :
|
|||
public:
|
||||
TestActorPunningSubParent() {}
|
||||
virtual ~TestActorPunningSubParent() {}
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ public:
|
|||
virtual ~TestBadActorSubParent() { }
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
virtual bool RecvPing();
|
||||
};
|
||||
|
||||
|
|
|
@ -80,8 +80,8 @@ public:
|
|||
virtual ~TestDescSubParent() { }
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
virtual PTestDescSubsubParent* AllocPTestDescSubsubParent() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool DeallocPTestDescSubsubParent(PTestDescSubsubParent* actor) MOZ_OVERRIDE;
|
||||
};
|
||||
|
||||
|
@ -108,6 +108,9 @@ class TestDescSubsubParent :
|
|||
public:
|
||||
TestDescSubsubParent() { }
|
||||
virtual ~TestDescSubsubParent() { }
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
};
|
||||
|
||||
class TestDescSubsubChild :
|
||||
|
|
|
@ -18,6 +18,9 @@ class TestHandleParent :
|
|||
public:
|
||||
TestHandleParent() { }
|
||||
virtual ~TestHandleParent() { }
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
};
|
||||
|
||||
class TestJSONParent :
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
virtual ~TestManyChildAllocsSubParent() { }
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
virtual bool RecvHello() MOZ_OVERRIDE { return true; }
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,9 @@ class TestMultiMgrsBottomParent :
|
|||
public:
|
||||
TestMultiMgrsBottomParent() { }
|
||||
virtual ~TestMultiMgrsBottomParent() { }
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
};
|
||||
|
||||
class TestMultiMgrsLeftParent :
|
||||
|
@ -40,6 +43,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
|
||||
virtual PTestMultiMgrsBottomParent* AllocPTestMultiMgrsBottomParent() MOZ_OVERRIDE
|
||||
{
|
||||
return new TestMultiMgrsBottomParent();
|
||||
|
@ -65,6 +70,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE {}
|
||||
|
||||
virtual PTestMultiMgrsBottomParent* AllocPTestMultiMgrsBottomParent() MOZ_OVERRIDE
|
||||
{
|
||||
return new TestMultiMgrsBottomParent();
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "jit/IonLinker.h"
|
||||
#include "jit/PerfSpewer.h"
|
||||
|
||||
#include "jit/IonFrames-inl.h"
|
||||
#include "vm/Stack-inl.h"
|
||||
|
|
|
@ -5688,6 +5688,9 @@ TryAttachGlobalNameStub(JSContext *cx, HandleScript script, jsbytecode *pc,
|
|||
return true;
|
||||
}
|
||||
|
||||
// Try to add a getter stub. We don't handle scripted getters yet; if this
|
||||
// changes we need to make sure IonBuilder::getPropTryCommonGetter (which
|
||||
// requires a Baseline stub) handles non-outerized this objects correctly.
|
||||
bool isScripted;
|
||||
if (IsCacheableGetPropCall(cx, global, global, shape, &isScripted) && !isScripted)
|
||||
{
|
||||
|
@ -5741,6 +5744,10 @@ TryAttachScopeNameStub(JSContext *cx, HandleScript script, ICGetName_Fallback *s
|
|||
scopeChain = scopeChain->enclosingScope();
|
||||
}
|
||||
|
||||
// We don't handle getters here. When this changes, we need to make sure
|
||||
// IonBuilder::getPropTryCommonGetter (which requires a Baseline stub to
|
||||
// work) handles non-outerized this objects correctly.
|
||||
|
||||
if (!IsCacheableGetPropReadSlot(scopeChain, scopeChain, shape))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -8605,6 +8605,10 @@ IonBuilder::jsop_getprop(PropertyName *name)
|
|||
if (!getPropTryInlineAccess(&emitted, obj, name, barrier, types) || emitted)
|
||||
return emitted;
|
||||
|
||||
// Try to optimize accesses on outer window proxies, for example window.foo.
|
||||
if (!getPropTryInnerize(&emitted, obj, name, types) || emitted)
|
||||
return emitted;
|
||||
|
||||
// Try to emit a polymorphic cache.
|
||||
if (!getPropTryCache(&emitted, obj, name, barrier, types) || emitted)
|
||||
return emitted;
|
||||
|
@ -9074,6 +9078,79 @@ IonBuilder::getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name,
|
|||
return true;
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
IonBuilder::tryInnerizeWindow(MDefinition *obj)
|
||||
{
|
||||
// Try to optimize accesses on outer window proxies (window.foo, for
|
||||
// example) to go directly to the inner window, the global.
|
||||
//
|
||||
// Callers should be careful not to pass the inner object to getters or
|
||||
// setters that require outerization.
|
||||
|
||||
if (obj->type() != MIRType_Object)
|
||||
return obj;
|
||||
|
||||
types::TemporaryTypeSet *types = obj->resultTypeSet();
|
||||
if (!types)
|
||||
return obj;
|
||||
|
||||
JSObject *singleton = types->getSingleton();
|
||||
if (!singleton)
|
||||
return obj;
|
||||
|
||||
JSObject *inner = GetInnerObject(singleton);
|
||||
if (inner == singleton || inner != &script()->global())
|
||||
return obj;
|
||||
|
||||
// When we navigate, the outer object is brain transplanted and we'll mark
|
||||
// its TypeObject as having unknown properties. The type constraint we add
|
||||
// here will invalidate JIT code when this happens.
|
||||
types::TypeObjectKey *objType = types::TypeObjectKey::get(singleton);
|
||||
if (objType->hasFlags(constraints(), types::OBJECT_FLAG_UNKNOWN_PROPERTIES))
|
||||
return obj;
|
||||
|
||||
obj->setImplicitlyUsedUnchecked();
|
||||
return constant(ObjectValue(script()->global()));
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *name,
|
||||
types::TemporaryTypeSet *types)
|
||||
{
|
||||
// See the comment in tryInnerizeWindow for how this works.
|
||||
|
||||
MOZ_ASSERT(*emitted == false);
|
||||
|
||||
MDefinition *inner = tryInnerizeWindow(obj);
|
||||
if (inner == obj)
|
||||
return true;
|
||||
|
||||
// Note: the Baseline ICs don't know about this optimization, so it's
|
||||
// possible the global property's HeapTypeSet has not been initialized
|
||||
// yet. In this case we'll fall back to getPropTryCache for now.
|
||||
//
|
||||
// Also note that we don't call getPropTryCommonGetter below, because
|
||||
// (a) it requires a Baseline getter stub, which we don't have for outer
|
||||
// window proxies and (b) we have to be careful not to pass the inner
|
||||
// object to scripted getters etc. See bug 1007631.
|
||||
|
||||
if (!getPropTryConstant(emitted, inner, name, types) || *emitted)
|
||||
return *emitted;
|
||||
|
||||
if (!getStaticName(&script()->global(), name, emitted) || *emitted)
|
||||
return *emitted;
|
||||
|
||||
// Passing the inner object to GetProperty IC is safe, see the
|
||||
// needsOuterizedThisObject check in IsCacheableGetPropCallNative.
|
||||
BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(),
|
||||
inner, name, types);
|
||||
if (!getPropTryCache(emitted, inner, name, barrier, types) || *emitted)
|
||||
return *emitted;
|
||||
|
||||
MOZ_ASSERT(*emitted == false);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::needsToMonitorMissingProperties(types::TemporaryTypeSet *types)
|
||||
{
|
||||
|
|
|
@ -397,6 +397,8 @@ class IonBuilder : public MIRGenerator
|
|||
bool storeSlot(MDefinition *obj, Shape *shape, MDefinition *value, bool needsBarrier,
|
||||
MIRType slotType = MIRType_None);
|
||||
|
||||
MDefinition *tryInnerizeWindow(MDefinition *obj);
|
||||
|
||||
// jsop_getprop() helpers.
|
||||
bool getPropTryArgumentsLength(bool *emitted, MDefinition *obj);
|
||||
bool getPropTryConstant(bool *emitted, MDefinition *obj, PropertyName *name,
|
||||
|
@ -418,6 +420,8 @@ class IonBuilder : public MIRGenerator
|
|||
TypeDescrSet fieldTypeReprs,
|
||||
size_t fieldIndex,
|
||||
types::TemporaryTypeSet *resultTypes);
|
||||
bool getPropTryInnerize(bool *emitted, MDefinition *obj, PropertyName *name,
|
||||
types::TemporaryTypeSet *types);
|
||||
bool getPropTryCache(bool *emitted, MDefinition *obj, PropertyName *name,
|
||||
BarrierKind barrier, types::TemporaryTypeSet *types);
|
||||
bool needsToMonitorMissingProperties(types::TemporaryTypeSet *types);
|
||||
|
|
|
@ -1161,6 +1161,12 @@ CanAttachNativeGetProp(typename GetPropCache::Context cx, const GetPropCache &ca
|
|||
// IonBuilder guarantees that it's impossible to generate a GetPropertyIC with
|
||||
// allowGetters() true and cache.output().hasValue() false. If this isn't true,
|
||||
// we will quickly assert during stub generation.
|
||||
//
|
||||
// Be careful when adding support for other getters here: for outer window
|
||||
// proxies, IonBuilder can innerize and pass us the inner window (the global),
|
||||
// see IonBuilder::getPropTryInnerize. This is fine for native getters because
|
||||
// IsCacheableGetPropCallNative checks they can handle both the inner and
|
||||
// outer object, but scripted getters would need a similar mechanism.
|
||||
if (cache.allowGetters() &&
|
||||
(IsCacheableGetPropCallNative(obj, holder, shape) ||
|
||||
IsCacheableGetPropCallPropertyOp(obj, holder, shape)))
|
||||
|
|
|
@ -1238,6 +1238,18 @@ MarkJitActivations(JSRuntime *rt, JSTracer *trc)
|
|||
MarkJitActivation(trc, activations);
|
||||
}
|
||||
|
||||
JSCompartment *
|
||||
TopmostIonActivationCompartment(JSRuntime *rt)
|
||||
{
|
||||
for (JitActivationIterator activations(rt); !activations.done(); ++activations) {
|
||||
for (JitFrameIterator frames(activations); !frames.done(); ++frames) {
|
||||
if (frames.type() == JitFrame_IonJS)
|
||||
return activations.activation()->compartment();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
void
|
||||
UpdateJitActivationsForMinorGC(JSRuntime *rt, JSTracer *trc)
|
||||
|
|
|
@ -268,6 +268,9 @@ void EnsureExitFrame(IonCommonFrameLayout *frame);
|
|||
void MarkJitActivations(JSRuntime *rt, JSTracer *trc);
|
||||
void MarkIonCompilerRoots(JSTracer *trc);
|
||||
|
||||
JSCompartment *
|
||||
TopmostIonActivationCompartment(JSRuntime *rt);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
void UpdateJitActivationsForMinorGC(JSRuntime *rt, JSTracer *trc);
|
||||
#endif
|
||||
|
|
|
@ -292,6 +292,11 @@ MDefinition::dump(FILE *fp) const
|
|||
fprintf(fp, " = ");
|
||||
printOpcode(fp);
|
||||
fprintf(fp, "\n");
|
||||
|
||||
if (isInstruction()) {
|
||||
if (MResumePoint *resume = toInstruction()->resumePoint())
|
||||
resume->dump(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2306,6 +2311,41 @@ MResumePoint::inherit(MBasicBlock *block)
|
|||
}
|
||||
}
|
||||
|
||||
void MResumePoint::dump(FILE *fp) const
|
||||
{
|
||||
fprintf(fp, "resumepoint mode=");
|
||||
|
||||
switch (mode()) {
|
||||
case MResumePoint::ResumeAt:
|
||||
fprintf(fp, "At");
|
||||
break;
|
||||
case MResumePoint::ResumeAfter:
|
||||
fprintf(fp, "After");
|
||||
break;
|
||||
case MResumePoint::Outer:
|
||||
fprintf(fp, "Outer");
|
||||
break;
|
||||
}
|
||||
|
||||
if (MResumePoint *c = caller())
|
||||
fprintf(fp, " (caller in block%u)", c->block()->id());
|
||||
|
||||
for (size_t i = 0; i < numOperands(); i++) {
|
||||
fprintf(fp, " ");
|
||||
if (operands_[i].hasProducer())
|
||||
getOperand(i)->printName(fp);
|
||||
else
|
||||
fprintf(fp, "(null)");
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
MResumePoint::dump() const
|
||||
{
|
||||
dump(stderr);
|
||||
}
|
||||
|
||||
MDefinition *
|
||||
MToInt32::foldsTo(TempAllocator &alloc, bool useValueNumbers)
|
||||
{
|
||||
|
|
|
@ -217,6 +217,9 @@ class MNode : public TempObject
|
|||
|
||||
virtual bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
|
||||
virtual void dump(FILE *fp) const = 0;
|
||||
virtual void dump() const = 0;
|
||||
|
||||
protected:
|
||||
// Sets an unset operand, updating use information.
|
||||
virtual void setOperand(size_t index, MDefinition *operand) = 0;
|
||||
|
@ -613,6 +616,7 @@ class MDefinition : public MNode
|
|||
# undef OPCODE_CASTS
|
||||
|
||||
inline MInstruction *toInstruction();
|
||||
inline const MInstruction *toInstruction() const;
|
||||
bool isInstruction() const {
|
||||
return !isPhi();
|
||||
}
|
||||
|
@ -9669,7 +9673,7 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
|
|||
uint32_t stackDepth() const {
|
||||
return stackDepth_;
|
||||
}
|
||||
MResumePoint *caller() {
|
||||
MResumePoint *caller() const {
|
||||
return caller_;
|
||||
}
|
||||
void setCaller(MResumePoint *caller) {
|
||||
|
@ -9699,6 +9703,9 @@ class MResumePoint MOZ_FINAL : public MNode, public InlineForwardListNode<MResum
|
|||
}
|
||||
|
||||
bool writeRecoverData(CompactBufferWriter &writer) const;
|
||||
|
||||
virtual void dump(FILE *fp) const;
|
||||
virtual void dump() const;
|
||||
};
|
||||
|
||||
class MIsCallable
|
||||
|
@ -10206,6 +10213,12 @@ MInstruction *MDefinition::toInstruction()
|
|||
return (MInstruction *)this;
|
||||
}
|
||||
|
||||
const MInstruction *MDefinition::toInstruction() const
|
||||
{
|
||||
JS_ASSERT(!isPhi());
|
||||
return (const MInstruction *)this;
|
||||
}
|
||||
|
||||
typedef Vector<MDefinition *, 8, IonAllocPolicy> MDefinitionVector;
|
||||
|
||||
// Helper functions used to decide how to build MIR.
|
||||
|
|
|
@ -1278,6 +1278,9 @@ void
|
|||
MBasicBlock::dump(FILE *fp)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (MResumePoint *resume = entryResumePoint()) {
|
||||
resume->dump();
|
||||
}
|
||||
for (MPhiIterator iter(phisBegin()); iter != phisEnd(); iter++) {
|
||||
iter->dump(fp);
|
||||
}
|
||||
|
|
|
@ -2828,6 +2828,13 @@ BeginMarkPhase(JSRuntime *rt)
|
|||
c->zone()->setPreservingCode(true);
|
||||
}
|
||||
|
||||
if (!rt->gc.shouldCleanUpEverything) {
|
||||
#ifdef JS_ION
|
||||
if (JSCompartment *comp = jit::TopmostIonActivationCompartment(rt))
|
||||
comp->zone()->setPreservingCode(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Atoms are not in the cross-compartment map. So if there are any
|
||||
* zones that are not being collected, we are not allowed to collect
|
||||
|
|
|
@ -1394,7 +1394,7 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
|
|||
// Otherwise, always show the transition.
|
||||
if (!animate.EqualsLiteral("false") &&
|
||||
(!animate.EqualsLiteral("cancel") || aIsRollup)) {
|
||||
nsCOMPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aDeselectMenu);
|
||||
nsRefPtr<TransitionEnder> ender = new TransitionEnder(aPopup, aDeselectMenu);
|
||||
aPopup->AddSystemEventListener(NS_LITERAL_STRING("transitionend"),
|
||||
ender, false, false);
|
||||
return;
|
||||
|
|
|
@ -4123,4 +4123,4 @@ pref("beacon.enabled", true);
|
|||
|
||||
// Camera prefs
|
||||
pref("camera.control.autofocus_moving_callback.enabled", false);
|
||||
pref("camera.control.face_detection.enabled", false);
|
||||
pref("camera.control.face_detection.enabled", true);
|
||||
|
|
|
@ -377,8 +377,7 @@ nsAsyncStreamCopier::AsyncCopy(nsIRequestObserver *observer, nsISupports *ctx)
|
|||
|
||||
if (NS_IsMainThread()) {
|
||||
// Don't perform buffer sniffing on the main thread
|
||||
nsCOMPtr<AsyncApplyBufferingPolicyEvent> event
|
||||
= new AsyncApplyBufferingPolicyEvent(this);
|
||||
nsCOMPtr<nsIRunnable> event = new AsyncApplyBufferingPolicyEvent(this);
|
||||
rv = mTarget->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
|
|
|
@ -171,7 +171,7 @@ nsAboutCache::VisitNextStorage()
|
|||
// from visitor callback. The cache v1 service doesn't like it.
|
||||
// TODO - mayhemer, bug 913828, remove this dispatch and call
|
||||
// directly.
|
||||
nsCOMPtr<nsRunnableMethod<nsAboutCache> > event =
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NS_NewRunnableMethod(this, &nsAboutCache::FireVisitStorage);
|
||||
return NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
|
|
@ -322,7 +322,7 @@ main(int32_t argc, char *argv[])
|
|||
if (NS_WARN_IF(!timer)) {
|
||||
return -1;
|
||||
}
|
||||
nsCOMPtr<MulticastTimerCallback> timerCb = new MulticastTimerCallback();
|
||||
nsRefPtr<MulticastTimerCallback> timerCb = new MulticastTimerCallback();
|
||||
|
||||
// The following multicast tests using multiple sockets require a firewall
|
||||
// exception on Windows XP before they pass. For now, we'll skip them here.
|
||||
|
|
|
@ -250,6 +250,17 @@ this.FxAccountsManager = {
|
|||
return this._signOut();
|
||||
},
|
||||
|
||||
resendVerificationEmail: function() {
|
||||
return this._fxAccounts.resendVerificationEmail().then(
|
||||
(result) => {
|
||||
return result;
|
||||
},
|
||||
(error) => {
|
||||
return this._error(ERROR_SERVER_ERROR, error);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
getAccount: function() {
|
||||
// We check first if we have session details cached.
|
||||
if (this._activeSession) {
|
||||
|
|
|
@ -122,6 +122,15 @@ FxAccountsManager._fxAccounts = {
|
|||
return deferred.promise;
|
||||
},
|
||||
|
||||
resendVerificationEmail: function() {
|
||||
return this.getSignedInUser().then(data => {
|
||||
if (data) {
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
throw new Error("Cannot resend verification email; no signed-in user");
|
||||
});
|
||||
},
|
||||
|
||||
setSignedInUser: function(user) {
|
||||
this._setSignedInUserCalled = true;
|
||||
let deferred = Promise.defer();
|
||||
|
@ -580,6 +589,33 @@ add_test(function(test_signIn_already_signed_user) {
|
|||
);
|
||||
});
|
||||
|
||||
add_test(function(test_resendVerificationEmail_error_handling) {
|
||||
do_print("= resendVerificationEmail smoke test =");
|
||||
let user = FxAccountsManager._fxAccounts._signedInUser;
|
||||
FxAccountsManager._fxAccounts._signedInUser.verified = false;
|
||||
FxAccountsManager.resendVerificationEmail().then(
|
||||
(success) => {
|
||||
do_check_true(success);
|
||||
},
|
||||
(error) => {
|
||||
do_throw("Unexpected failure");
|
||||
}
|
||||
);
|
||||
// Here we verify that when FxAccounts.resendVerificationEmail
|
||||
// throws an error, we gracefully handle it in the reject() channel.
|
||||
FxAccountsManager._fxAccounts._signedInUser = null;
|
||||
FxAccountsManager.resendVerificationEmail().then(
|
||||
(success) => {
|
||||
do_throw("Unexpected success");
|
||||
},
|
||||
(error) => {
|
||||
do_check_eq(error.error, ERROR_SERVER_ERROR);
|
||||
}
|
||||
);
|
||||
FxAccountsManager._fxAccounts._signedInUser = user;
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function(test_verificationStatus_unverified_session_unverified_user) {
|
||||
do_print("= verificationStatus unverified session and user =");
|
||||
FakeFxAccountsClient._verified = false;
|
||||
|
|
|
@ -190,7 +190,8 @@ class MochitestRunner(MozbuildObject):
|
|||
jsdebugger=False, debug_on_failure=False, start_at=None, end_at=None,
|
||||
e10s=False, dmd=False, dump_output_directory=None,
|
||||
dump_about_memory_after_test=False, dump_dmd_after_test=False,
|
||||
install_extension=None, quiet=False, environment=[], app_override=None, **kwargs):
|
||||
install_extension=None, quiet=False, environment=[], app_override=None,
|
||||
useTestMediaDevices=False, **kwargs):
|
||||
"""Runs a mochitest.
|
||||
|
||||
test_paths are path to tests. They can be a relative path from the
|
||||
|
@ -315,6 +316,7 @@ class MochitestRunner(MozbuildObject):
|
|||
options.dumpOutputDirectory = dump_output_directory
|
||||
options.quiet = quiet
|
||||
options.environment = environment
|
||||
options.useTestMediaDevices = useTestMediaDevices
|
||||
|
||||
options.failureFile = failure_file_path
|
||||
if install_extension != None:
|
||||
|
@ -526,6 +528,12 @@ def MochitestCommand(func):
|
|||
help="Sets the given variable in the application's environment")
|
||||
func = setenv(func)
|
||||
|
||||
test_media = CommandArgument('--use-test-media-devices', default=False,
|
||||
action='store_true',
|
||||
dest='useTestMediaDevices',
|
||||
help='Use test media device drivers for media testing.')
|
||||
func = test_media(func)
|
||||
|
||||
app_override = CommandArgument('--app-override', default=None, action='store',
|
||||
help="Override the default binary used to run tests with the path you provide, e.g. " \
|
||||
" --app-override /usr/bin/firefox . " \
|
||||
|
|
|
@ -416,6 +416,12 @@ class MochitestOptions(optparse.OptionParser):
|
|||
"help": "name of the pidfile to generate",
|
||||
"default": "",
|
||||
}],
|
||||
[["--use-test-media-devices"],
|
||||
{ "action": "store_true",
|
||||
"default": False,
|
||||
"dest": "useTestMediaDevices",
|
||||
"help": "Use test media device drivers for media testing.",
|
||||
}],
|
||||
]
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
|
@ -574,6 +580,13 @@ class MochitestOptions(optparse.OptionParser):
|
|||
self.error('--dump-output-directory not a directory: %s' %
|
||||
options.dumpOutputDirectory)
|
||||
|
||||
if options.useTestMediaDevices:
|
||||
if not mozinfo.isLinux:
|
||||
self.error('--use-test-media-devices is only supported on Linux currently')
|
||||
for f in ['/usr/bin/gst-launch-0.10', '/usr/bin/pactl']:
|
||||
if not os.path.isfile(f):
|
||||
self.error('Missing binary %s required for --use-test-media-devices')
|
||||
|
||||
return options
|
||||
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import sys
|
|||
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
|
||||
sys.path.insert(0, SCRIPT_DIR);
|
||||
|
||||
import ctypes
|
||||
import glob
|
||||
import json
|
||||
import mozcrash
|
||||
|
@ -754,11 +755,123 @@ class SSLTunnel:
|
|||
if os.path.exists(self.configFile):
|
||||
os.remove(self.configFile)
|
||||
|
||||
def checkAndConfigureV4l2loopback(device):
|
||||
'''
|
||||
Determine if a given device path is a v4l2loopback device, and if so
|
||||
toggle a few settings on it via fcntl. Very linux-specific.
|
||||
|
||||
Returns (status, device name) where status is a boolean.
|
||||
'''
|
||||
if not mozinfo.isLinux:
|
||||
return False, ''
|
||||
|
||||
libc = ctypes.cdll.LoadLibrary('libc.so.6')
|
||||
O_RDWR = 2
|
||||
# These are from linux/videodev2.h
|
||||
class v4l2_capability(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('driver', ctypes.c_char * 16),
|
||||
('card', ctypes.c_char * 32),
|
||||
('bus_info', ctypes.c_char * 32),
|
||||
('version', ctypes.c_uint32),
|
||||
('capabilities', ctypes.c_uint32),
|
||||
('device_caps', ctypes.c_uint32),
|
||||
('reserved', ctypes.c_uint32 * 3)
|
||||
]
|
||||
VIDIOC_QUERYCAP = 0x80685600
|
||||
|
||||
fd = libc.open(device, O_RDWR)
|
||||
if fd < 0:
|
||||
return False, ''
|
||||
|
||||
vcap = v4l2_capability()
|
||||
if libc.ioctl(fd, VIDIOC_QUERYCAP, ctypes.byref(vcap)) != 0:
|
||||
return False, ''
|
||||
|
||||
if vcap.driver != 'v4l2 loopback':
|
||||
return False, ''
|
||||
|
||||
class v4l2_control(ctypes.Structure):
|
||||
_fields_ = [
|
||||
('id', ctypes.c_uint32),
|
||||
('value', ctypes.c_int32)
|
||||
]
|
||||
|
||||
# These are private v4l2 control IDs, see:
|
||||
# https://github.com/umlaeute/v4l2loopback/blob/fd822cf0faaccdf5f548cddd9a5a3dcebb6d584d/v4l2loopback.c#L131
|
||||
KEEP_FORMAT = 0x8000000
|
||||
SUSTAIN_FRAMERATE = 0x8000001
|
||||
VIDIOC_S_CTRL = 0xc008561c
|
||||
|
||||
control = v4l2_control()
|
||||
control.id = KEEP_FORMAT
|
||||
control.value = 1
|
||||
libc.ioctl(fd, VIDIOC_S_CTRL, ctypes.byref(control))
|
||||
|
||||
control.id = SUSTAIN_FRAMERATE
|
||||
control.value = 1
|
||||
libc.ioctl(fd, VIDIOC_S_CTRL, ctypes.byref(control))
|
||||
libc.close(fd)
|
||||
|
||||
return True, vcap.card
|
||||
|
||||
def findTestMediaDevices():
|
||||
'''
|
||||
Find the test media devices configured on this system, and return a dict
|
||||
containing information about them. The dict will have keys for 'audio'
|
||||
and 'video', each containing the name of the media device to use.
|
||||
|
||||
If audio and video devices could not be found, return None.
|
||||
|
||||
This method is only currently implemented for Linux.
|
||||
'''
|
||||
if not mozinfo.isLinux:
|
||||
return None
|
||||
|
||||
info = {}
|
||||
# Look for a v4l2loopback device.
|
||||
name = None
|
||||
device = None
|
||||
for dev in sorted(glob.glob('/dev/video*')):
|
||||
result, name_ = checkAndConfigureV4l2loopback(dev)
|
||||
if result:
|
||||
name = name_
|
||||
device = dev
|
||||
break
|
||||
|
||||
if not (name and device):
|
||||
log.error('Couldn\'t find a v4l2loopback video device')
|
||||
return None
|
||||
|
||||
# Feed it a frame of output so it has something to display
|
||||
subprocess.check_call(['/usr/bin/gst-launch-0.10', 'videotestsrc',
|
||||
'pattern=green', 'num-buffers=1', '!',
|
||||
'v4l2sink', 'device=%s' % device])
|
||||
info['video'] = name
|
||||
|
||||
# Use pactl to see if the PulseAudio module-sine-source module is loaded.
|
||||
def sine_source_loaded():
|
||||
o = subprocess.check_output(['/usr/bin/pactl', 'list', 'short', 'modules'])
|
||||
return filter(lambda x: 'module-sine-source' in x, o.splitlines())
|
||||
|
||||
if not sine_source_loaded():
|
||||
# Load module-sine-source
|
||||
subprocess.check_call(['/usr/bin/pactl', 'load-module',
|
||||
'module-sine-source'])
|
||||
if not sine_source_loaded():
|
||||
log.error('Couldn\'t load module-sine-source')
|
||||
return None
|
||||
|
||||
# Hardcode the name since it's always the same.
|
||||
info['audio'] = 'Sine source at 440 Hz'
|
||||
return info
|
||||
|
||||
class Mochitest(MochitestUtilsMixin):
|
||||
certdbNew = False
|
||||
sslTunnel = None
|
||||
vmwareHelper = None
|
||||
DEFAULT_TIMEOUT = 60.0
|
||||
mediaDevices = None
|
||||
|
||||
# XXX use automation.py for test name to avoid breaking legacy
|
||||
# TODO: replace this with 'runtests.py' or 'mochitest' or the like
|
||||
|
@ -877,6 +990,11 @@ class Mochitest(MochitestUtilsMixin):
|
|||
'ws': options.sslPort
|
||||
}
|
||||
|
||||
# See if we should use fake media devices.
|
||||
if options.useTestMediaDevices:
|
||||
prefs['media.audio_loopback_dev'] = self.mediaDevices['audio']
|
||||
prefs['media.video_loopback_dev'] = self.mediaDevices['video']
|
||||
|
||||
|
||||
# create a profile
|
||||
self.profile = Profile(profile=options.profilePath,
|
||||
|
@ -1225,6 +1343,13 @@ class Mochitest(MochitestUtilsMixin):
|
|||
options.debuggerArgs,
|
||||
options.debuggerInteractive)
|
||||
|
||||
if options.useTestMediaDevices:
|
||||
devices = findTestMediaDevices()
|
||||
if not devices:
|
||||
log.error("Could not find test media devices to use")
|
||||
return 1
|
||||
self.mediaDevices = devices
|
||||
|
||||
self.leak_report_file = os.path.join(options.profilePath, "runtests_leaks.log")
|
||||
|
||||
browserEnv = self.buildBrowserEnv(options, debuggerInfo is not None)
|
||||
|
|
|
@ -117,10 +117,22 @@ if (LINUX) {
|
|||
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
|
||||
}
|
||||
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
let removed = false;
|
||||
do {
|
||||
try {
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
|
||||
removed = true;
|
||||
} catch (ex if ex instanceof OS.File.Error &&
|
||||
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
|
||||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
|
||||
// Wait 100 ms before attempting to remove again.
|
||||
yield wait(100);
|
||||
}
|
||||
} while (!removed);
|
||||
});
|
||||
};
|
||||
} else if (MAC) {
|
||||
|
|
|
@ -117,10 +117,22 @@ if (LINUX) {
|
|||
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
|
||||
}
|
||||
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
let removed = false;
|
||||
do {
|
||||
try {
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
|
||||
removed = true;
|
||||
} catch (ex if ex instanceof OS.File.Error &&
|
||||
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
|
||||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
|
||||
// Wait 100 ms before attempting to remove again.
|
||||
yield wait(100);
|
||||
}
|
||||
} while (!removed);
|
||||
});
|
||||
};
|
||||
} else if (MAC) {
|
||||
|
|
|
@ -122,10 +122,22 @@ if (LINUX) {
|
|||
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
|
||||
}
|
||||
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
let removed = false;
|
||||
do {
|
||||
try {
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
|
||||
removed = true;
|
||||
} catch (ex if ex instanceof OS.File.Error &&
|
||||
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
|
||||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
|
||||
// Wait 100 ms before attempting to remove again.
|
||||
yield wait(100);
|
||||
}
|
||||
} while (!removed);
|
||||
});
|
||||
};
|
||||
} else if (MAC) {
|
||||
|
|
|
@ -127,10 +127,22 @@ if (LINUX) {
|
|||
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
|
||||
}
|
||||
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
let removed = false;
|
||||
do {
|
||||
try {
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
|
||||
removed = true;
|
||||
} catch (ex if ex instanceof OS.File.Error &&
|
||||
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
|
||||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
|
||||
// Wait 100 ms before attempting to remove again.
|
||||
yield wait(100);
|
||||
}
|
||||
} while (!removed);
|
||||
});
|
||||
};
|
||||
} else if (MAC) {
|
||||
|
|
|
@ -127,10 +127,22 @@ if (LINUX) {
|
|||
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
|
||||
}
|
||||
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
let removed = false;
|
||||
do {
|
||||
try {
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
|
||||
removed = true;
|
||||
} catch (ex if ex instanceof OS.File.Error &&
|
||||
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
|
||||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
|
||||
// Wait 100 ms before attempting to remove again.
|
||||
yield wait(100);
|
||||
}
|
||||
} while (!removed);
|
||||
});
|
||||
};
|
||||
} else if (MAC) {
|
||||
|
|
|
@ -135,10 +135,22 @@ if (LINUX) {
|
|||
yield OS.File.removeDir(profileDir.parent.parent.path, { ignoreAbsent: true });
|
||||
}
|
||||
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
let removed = false;
|
||||
do {
|
||||
try {
|
||||
yield OS.File.removeDir(installPath, { ignoreAbsent: true });
|
||||
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(desktopShortcut, { ignoreAbsent: true });
|
||||
yield OS.File.remove(startMenuShortcut, { ignoreAbsent: true });
|
||||
|
||||
removed = true;
|
||||
} catch (ex if ex instanceof OS.File.Error &&
|
||||
(ex.winLastError == OS.Constants.Win.ERROR_SUCCESS ||
|
||||
ex.winLastError == OS.Constants.Win.ERROR_SHARING_VIOLATION)) {
|
||||
// Wait 100 ms before attempting to remove again.
|
||||
yield wait(100);
|
||||
}
|
||||
} while (!removed);
|
||||
});
|
||||
};
|
||||
} else if (MAC) {
|
||||
|
|
|
@ -1243,6 +1243,8 @@ private:
|
|||
void MarkRoots(SliceBudget &aBudget);
|
||||
void ScanRoots(bool aFullySynchGraphBuild);
|
||||
void ScanIncrementalRoots();
|
||||
void ScanWhiteNodes(bool aFullySynchGraphBuild);
|
||||
void ScanBlackNodes();
|
||||
void ScanWeakMaps();
|
||||
|
||||
// returns whether anything was collected
|
||||
|
@ -2680,50 +2682,6 @@ FloodBlackNode(uint32_t& aWhiteNodeCount, bool& aFailed, PtrInfo* aPi)
|
|||
MOZ_ASSERT(aPi->mColor == black || !aPi->mParticipant, "FloodBlackNode should make aPi black");
|
||||
}
|
||||
|
||||
struct scanVisitor
|
||||
{
|
||||
scanVisitor(uint32_t &aWhiteNodeCount, bool &aFailed, bool aWasIncremental)
|
||||
: mWhiteNodeCount(aWhiteNodeCount), mFailed(aFailed),
|
||||
mWasIncremental(aWasIncremental)
|
||||
{
|
||||
}
|
||||
|
||||
bool ShouldVisitNode(PtrInfo const *pi)
|
||||
{
|
||||
return pi->mColor == grey;
|
||||
}
|
||||
|
||||
MOZ_NEVER_INLINE void VisitNode(PtrInfo *pi)
|
||||
{
|
||||
if (pi->mInternalRefs > pi->mRefCount && pi->mRefCount > 0) {
|
||||
// If we found more references to an object than its ref count, then
|
||||
// the object should have already been marked as an incremental
|
||||
// root. Note that this is imprecise, because pi could have been
|
||||
// marked black for other reasons. Always fault if we weren't
|
||||
// incremental, as there were no incremental roots in that case.
|
||||
if (!mWasIncremental || pi->mColor != black) {
|
||||
Fault("traversed refs exceed refcount", pi);
|
||||
}
|
||||
}
|
||||
|
||||
if (pi->mInternalRefs == pi->mRefCount || pi->mRefCount == 0) {
|
||||
pi->mColor = white;
|
||||
++mWhiteNodeCount;
|
||||
} else {
|
||||
FloodBlackNode(mWhiteNodeCount, mFailed, pi);
|
||||
}
|
||||
}
|
||||
|
||||
void Failed() {
|
||||
mFailed = true;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t &mWhiteNodeCount;
|
||||
bool &mFailed;
|
||||
bool mWasIncremental;
|
||||
};
|
||||
|
||||
// Iterate over the WeakMaps. If we mark anything while iterating
|
||||
// over the WeakMaps, we must iterate over all of the WeakMaps again.
|
||||
void
|
||||
|
@ -2742,10 +2700,6 @@ nsCycleCollector::ScanWeakMaps()
|
|||
uint32_t kdColor = wm->mKeyDelegate ? wm->mKeyDelegate->mColor : black;
|
||||
uint32_t vColor = wm->mVal ? wm->mVal->mColor : black;
|
||||
|
||||
// All non-null weak mapping maps, keys and values are
|
||||
// roots (in the sense of WalkFromRoots) in the cycle
|
||||
// collector graph, and thus should have been colored
|
||||
// either black or white in ScanRoots().
|
||||
MOZ_ASSERT(mColor != grey, "Uncolored weak map");
|
||||
MOZ_ASSERT(kColor != grey, "Uncolored weak map key");
|
||||
MOZ_ASSERT(kdColor != grey, "Uncolored weak map key delegate");
|
||||
|
@ -2895,6 +2849,68 @@ nsCycleCollector::ScanIncrementalRoots()
|
|||
}
|
||||
}
|
||||
|
||||
// Mark nodes white and make sure their refcounts are ok.
|
||||
// No nodes are marked black during this pass to ensure that refcount
|
||||
// checking is run on all nodes not marked black by ScanIncrementalRoots.
|
||||
void
|
||||
nsCycleCollector::ScanWhiteNodes(bool aFullySynchGraphBuild)
|
||||
{
|
||||
NodePool::Enumerator nodeEnum(mGraph.mNodes);
|
||||
while (!nodeEnum.IsDone()) {
|
||||
PtrInfo* pi = nodeEnum.GetNext();
|
||||
if (pi->mColor == black) {
|
||||
// Incremental roots can be in a nonsensical state, so don't
|
||||
// check them. This will miss checking nodes that are merely
|
||||
// reachable from incremental roots.
|
||||
MOZ_ASSERT(!aFullySynchGraphBuild,
|
||||
"In a synch CC, no nodes should be marked black early on.");
|
||||
continue;
|
||||
}
|
||||
MOZ_ASSERT(pi->mColor == grey);
|
||||
|
||||
if (!pi->mParticipant) {
|
||||
// This node has been deleted, so it could be in a mangled state, but
|
||||
// that's okay because we're not going to look at it again.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pi->mInternalRefs == pi->mRefCount || pi->mRefCount == 0) {
|
||||
pi->mColor = white;
|
||||
++mWhiteNodeCount;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (MOZ_LIKELY(pi->mInternalRefs < pi->mRefCount)) {
|
||||
// This node will get marked black in the next pass.
|
||||
continue;
|
||||
}
|
||||
|
||||
Fault("Traversed refs exceed refcount", pi);
|
||||
}
|
||||
}
|
||||
|
||||
// Any remaining grey nodes that haven't already been deleted must be alive,
|
||||
// so mark them and their children black. Any nodes that are black must have
|
||||
// already had their children marked black, so there's no need to look at them
|
||||
// again. This pass may turn some white nodes to black.
|
||||
void
|
||||
nsCycleCollector::ScanBlackNodes()
|
||||
{
|
||||
bool failed = false;
|
||||
NodePool::Enumerator nodeEnum(mGraph.mNodes);
|
||||
while (!nodeEnum.IsDone()) {
|
||||
PtrInfo* pi = nodeEnum.GetNext();
|
||||
if (pi->mColor == grey && pi->mParticipant) {
|
||||
FloodBlackNode(mWhiteNodeCount, failed, pi);
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
NS_ASSERTION(false, "Ran out of memory in ScanBlackNodes");
|
||||
CC_TELEMETRY(_OOM, true);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsCycleCollector::ScanRoots(bool aFullySynchGraphBuild)
|
||||
{
|
||||
|
@ -2909,19 +2925,11 @@ nsCycleCollector::ScanRoots(bool aFullySynchGraphBuild)
|
|||
}
|
||||
|
||||
TimeLog timeLog;
|
||||
ScanWhiteNodes(aFullySynchGraphBuild);
|
||||
timeLog.Checkpoint("ScanRoots::ScanWhiteNodes");
|
||||
|
||||
// On the assumption that most nodes will be black, it's
|
||||
// probably faster to use a GraphWalker than a
|
||||
// NodePool::Enumerator.
|
||||
bool failed = false;
|
||||
scanVisitor sv(mWhiteNodeCount, failed, !aFullySynchGraphBuild);
|
||||
GraphWalker<scanVisitor>(sv).WalkFromRoots(mGraph);
|
||||
timeLog.Checkpoint("ScanRoots::WalkFromRoots");
|
||||
|
||||
if (failed) {
|
||||
NS_ASSERTION(false, "Ran out of memory in ScanRoots");
|
||||
CC_TELEMETRY(_OOM, true);
|
||||
}
|
||||
ScanBlackNodes();
|
||||
timeLog.Checkpoint("ScanRoots::ScanBlackNodes");
|
||||
|
||||
// Scanning weak maps must be done last.
|
||||
ScanWeakMaps();
|
||||
|
|
Загрузка…
Ссылка в новой задаче