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 " + + + + + + 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() {