diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml
index 9ca1c3a3513..eceeca280b8 100644
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -19,13 +19,13 @@
-
+
-
+
diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml
index 820f8268e1e..5304bfd4c92 100644
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml
index 325c5d8b067..62744b1cdf5 100644
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -15,14 +15,14 @@
-
+
-
+
diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml
index 9ca1c3a3513..eceeca280b8 100644
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -19,13 +19,13 @@
-
+
-
+
diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml
index 77f372a35ef..aaa39c29283 100644
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -18,10 +18,10 @@
-
+
-
+
diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json
index caba60e33ef..a8009ace668 100644
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
- "revision": "ee7c5efe7a7f24887ee7f772311a9a37997ae232",
+ "revision": "993067c495a5e0956dfe4169f1f48d9a791304f0",
"repo_path": "/integration/gaia-central"
}
diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml
index a1b2905321a..b87d1a2133d 100644
--- a/b2g/config/hamachi/sources.xml
+++ b/b2g/config/hamachi/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml
index 1b3c5f02cb6..484b2281bd6 100644
--- a/b2g/config/helix/sources.xml
+++ b/b2g/config/helix/sources.xml
@@ -15,7 +15,7 @@
-
+
diff --git a/b2g/config/inari/sources.xml b/b2g/config/inari/sources.xml
index 2f26cf699ac..d6c6292cfa3 100644
--- a/b2g/config/inari/sources.xml
+++ b/b2g/config/inari/sources.xml
@@ -19,12 +19,12 @@
-
+
-
+
diff --git a/b2g/config/leo/sources.xml b/b2g/config/leo/sources.xml
index 699159a474c..f272014ccbb 100644
--- a/b2g/config/leo/sources.xml
+++ b/b2g/config/leo/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/b2g/config/mako/sources.xml b/b2g/config/mako/sources.xml
index 9f45639efef..d0af9377bec 100644
--- a/b2g/config/mako/sources.xml
+++ b/b2g/config/mako/sources.xml
@@ -17,10 +17,10 @@
-
+
-
+
diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml
index c17b25b0ba6..8ab49b5f019 100644
--- a/b2g/config/wasabi/sources.xml
+++ b/b2g/config/wasabi/sources.xml
@@ -17,12 +17,12 @@
-
+
-
+
diff --git a/build/gyp.mozbuild b/build/gyp.mozbuild
index e1733518166..9595ba3803f 100644
--- a/build/gyp.mozbuild
+++ b/build/gyp.mozbuild
@@ -7,6 +7,7 @@
gyp_vars = {
'build_with_mozilla': 1,
'build_with_chromium': 0,
+ 'use_official_google_api_keys': 0,
'have_clock_monotonic': 1 if CONFIG['HAVE_CLOCK_MONOTONIC'] else 0,
'have_ethtool_cmd_speed_hi': 1 if CONFIG['MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI'] else 0,
'include_alsa_audio': 1 if CONFIG['MOZ_ALSA'] else 0,
diff --git a/content/media/gtest/TestVorbisTrackEncoder.cpp b/content/media/gtest/TestVorbisTrackEncoder.cpp
new file mode 100644
index 00000000000..bf9d2683d04
--- /dev/null
+++ b/content/media/gtest/TestVorbisTrackEncoder.cpp
@@ -0,0 +1,223 @@
+/* -*- 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 "VorbisTrackEncoder.h"
+#include "WebMWriter.h"
+#include "MediaStreamGraph.h"
+
+using namespace mozilla;
+
+class TestVorbisTrackEncoder : public VorbisTrackEncoder
+{
+public:
+ // Return true if it has successfully initialized the vorbis encoder.
+ bool TestVorbisCreation(int aChannels, int aSamplingRate)
+ {
+ if (Init(aChannels, aSamplingRate) == NS_OK) {
+ return true;
+ }
+ return false;
+ }
+};
+
+static bool
+TestVorbisInit(int aChannels, int aSamplingRate)
+{
+ TestVorbisTrackEncoder encoder;
+ return encoder.TestVorbisCreation(aChannels, aSamplingRate);
+}
+
+static int
+ReadLacing(const uint8_t* aInput, uint32_t aInputLength, uint32_t& aReadBytes)
+{
+ aReadBytes = 0;
+
+ int packetSize = 0;
+ while (aReadBytes < aInputLength) {
+ if (aInput[aReadBytes] == 255) {
+ packetSize += 255;
+ aReadBytes++;
+ } else { // the last byte
+ packetSize += aInput[aReadBytes];
+ aReadBytes++;
+ break;
+ }
+ }
+
+ return packetSize;
+}
+
+static bool
+parseVorbisMetadata(nsTArray& aData, int aChannels, int aRate)
+{
+ uint32_t offset = 0;
+ // the first byte should be 2.
+ if (aData.ElementAt(0) != 2) {
+ return false;
+ }
+ offset = 1;
+
+ // Read the length of header and header_comm
+ uint32_t readbytes;
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+ memset(&header, 0, sizeof(ogg_packet));
+ memset(&header_comm, 0, sizeof(ogg_packet));
+ memset(&header_code, 0, sizeof(ogg_packet));
+
+ int header_length;
+ int header_comm_length;
+ int header_code_length;
+ EXPECT_TRUE(offset < aData.Length());
+ header_length = ReadLacing(aData.Elements()+offset, aData.Length()-offset,
+ readbytes);
+ offset += readbytes;
+ EXPECT_TRUE(offset < aData.Length());
+ header_comm_length = ReadLacing(aData.Elements()+offset,
+ aData.Length()-offset, readbytes);
+ offset += readbytes;
+ EXPECT_TRUE(offset < aData.Length());
+ // The rest length is header_code.
+ header_code_length = aData.Length() - offset - header_length
+ - header_comm_length;
+ EXPECT_TRUE(header_code_length >= 32);
+
+ // Verify the three header packets by vorbis_synthesis_headerin.
+ // Raise the b_o_s (begin of stream) flag.
+ header.b_o_s = true;
+ header.packet = aData.Elements() + offset;
+ header.bytes = header_length;
+ offset += header_length;
+ header_comm.packet = aData.Elements() + offset;
+ header_comm.bytes = header_comm_length;
+ offset += header_comm_length;
+ header_code.packet = aData.Elements() + offset;
+ header_code.bytes = header_code_length;
+
+ vorbis_info vi;
+ vorbis_comment vc;
+ vorbis_info_init(&vi);
+ vorbis_comment_init(&vc);
+
+ EXPECT_TRUE(0 == vorbis_synthesis_headerin(&vi, &vc, &header));
+
+ EXPECT_TRUE(0 == vorbis_synthesis_headerin(&vi, &vc, &header_comm));
+
+ EXPECT_TRUE(0 == vorbis_synthesis_headerin(&vi, &vc, &header_code));
+
+ EXPECT_TRUE(vi.channels == aChannels);
+ EXPECT_TRUE(vi.rate == aRate);
+
+ vorbis_info_clear(&vi);
+ vorbis_comment_clear(&vc);
+
+ return true;
+}
+
+// Test init function
+TEST(VorbisTrackEncoder, Init)
+{
+ // Channel number range test
+ // Expect false with 0 or negative channels of input signal.
+ EXPECT_FALSE(TestVorbisInit(0, 16000));
+ EXPECT_FALSE(TestVorbisInit(-1, 16000));
+ EXPECT_FALSE(TestVorbisInit(8 + 1, 16000));
+
+ // Sample rate and channel range test.
+ for (int i = 1; i <= 8; i++) {
+ EXPECT_FALSE(TestVorbisInit(i, -1));
+ EXPECT_TRUE(TestVorbisInit(i, 8000));
+ EXPECT_TRUE(TestVorbisInit(i, 11000));
+ EXPECT_TRUE(TestVorbisInit(i, 16000));
+ EXPECT_TRUE(TestVorbisInit(i, 22050));
+ EXPECT_TRUE(TestVorbisInit(i, 32000));
+ EXPECT_TRUE(TestVorbisInit(i, 44100));
+ EXPECT_TRUE(TestVorbisInit(i, 48000));
+ EXPECT_TRUE(TestVorbisInit(i, 96000));
+ EXPECT_FALSE(TestVorbisInit(i, 200000 + 1));
+ }
+}
+
+// Test metadata
+TEST(VorbisTrackEncoder, Metadata)
+{
+ // Initiate vorbis encoder.
+ TestVorbisTrackEncoder encoder;
+ int channels = 1;
+ int rate = 44100;
+ encoder.TestVorbisCreation(channels, rate);
+
+ nsRefPtr meta = encoder.GetMetadata();
+ nsRefPtr vorbisMetadata(static_cast(meta.get()));
+
+ // According to initialization parameters, verify the correctness
+ // of vorbisMetadata.
+ EXPECT_TRUE(vorbisMetadata->mChannels == channels);
+ EXPECT_TRUE(vorbisMetadata->mSamplingFrequency == rate);
+ EXPECT_TRUE(parseVorbisMetadata(vorbisMetadata->mData, channels, rate));
+}
+
+// Test encode function
+TEST(VorbisTrackEncoder, EncodedFrame)
+{
+ // Initiate vorbis encoder
+ TestVorbisTrackEncoder encoder;
+ int channels = 1;
+ int rate = 44100;
+ encoder.TestVorbisCreation(channels, rate);
+
+ // Generate 1 second samples.
+ // Reference PeerConnectionMedia.h::Fake_AudioGenerator
+ nsRefPtr samples =
+ mozilla::SharedBuffer::Create(rate * sizeof(AudioDataValue));
+ AudioDataValue* data = static_cast(samples->Data());
+ for (int i = 0; i < rate; i++) {
+ data[i] = ((i%8)*4000) - (7*4000)/2;
+ }
+ nsAutoTArray channelData;
+ channelData.AppendElement(data);
+ AudioSegment segment;
+ segment.AppendFrames(samples.forget(), channelData, 44100);
+
+ // Track change notification.
+ encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0, 0, segment);
+
+ // Pull Encoded data back from encoder and verify encoded samples.
+ EncodedFrameContainer container;
+ EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
+ // Should have some encoded data.
+ EXPECT_TRUE(container.GetEncodedFrames().Length() > 0);
+ EXPECT_TRUE(container.GetEncodedFrames().ElementAt(0)->GetFrameData().Length()
+ > 0);
+ EXPECT_TRUE(container.GetEncodedFrames().ElementAt(0)->GetFrameType() ==
+ EncodedFrame::FrameType::VORBIS_AUDIO_FRAME);
+ // Encoded data doesn't have duration and timestamp.
+ EXPECT_TRUE(container.GetEncodedFrames().ElementAt(0)->GetDuration() == 0);
+ EXPECT_TRUE(container.GetEncodedFrames().ElementAt(0)->GetTimeStamp() == 0);
+}
+
+// EOS test
+TEST(VorbisTrackEncoder, EncodeComplete)
+{
+ // Initiate vorbis encoder
+ TestVorbisTrackEncoder encoder;
+ int channels = 1;
+ int rate = 44100;
+ encoder.TestVorbisCreation(channels, rate);
+
+ // Track end notification.
+ AudioSegment segment;
+ encoder.NotifyQueuedTrackChanges(nullptr, 0, 0, 0,
+ MediaStreamListener::TRACK_EVENT_ENDED,
+ segment);
+
+ // Pull Encoded Data back from encoder. Since we had send out
+ // EOS to encoder, encoder.GetEncodedTrack should return
+ // NS_OK immidiately.
+ EncodedFrameContainer container;
+ EXPECT_TRUE(NS_SUCCEEDED(encoder.GetEncodedTrack(container)));
+}
diff --git a/content/media/gtest/moz.build b/content/media/gtest/moz.build
index 089894bffb6..ab107f78d9b 100644
--- a/content/media/gtest/moz.build
+++ b/content/media/gtest/moz.build
@@ -13,6 +13,7 @@ UNIFIED_SOURCES += [
if CONFIG['MOZ_WEBM_ENCODER']:
UNIFIED_SOURCES += ['TestVideoTrackEncoder.cpp',
+ 'TestVorbisTrackEncoder.cpp',
]
EXPORT_LIBRARY = True
diff --git a/content/media/test/crashtests/crashtests.list b/content/media/test/crashtests/crashtests.list
index 019d132c1e1..4585bc4aa28 100644
--- a/content/media/test/crashtests/crashtests.list
+++ b/content/media/test/crashtests/crashtests.list
@@ -66,7 +66,7 @@ load 952756.html
load 986901.html
load buffer-source-ended-1.html
load offline-buffer-source-ended-1.html
-skip-if(B2G) HTTP load media-element-source-seek-1.html # intermittent B2G timeouts, bug 994351
+HTTP load media-element-source-seek-1.html
skip-if(B2G) load oscillator-ended-1.html # intermittent B2G timeouts, bug 920338
skip-if(B2G) load oscillator-ended-2.html # intermittent B2G timeouts, bug 920338
include ../../mediasource/test/crashtests/crashtests.list
diff --git a/content/media/test/crashtests/media-element-source-seek-1.html b/content/media/test/crashtests/media-element-source-seek-1.html
index 95646572362..2f6a11e66e7 100644
--- a/content/media/test/crashtests/media-element-source-seek-1.html
+++ b/content/media/test/crashtests/media-element-source-seek-1.html
@@ -6,14 +6,15 @@ audioElement.autoplay = true;
audioElement.src = "sound.ogg";
audioElement.onplaying =
function() {
- audioElement.onseeked =
+ audioElement.onplaying = null;
+ setTimeout(
function() {
- setTimeout(
+ audioElement.onseeked =
function() {
document.documentElement.removeAttribute("class");
- }, 100);
- };
- audioElement.currentTime = 0;
+ };
+ audioElement.currentTime = 0;
+ }, 100);
};
var context = new window.AudioContext();
diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h
index 04ec4af5e75..00b2f4df922 100644
--- a/dom/devicestorage/DeviceStorage.h
+++ b/dom/devicestorage/DeviceStorage.h
@@ -256,6 +256,9 @@ public:
already_AddRefed Mount(ErrorResult& aRv);
already_AddRefed Unmount(ErrorResult& aRv);
+ bool CanBeMounted();
+ bool CanBeFormatted();
+ bool CanBeShared();
bool Default();
// Uses XPCOM GetStorageName
@@ -305,6 +308,7 @@ private:
nsString mStorageType;
nsCOMPtr mRootDirectory;
nsString mStorageName;
+ bool mIsShareable;
already_AddRefed GetStorage(const nsAString& aFullPath,
nsAString& aOutStoragePath);
diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp
index 020b3ea3946..9828ab671b8 100644
--- a/dom/devicestorage/nsDeviceStorage.cpp
+++ b/dom/devicestorage/nsDeviceStorage.cpp
@@ -3100,6 +3100,7 @@ NS_IMPL_RELEASE_INHERITED(nsDOMDeviceStorage, DOMEventTargetHelper)
nsDOMDeviceStorage::nsDOMDeviceStorage(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow)
+ , mIsShareable(false)
, mIsWatchingFile(false)
, mAllowedToWatchFile(false)
{
@@ -3127,6 +3128,27 @@ nsDOMDeviceStorage::Init(nsPIDOMWindow* aWindow, const nsAString &aType,
}
if (!mStorageName.IsEmpty()) {
RegisterForSDCardChanges(this);
+
+#ifdef MOZ_WIDGET_GONK
+ if (DeviceStorageTypeChecker::IsVolumeBased(mStorageType)) {
+ nsCOMPtr vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID);
+ if (NS_WARN_IF(!vs)) {
+ return NS_ERROR_FAILURE;
+ }
+ nsresult rv;
+ nsCOMPtr vol;
+ rv = vs->GetVolumeByName(mStorageName, getter_AddRefs(vol));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ bool isFake;
+ rv = vol->GetIsFake(&isFake);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ mIsShareable = !isFake;
+ }
+#endif
}
// Grab the principal of the document
@@ -3913,6 +3935,26 @@ nsDOMDeviceStorage::Default()
return mStorageName.Equals(defaultStorageName);
}
+bool
+nsDOMDeviceStorage::CanBeFormatted()
+{
+ // Currently, any volume which can be shared can also be formatted.
+ return mIsShareable;
+}
+
+bool
+nsDOMDeviceStorage::CanBeMounted()
+{
+ // Currently, any volume which can be shared can also be mounted/unmounted.
+ return mIsShareable;
+}
+
+bool
+nsDOMDeviceStorage::CanBeShared()
+{
+ return mIsShareable;
+}
+
already_AddRefed
nsDOMDeviceStorage::GetRoot()
{
diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp
index 7be3aba227c..65b01924891 100644
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1690,12 +1690,13 @@ ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
const int32_t& aMountGeneration,
const bool& aIsMediaPresent,
const bool& aIsSharing,
- const bool& aIsFormatting)
+ const bool& aIsFormatting,
+ const bool& aIsFake)
{
#ifdef MOZ_WIDGET_GONK
nsRefPtr volume = new nsVolume(aFsName, aVolumeName, aState,
aMountGeneration, aIsMediaPresent,
- aIsSharing, aIsFormatting);
+ aIsSharing, aIsFormatting, aIsFake);
nsRefPtr vs = nsVolumeService::GetSingleton();
if (vs) {
@@ -1710,6 +1711,7 @@ ContentChild::RecvFileSystemUpdate(const nsString& aFsName,
unused << aIsMediaPresent;
unused << aIsSharing;
unused << aIsFormatting;
+ unused << aIsFake;
#endif
return true;
}
diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h
index f5d65b0739e..12b3f533dd7 100644
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -256,7 +256,8 @@ public:
const int32_t& aMountGeneration,
const bool& aIsMediaPresent,
const bool& aIsSharing,
- const bool& aIsFormatting) MOZ_OVERRIDE;
+ const bool& aIsFormatting,
+ const bool& aIsFake) MOZ_OVERRIDE;
virtual bool RecvNuwaFork() MOZ_OVERRIDE;
diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp
index 7b037f48868..590570d6dbc 100644
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -2237,6 +2237,7 @@ ContentParent::Observe(nsISupports* aSubject,
bool isMediaPresent;
bool isSharing;
bool isFormatting;
+ bool isFake;
vol->GetName(volName);
vol->GetMountPoint(mountPoint);
@@ -2245,10 +2246,11 @@ ContentParent::Observe(nsISupports* aSubject,
vol->GetIsMediaPresent(&isMediaPresent);
vol->GetIsSharing(&isSharing);
vol->GetIsFormatting(&isFormatting);
+ vol->GetIsFake(&isFake);
unused << SendFileSystemUpdate(volName, mountPoint, state,
mountGeneration, isMediaPresent,
- isSharing, isFormatting);
+ isSharing, isFormatting, isFake);
} else if (!strcmp(aTopic, "phone-state-changed")) {
nsString state(aData);
unused << SendNotifyPhoneStateChange(state);
diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl
index 6a7477a4eaa..a330d76372b 100644
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -388,7 +388,7 @@ child:
FileSystemUpdate(nsString fsName, nsString mountPoint, int32_t fsState,
int32_t mountGeneration, bool isMediaPresent,
- bool isSharing, bool isFormatting);
+ bool isSharing, bool isFormatting, bool isFake);
// Ask the Nuwa process to create a new child process.
NuwaFork();
diff --git a/dom/media/tests/mochitest/moz.build b/dom/media/tests/mochitest/moz.build
index 01a34a27a25..3f6807d4561 100644
--- a/dom/media/tests/mochitest/moz.build
+++ b/dom/media/tests/mochitest/moz.build
@@ -4,7 +4,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/.
-WEBRTC_SIGNALLING_TEST_MANIFESTS += ['steeplechase.ini']
-
-MOCHITEST_MANIFESTS += ['mochitest.ini']
+if CONFIG ['MOZ_WEBRTC']:
+ MOCHITEST_MANIFESTS += ['mochitest.ini']
+ WEBRTC_SIGNALLING_TEST_MANIFESTS += ['steeplechase.ini']
diff --git a/dom/system/gonk/nsVolume.h b/dom/system/gonk/nsVolume.h
index 3b078eae7cd..e583f8f697a 100644
--- a/dom/system/gonk/nsVolume.h
+++ b/dom/system/gonk/nsVolume.h
@@ -30,13 +30,13 @@ public:
nsVolume(const nsAString& aName, const nsAString& aMountPoint,
const int32_t& aState, const int32_t& aMountGeneration,
const bool& aIsMediaPresent, const bool& aIsSharing,
- const bool& aIsFormatting)
+ const bool& aIsFormatting, const bool& aIsFake)
: mName(aName),
mMountPoint(aMountPoint),
mState(aState),
mMountGeneration(aMountGeneration),
mMountLocked(false),
- mIsFake(false),
+ mIsFake(aIsFake),
mIsMediaPresent(aIsMediaPresent),
mIsSharing(aIsSharing),
mIsFormatting(aIsFormatting)
@@ -82,7 +82,7 @@ public:
typedef nsTArray > Array;
private:
- ~nsVolume() {}
+ virtual ~nsVolume() {} // MozExternalRefCountType complains if this is non-virtual
friend class nsVolumeService; // Calls the following XxxMountLock functions
void UpdateMountLock(const nsAString& aMountLockState);
diff --git a/dom/system/gonk/nsVolumeService.cpp b/dom/system/gonk/nsVolumeService.cpp
index 3ff86b84222..ef058cc388b 100644
--- a/dom/system/gonk/nsVolumeService.cpp
+++ b/dom/system/gonk/nsVolumeService.cpp
@@ -249,7 +249,8 @@ nsVolumeService::CreateOrGetVolumeByPath(const nsAString& aPath, nsIVolume** aRe
-1 /* generation */,
true /* isMediaPresent*/,
false /* isSharing */,
- false /* isFormatting */);
+ false /* isFormatting */,
+ true /* isFake */);
vol.forget(aResult);
return NS_OK;
}
@@ -382,8 +383,8 @@ nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path)
-1 /* mountGeneration */,
true /* isMediaPresent */,
false /* isSharing */,
- false /* isFormatting */);
- vol->SetIsFake(true);
+ false /* isFormatting */,
+ true /* isFake */);
vol->LogState();
UpdateVolume(vol.get());
return NS_OK;
diff --git a/dom/webidl/DeviceStorage.webidl b/dom/webidl/DeviceStorage.webidl
index 4df27c46788..b8713f08a4d 100644
--- a/dom/webidl/DeviceStorage.webidl
+++ b/dom/webidl/DeviceStorage.webidl
@@ -52,6 +52,18 @@ interface DeviceStorage : EventTarget {
// include any path information.
readonly attribute DOMString storageName;
+ // Indicates if the storage area denoted by storageName is capable of
+ // being mounted and unmounted.
+ readonly attribute boolean canBeMounted;
+
+ // Indicates if the storage area denoted by storageName is capable of
+ // being shared and unshared.
+ readonly attribute boolean canBeShared;
+
+ // Indicates if the storage area denoted by storageName is capable of
+ // being formatted.
+ readonly attribute boolean canBeFormatted;
+
// Determines if this storage area is the one which will be used by default
// for storing new files.
readonly attribute boolean default;
diff --git a/gfx/gl/SurfaceStream.cpp b/gfx/gl/SurfaceStream.cpp
index a814684ef50..de0f760b731 100644
--- a/gfx/gl/SurfaceStream.cpp
+++ b/gfx/gl/SurfaceStream.cpp
@@ -434,10 +434,13 @@ SurfaceStream_TripleBuffer::SwapProducer(SurfaceFactory* factory,
// If WaitForCompositor succeeds, mStaging has moved to mConsumer.
// If it failed, we might have to scrap it.
- if (mStaging && !WaitForCompositor())
+ if (mStaging) {
+ WaitForCompositor();
+ }
+ if (mStaging) {
Scrap(mStaging);
+ }
- MOZ_ASSERT(!mStaging);
Move(mProducer, mStaging);
mStaging->Fence();
}
@@ -470,19 +473,15 @@ SurfaceStream_TripleBuffer_Async::~SurfaceStream_TripleBuffer_Async()
{
}
-bool
+void
SurfaceStream_TripleBuffer_Async::WaitForCompositor()
{
PROFILER_LABEL("SurfaceStream_TripleBuffer_Async", "WaitForCompositor");
- // We are assumed to be locked
- while (mStaging) {
- if (!NS_SUCCEEDED(mMonitor.Wait(PR_MillisecondsToInterval(100)))) {
- return false;
- }
- }
-
- return true;
+ // If we haven't be notified within 100ms, then
+ // something must have happened and it will never arrive.
+ // Bail out to avoid deadlocking.
+ mMonitor.Wait(PR_MillisecondsToInterval(100));
}
} /* namespace gfx */
diff --git a/gfx/gl/SurfaceStream.h b/gfx/gl/SurfaceStream.h
index 2de34fbe266..0b95d7b5dd0 100644
--- a/gfx/gl/SurfaceStream.h
+++ b/gfx/gl/SurfaceStream.h
@@ -192,7 +192,7 @@ protected:
SharedSurface* mConsumer;
// Returns true if we were able to wait, false if not
- virtual bool WaitForCompositor() { return false; }
+ virtual void WaitForCompositor() {}
// To support subclasses initializing the mType.
SurfaceStream_TripleBuffer(SurfaceStreamType type, SurfaceStream* prevStream);
@@ -221,7 +221,7 @@ class SurfaceStream_TripleBuffer_Async
: public SurfaceStream_TripleBuffer
{
protected:
- virtual bool WaitForCompositor() MOZ_OVERRIDE;
+ virtual void WaitForCompositor() MOZ_OVERRIDE;
public:
SurfaceStream_TripleBuffer_Async(SurfaceStream* prevStream);
diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp
index 27ecc7ef27a..cc4dc1ef5c6 100644
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -453,7 +453,9 @@ Range::intersect(TempAllocator &alloc, const Range *lhs, const Range *rhs, bool
newHasInt32LowerBound && newHasInt32UpperBound &&
newLower == newUpper))
{
- refineInt32BoundsByExponent(newExponent, &newLower, &newUpper);
+ refineInt32BoundsByExponent(newExponent,
+ &newLower, &newHasInt32LowerBound,
+ &newUpper, &newHasInt32UpperBound);
// If we're intersecting two ranges that don't overlap, this could also
// push the bounds past each other, since the actual intersection is
@@ -2113,7 +2115,9 @@ Range::wrapAroundToInt32()
// Clearing the fractional field may provide an opportunity to refine
// lower_ or upper_.
- refineInt32BoundsByExponent(max_exponent_, &lower_, &upper_);
+ refineInt32BoundsByExponent(max_exponent_,
+ &lower_, &hasInt32LowerBound_,
+ &upper_, &hasInt32UpperBound_);
assertInvariants();
}
diff --git a/js/src/jit/RangeAnalysis.h b/js/src/jit/RangeAnalysis.h
index 584902859e6..658aff1eda6 100644
--- a/js/src/jit/RangeAnalysis.h
+++ b/js/src/jit/RangeAnalysis.h
@@ -277,12 +277,17 @@ class Range : public TempObject {
// Given an exponent value and pointers to the lower and upper bound values,
// this function refines the lower and upper bound values to the tighest
// bound for integer values implied by the exponent.
- static void refineInt32BoundsByExponent(uint16_t e, int32_t *l, int32_t *h) {
+ static void refineInt32BoundsByExponent(uint16_t e,
+ int32_t *l, bool *lb,
+ int32_t *h, bool *hb)
+ {
if (e < MaxInt32Exponent) {
// pow(2, max_exponent_+1)-1 to compute a maximum absolute value.
int32_t limit = (uint32_t(1) << (e + 1)) - 1;
*h = Min(*h, limit);
*l = Max(*l, -limit);
+ *hb = true;
+ *lb = true;
}
}
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp
index c90f75f4e0e..c91c26e9fa8 100644
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -771,7 +771,7 @@ Chunk::init(JSRuntime *rt)
info.trailer.location = ChunkLocationTenuredHeap;
info.trailer.runtime = rt;
- /* The rest of info fields are initialized in PickChunk. */
+ /* The rest of info fields are initialized in pickChunk. */
}
static inline Chunk **
@@ -1502,11 +1502,9 @@ ArenaLists::allocateFromArenaInline(Zone *zone, AllocKind thingKind)
* a lock.
*/
- Chunk *chunk = nullptr;
-
- ArenaList *al = &arenaLists[thingKind];
AutoLockGC maybeLock;
+ bool backgroundFinalizationIsRunning = false;
#ifdef JS_THREADSAFE
ArenaLists::BackgroundFinalizeState *bfs = &backgroundFinalizeState[thingKind];
if (*bfs != BFS_DONE) {
@@ -1518,15 +1516,7 @@ ArenaLists::allocateFromArenaInline(Zone *zone, AllocKind thingKind)
JSRuntime *rt = zone->runtimeFromAnyThread();
maybeLock.lock(rt);
if (*bfs == BFS_RUN) {
- JS_ASSERT(al->isCursorAtEnd());
- chunk = rt->gc.pickChunk(zone);
- if (!chunk) {
- /*
- * Let the caller to wait for the background allocation to
- * finish and restart the allocation attempt.
- */
- return nullptr;
- }
+ backgroundFinalizationIsRunning = true;
} else if (*bfs == BFS_JUST_FINISHED) {
/* See comments before BackgroundFinalizeState definition. */
*bfs = BFS_DONE;
@@ -1536,47 +1526,47 @@ ArenaLists::allocateFromArenaInline(Zone *zone, AllocKind thingKind)
}
#endif /* JS_THREADSAFE */
- if (!chunk) {
- if (ArenaHeader *aheader = al->arenaAfterCursor()) {
- /*
- * Normally, the empty arenas are returned to the chunk
- * and should not present on the list. In parallel
- * execution, however, we keep empty arenas in the arena
- * list to avoid synchronizing on the chunk.
- */
- JS_ASSERT(!aheader->isEmpty() || InParallelSection());
+ ArenaHeader *aheader;
+ ArenaList *al = &arenaLists[thingKind];
+ if (!backgroundFinalizationIsRunning && (aheader = al->arenaAfterCursor())) {
+ /*
+ * Normally, the empty arenas are returned to the chunk
+ * and should not be present on the list. In parallel
+ * execution, however, we keep empty arenas in the arena
+ * list to avoid synchronizing on the chunk.
+ */
+ JS_ASSERT(!aheader->isEmpty() || InParallelSection());
- al->moveCursorPast(aheader);
+ al->moveCursorPast(aheader);
- /*
- * Move the free span stored in the arena to the free list and
- * allocate from it.
- */
- FreeSpan firstFreeSpan = aheader->getFirstFreeSpan();
- freeLists[thingKind].setHead(&firstFreeSpan);
- aheader->setAsFullyUsed();
- if (MOZ_UNLIKELY(zone->wasGCStarted())) {
- if (zone->needsBarrier()) {
- aheader->allocatedDuringIncremental = true;
- zone->runtimeFromMainThread()->gc.marker.delayMarkingArena(aheader);
- } else if (zone->isGCSweeping()) {
- PushArenaAllocatedDuringSweep(zone->runtimeFromMainThread(), aheader);
- }
+ /*
+ * Move the free span stored in the arena to the free list and
+ * allocate from it.
+ */
+ FreeSpan firstFreeSpan = aheader->getFirstFreeSpan();
+ freeLists[thingKind].setHead(&firstFreeSpan);
+ aheader->setAsFullyUsed();
+ if (MOZ_UNLIKELY(zone->wasGCStarted())) {
+ if (zone->needsBarrier()) {
+ aheader->allocatedDuringIncremental = true;
+ zone->runtimeFromMainThread()->gc.marker.delayMarkingArena(aheader);
+ } else if (zone->isGCSweeping()) {
+ PushArenaAllocatedDuringSweep(zone->runtimeFromMainThread(), aheader);
}
- void *thing = freeLists[thingKind].allocate(Arena::thingSize(thingKind));
- JS_ASSERT(thing); // This allocation is infallible.
- return thing;
}
-
- /* Make sure we hold the GC lock before we call PickChunk. */
- JSRuntime *rt = zone->runtimeFromAnyThread();
- if (!maybeLock.locked())
- maybeLock.lock(rt);
- chunk = rt->gc.pickChunk(zone);
- if (!chunk)
- return nullptr;
+ void *thing = freeLists[thingKind].allocate(Arena::thingSize(thingKind));
+ JS_ASSERT(thing); // This allocation is infallible.
+ return thing;
}
+ /* Make sure we hold the GC lock before we call pickChunk. */
+ JSRuntime *rt = zone->runtimeFromAnyThread();
+ if (!maybeLock.locked())
+ maybeLock.lock(rt);
+ Chunk *chunk = rt->gc.pickChunk(zone);
+ if (!chunk)
+ return nullptr;
+
/*
* While we still hold the GC lock get an arena from some chunk, mark it
* as full as its single free span is moved to the free lits, and insert
@@ -1587,7 +1577,7 @@ ArenaLists::allocateFromArenaInline(Zone *zone, AllocKind thingKind)
* cache locality.
*/
JS_ASSERT(al->isCursorAtEnd());
- ArenaHeader *aheader = chunk->allocateArena(zone, thingKind);
+ aheader = chunk->allocateArena(zone, thingKind);
if (!aheader)
return nullptr;
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 3c43cb64700..a1ed129e149 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2308,13 +2308,16 @@ nsLayoutUtils::TransformFrameRectToAncestor(nsIFrame* aFrame,
static nsIntPoint GetWidgetOffset(nsIWidget* aWidget, nsIWidget*& aRootWidget) {
nsIntPoint offset(0, 0);
- nsIWidget* parent = aWidget->GetParent();
- while (parent) {
+ while ((aWidget->WindowType() == eWindowType_child ||
+ aWidget->WindowType() == eWindowType_plugin)) {
+ nsIWidget* parent = aWidget->GetParent();
+ if (!parent) {
+ break;
+ }
nsIntRect bounds;
aWidget->GetBounds(bounds);
offset += bounds.TopLeft();
aWidget = parent;
- parent = aWidget->GetParent();
}
aRootWidget = aWidget;
return offset;
diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp
index 9768874c165..37a9043a47d 100644
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -1185,7 +1185,7 @@ nsObjectFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
DisplayListClipState::AutoClipContainingBlockDescendantsToContentBox
- clip(aBuilder, this, DisplayListClipState::ASSUME_DRAWING_RESTRICTED_TO_CONTENT_RECT);
+ clip(aBuilder, this);
// determine if we are printing
if (type == nsPresContext::eContext_Print) {
diff --git a/layout/tools/reftest/reftest.js b/layout/tools/reftest/reftest.js
index beb7d2e1c0f..8acc57784f9 100644
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -660,6 +660,12 @@ function BuildConditionSandbox(aURL) {
sandbox.AddressSanitizer = false;
#endif
+#if MOZ_WEBRTC
+ sandbox.webrtc = true;
+#else
+ sandbox.webrtc = false;
+#endif
+
var hh = CC[NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX + "http"].
getService(CI.nsIHttpProtocolHandler);
sandbox.http = { __exposedProps__: {} };
diff --git a/media/libyuv/build/dir_exists.py b/media/libyuv/build/dir_exists.py
new file mode 100644
index 00000000000..be4c54d2e1f
--- /dev/null
+++ b/media/libyuv/build/dir_exists.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+import sys
+import subprocess
+import os.path
+
+def main():
+ return subprocess.call([sys.executable, "../webrtc/trunk/build/dir_exists.py"] + sys.argv[1:])
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/media/libyuv/build/mac/find_sdk.py b/media/libyuv/build/mac/find_sdk.py
new file mode 100755
index 00000000000..7fd9a980eb8
--- /dev/null
+++ b/media/libyuv/build/mac/find_sdk.py
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+import sys
+import subprocess
+
+def main():
+ return subprocess.call([sys.executable, "../webrtc/trunk/build/mac/find_sdk.py"] + sys.argv[1:])
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/media/webrtc/trunk/build/common.gypi b/media/webrtc/trunk/build/common.gypi
index 3ce90258547..51aedc4742e 100644
--- a/media/webrtc/trunk/build/common.gypi
+++ b/media/webrtc/trunk/build/common.gypi
@@ -924,7 +924,7 @@
'directx_sdk_default_path': '<(DEPTH)/third_party/directxsdk/files',
'conditions': [
- ['OS=="win" and "
+
+
+
+
+
+
+
+
+
+
+
+ Mozilla Bug 835044
+
+
+
+
+
diff --git a/xpcom/base/nsCycleCollector.cpp b/xpcom/base/nsCycleCollector.cpp
index 98f1041d958..91cd2d77b4b 100644
--- a/xpcom/base/nsCycleCollector.cpp
+++ b/xpcom/base/nsCycleCollector.cpp
@@ -613,7 +613,9 @@ public:
class NodePool
{
private:
- enum { BlockSize = 8 * 1024 }; // could be int template parameter
+ // The -2 allows us to use |BlockSize + 1| for |mEntries|, and fit |mNext|,
+ // all without causing slop.
+ enum { BlockSize = 8 * 1024 - 2 };
struct Block
{
@@ -623,6 +625,13 @@ private:
Block()
{
NS_NOTREACHED("should never be called");
+
+ // Ensure Block is the right size (see the comment on BlockSize above).
+ static_assert(
+ sizeof(Block) == 163824 || // 32-bit; equals 39.997 pages
+ sizeof(Block) == 262120, // 64-bit; equals 63.994 pages
+ "ill-sized NodePool::Block"
+ );
}
~Block()
{