diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index 6463543043c3..6a65b020ff9c 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index 9c8b243948d5..8689b52509eb 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 082a69b37cd9..e3e5ad363fd5 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 205f8844f305..d91bfa9b69d6 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator-l/sources.xml b/b2g/config/emulator-l/sources.xml index 059239643330..d6ed7845464c 100644 --- a/b2g/config/emulator-l/sources.xml +++ b/b2g/config/emulator-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index 9c8b243948d5..8689b52509eb 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index f6c2445cf48e..c6370b364ef7 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index bd6addaa0201..ee864d9288a2 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index a4cd19f85a0e..9784892bcce1 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,9 +1,9 @@ { "git": { - "git_revision": "e1773d6d1014c997be4b5c4233bba3ee073b8d7b", + "git_revision": "42dc5f02a9df006b129824cd9bffa93cab937ab2", "remote": "https://git.mozilla.org/releases/gaia.git", "branch": "" }, - "revision": "172680469094791e563268fa7d074fee9e0105ab", + "revision": "1ada14e78334ed61c226ba43be1f3ac286c66a95", "repo_path": "integration/gaia-central" } diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index 6bf6665b613b..e1059f090f4d 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/nexus-5-l/sources.xml b/b2g/config/nexus-5-l/sources.xml index f1d18c78b54b..811029dc989b 100644 --- a/b2g/config/nexus-5-l/sources.xml +++ b/b2g/config/nexus-5-l/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/browser/themes/shared/aboutNetError.css b/browser/themes/shared/aboutNetError.css index f507d3a858dc..460efd5d2eeb 100644 --- a/browser/themes/shared/aboutNetError.css +++ b/browser/themes/shared/aboutNetError.css @@ -136,13 +136,3 @@ span#hostname { #automaticallyReportInFuture { cursor: pointer; } - -#reportSendingMessage { - /* adjust the line-height to match the link */ - line-height: 22px; -} - -#reportSentMessage { - /* adjust the line-height to match the link */ - line-height: 22px; -} diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp index a28f528ee32f..bfecce47afd4 100644 --- a/dom/base/Navigator.cpp +++ b/dom/base/Navigator.cpp @@ -32,6 +32,7 @@ #include "mozilla/Preferences.h" #include "mozilla/Telemetry.h" #include "BatteryManager.h" +#include "mozilla/dom/DeviceStorageAreaListener.h" #include "mozilla/dom/PowerManager.h" #include "mozilla/dom/WakeLock.h" #include "mozilla/dom/power/PowerManagerService.h" @@ -210,6 +211,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Navigator) #ifdef MOZ_EME NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMediaKeySystemAccessManager) #endif + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDeviceStorageAreaListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -334,6 +336,10 @@ Navigator::Invalidate() mMediaKeySystemAccessManager = nullptr; } #endif + + if (mDeviceStorageAreaListener) { + mDeviceStorageAreaListener = nullptr; + } } //***************************************************************************** @@ -914,6 +920,20 @@ Navigator::RegisterProtocolHandler(const nsAString& aProtocol, mWindow->GetOuterWindow()); } +DeviceStorageAreaListener* +Navigator::GetDeviceStorageAreaListener(ErrorResult& aRv) +{ + if (!mDeviceStorageAreaListener) { + if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + mDeviceStorageAreaListener = new DeviceStorageAreaListener(mWindow); + } + + return mDeviceStorageAreaListener; +} + nsDOMDeviceStorage* Navigator::GetDeviceStorage(const nsAString& aType, ErrorResult& aRv) { @@ -949,6 +969,28 @@ Navigator::GetDeviceStorages(const nsAString& aType, mDeviceStorageStores.AppendElements(aStores); } +nsDOMDeviceStorage* +Navigator::GetDeviceStorageByNameAndType(const nsAString& aName, + const nsAString& aType, + ErrorResult& aRv) +{ + if (!mWindow || !mWindow->GetOuterWindow() || !mWindow->GetDocShell()) { + aRv.Throw(NS_ERROR_FAILURE); + return nullptr; + } + + nsRefPtr storage; + nsDOMDeviceStorage::CreateDeviceStorageByNameAndType(mWindow, aName, aType, + getter_AddRefs(storage)); + + if (!storage) { + return nullptr; + } + + mDeviceStorageStores.AppendElement(storage); + return storage; +} + Geolocation* Navigator::GetGeolocation(ErrorResult& aRv) { diff --git a/dom/base/Navigator.h b/dom/base/Navigator.h index c059708d5cd5..2cf82718db2e 100644 --- a/dom/base/Navigator.h +++ b/dom/base/Navigator.h @@ -94,6 +94,7 @@ class Telephony; class Voicemail; class TVManager; class InputPortManager; +class DeviceStorageAreaListener; namespace time { class TimeManager; @@ -214,11 +215,15 @@ public: void RemoveIdleObserver(MozIdleObserver& aObserver, ErrorResult& aRv); already_AddRefed RequestWakeLock(const nsAString &aTopic, ErrorResult& aRv); + DeviceStorageAreaListener* GetDeviceStorageAreaListener(ErrorResult& aRv); nsDOMDeviceStorage* GetDeviceStorage(const nsAString& aType, ErrorResult& aRv); void GetDeviceStorages(const nsAString& aType, nsTArray >& aStores, ErrorResult& aRv); + nsDOMDeviceStorage* GetDeviceStorageByNameAndType(const nsAString& aName, + const nsAString& aType, + ErrorResult& aRv); DesktopNotificationCenter* GetMozNotification(ErrorResult& aRv); CellBroadcast* GetMozCellBroadcast(ErrorResult& aRv); IccManager* GetMozIccManager(ErrorResult& aRv); @@ -379,6 +384,7 @@ private: nsRefPtr mTimeManager; nsRefPtr mServiceWorkerContainer; nsCOMPtr mWindow; + nsRefPtr mDeviceStorageAreaListener; // Hashtable for saving cached objects DoResolve created, so we don't create // the object twice if asked for it twice, whether due to use of "delete" or diff --git a/dom/cache/Cache.cpp b/dom/cache/Cache.cpp index 64c3d2c8b133..140b38fb317e 100644 --- a/dom/cache/Cache.cpp +++ b/dom/cache/Cache.cpp @@ -512,7 +512,7 @@ Cache::CreatePushStream(nsIAsyncInputStream* aStream) NS_ASSERT_OWNINGTHREAD(Cache); MOZ_ASSERT(mActor); MOZ_ASSERT(aStream); - return mActor->CreatePushStream(aStream); + return mActor->CreatePushStream(this, aStream); } Cache::~Cache() diff --git a/dom/cache/CacheChild.cpp b/dom/cache/CacheChild.cpp index 4c2fe7abcf71..bb39d44e281d 100644 --- a/dom/cache/CacheChild.cpp +++ b/dom/cache/CacheChild.cpp @@ -73,11 +73,11 @@ CacheChild::ExecuteOp(nsIGlobalObject* aGlobal, Promise* aPromise, } CachePushStreamChild* -CacheChild::CreatePushStream(nsIAsyncInputStream* aStream) +CacheChild::CreatePushStream(nsISupports* aParent, nsIAsyncInputStream* aStream) { mNumChildActors += 1; auto actor = SendPCachePushStreamConstructor( - new CachePushStreamChild(GetFeature(), aStream)); + new CachePushStreamChild(GetFeature(), aParent, aStream)); MOZ_ASSERT(actor); return static_cast(actor); } diff --git a/dom/cache/CacheChild.h b/dom/cache/CacheChild.h index 647df82cc69f..4d43535cc52a 100644 --- a/dom/cache/CacheChild.h +++ b/dom/cache/CacheChild.h @@ -43,7 +43,7 @@ public: nsISupports* aParent, const CacheOpArgs& aArgs); CachePushStreamChild* - CreatePushStream(nsIAsyncInputStream* aStream); + CreatePushStream(nsISupports* aParent, nsIAsyncInputStream* aStream); // Our parent Listener object has gone out of scope and is being destroyed. void StartDestroyFromListener(); diff --git a/dom/cache/CachePushStreamChild.cpp b/dom/cache/CachePushStreamChild.cpp index 57eca994ef73..0c5d90974762 100644 --- a/dom/cache/CachePushStreamChild.cpp +++ b/dom/cache/CachePushStreamChild.cpp @@ -93,10 +93,13 @@ NS_IMPL_ISUPPORTS(CachePushStreamChild::Callback, nsIInputStreamCallback, nsICancelableRunnable); CachePushStreamChild::CachePushStreamChild(Feature* aFeature, + nsISupports* aParent, nsIAsyncInputStream* aStream) - : mStream(aStream) + : mParent(aParent) + , mStream(aStream) , mClosed(false) { + MOZ_ASSERT(mParent); MOZ_ASSERT(mStream); MOZ_ASSERT_IF(!NS_IsMainThread(), aFeature); SetFeature(aFeature); diff --git a/dom/cache/CachePushStreamChild.h b/dom/cache/CachePushStreamChild.h index 03b1d3ed4f1d..9517aabba03f 100644 --- a/dom/cache/CachePushStreamChild.h +++ b/dom/cache/CachePushStreamChild.h @@ -31,7 +31,8 @@ private: class Callback; // This class must be constructed using CacheChild::CreatePushStream() - CachePushStreamChild(Feature* aFeature, nsIAsyncInputStream* aStream); + CachePushStreamChild(Feature* aFeature, nsISupports* aParent, + nsIAsyncInputStream* aStream); ~CachePushStreamChild(); // PCachePushStreamChild methods @@ -46,6 +47,7 @@ private: void OnEnd(nsresult aRv); + nsCOMPtr mParent; nsCOMPtr mStream; nsRefPtr mCallback; bool mClosed; diff --git a/dom/devicestorage/DeviceStorage.h b/dom/devicestorage/DeviceStorage.h index 3a982feba228..43d308e42b27 100644 --- a/dom/devicestorage/DeviceStorage.h +++ b/dom/devicestorage/DeviceStorage.h @@ -292,6 +292,12 @@ public: const nsAString& aType, nsTArray >& aStores); + static void + CreateDeviceStorageByNameAndType(nsPIDOMWindow* aWin, + const nsAString& aName, + const nsAString& aType, + nsDOMDeviceStorage** aStore); + void Shutdown(); static void GetOrderedVolumeNames(nsTArray& aVolumeNames); @@ -334,6 +340,11 @@ private: already_AddRefed GetStorageByName(const nsAString &aStorageName); + static already_AddRefed + GetStorageByNameAndType(nsPIDOMWindow* aWin, + const nsAString& aStorageName, + const nsAString& aType); + nsCOMPtr mPrincipal; bool mIsWatchingFile; diff --git a/dom/devicestorage/DeviceStorageAreaListener.cpp b/dom/devicestorage/DeviceStorageAreaListener.cpp new file mode 100755 index 000000000000..22eeaae0e62d --- /dev/null +++ b/dom/devicestorage/DeviceStorageAreaListener.cpp @@ -0,0 +1,149 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 "mozilla/dom/DeviceStorageAreaListener.h" +#include "mozilla/dom/DeviceStorageAreaListenerBinding.h" +#include "mozilla/Attributes.h" +#include "mozilla/Services.h" +#include "nsIObserverService.h" +#ifdef MOZ_WIDGET_GONK +#include "nsIVolume.h" +#include "nsIVolumeService.h" +#endif + +namespace mozilla { +namespace dom { + +class VolumeStateObserver final : public nsIObserver +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + explicit VolumeStateObserver(DeviceStorageAreaListener* aListener) + : mDeviceStorageAreaListener(aListener) {} + void ForgetListener() { mDeviceStorageAreaListener = nullptr; } + +private: + ~VolumeStateObserver() {}; + + // This reference is non-owning and it's cleared by + // DeviceStorageAreaListener's destructor. + DeviceStorageAreaListener* MOZ_NON_OWNING_REF mDeviceStorageAreaListener; +}; + +NS_IMPL_ISUPPORTS(VolumeStateObserver, nsIObserver) + +NS_IMETHODIMP +VolumeStateObserver::Observe(nsISupports *aSubject, + const char *aTopic, + const char16_t *aData) +{ + if (!mDeviceStorageAreaListener) { + return NS_OK; + } + +#ifdef MOZ_WIDGET_GONK + if (!strcmp(aTopic, NS_VOLUME_STATE_CHANGED)) { + nsCOMPtr vol = do_QueryInterface(aSubject); + MOZ_ASSERT(vol); + + int32_t state; + nsresult rv = vol->GetState(&state); + NS_ENSURE_SUCCESS(rv, rv); + + nsString volName; + vol->GetName(volName); + + switch (state) { + case nsIVolume::STATE_MOUNTED: + mDeviceStorageAreaListener->DispatchStorageAreaChangedEvent( + volName, + DeviceStorageAreaChangedEventOperation::Added); + break; + default: + mDeviceStorageAreaListener->DispatchStorageAreaChangedEvent( + volName, + DeviceStorageAreaChangedEventOperation::Removed); + break; + } + } +#endif + return NS_OK; +} + +NS_IMPL_ADDREF_INHERITED(DeviceStorageAreaListener, DOMEventTargetHelper) +NS_IMPL_RELEASE_INHERITED(DeviceStorageAreaListener, DOMEventTargetHelper) + +NS_INTERFACE_MAP_BEGIN(DeviceStorageAreaListener) +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) + +DeviceStorageAreaListener::DeviceStorageAreaListener(nsPIDOMWindow* aWindow) + : DOMEventTargetHelper(aWindow) +{ + MOZ_ASSERT(aWindow); + + mVolumeStateObserver = new VolumeStateObserver(this); +#ifdef MOZ_WIDGET_GONK + nsCOMPtr obs = mozilla::services::GetObserverService(); + if (obs) { + obs->AddObserver(mVolumeStateObserver, NS_VOLUME_STATE_CHANGED, false); + } +#endif +} + +DeviceStorageAreaListener::~DeviceStorageAreaListener() +{ +#ifdef MOZ_WIDGET_GONK + nsCOMPtr obs = mozilla::services::GetObserverService(); + if (obs) { + obs->RemoveObserver(mVolumeStateObserver, NS_VOLUME_STATE_CHANGED); + } +#endif + mVolumeStateObserver->ForgetListener(); +} + +JSObject* +DeviceStorageAreaListener::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return DeviceStorageAreaListenerBinding::Wrap(aCx, this, aGivenProto); +} + +void +DeviceStorageAreaListener::DispatchStorageAreaChangedEvent( + const nsString& aStorageName, + DeviceStorageAreaChangedEventOperation aOperation) +{ + StateMapType::const_iterator iter = mStorageAreaStateMap.find(aStorageName); + if (iter == mStorageAreaStateMap.end() && + aOperation != DeviceStorageAreaChangedEventOperation::Added) { + // The operation of the first event to dispatch should be "Added". + return; + } + if (iter != mStorageAreaStateMap.end() && + iter->second == aOperation) { + // No need to disptach the event if the state is unchanged. + return; + } + + DeviceStorageAreaChangedEventInit init; + init.mOperation = aOperation; + init.mStorageName = aStorageName; + + nsRefPtr event = + DeviceStorageAreaChangedEvent::Constructor(this, + NS_LITERAL_STRING("storageareachanged"), + init); + event->SetTrusted(true); + + bool ignore; + DOMEventTargetHelper::DispatchEvent(event, &ignore); + + mStorageAreaStateMap[aStorageName] = aOperation; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/devicestorage/DeviceStorageAreaListener.h b/dom/devicestorage/DeviceStorageAreaListener.h new file mode 100755 index 000000000000..59c2854d7958 --- /dev/null +++ b/dom/devicestorage/DeviceStorageAreaListener.h @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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/. */ + +#ifndef mozilla_dom_DeviceStorageAreaListener_h +#define mozilla_dom_DeviceStorageAreaListener_h + +#include +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/dom/DeviceStorageAreaChangedEvent.h" + +namespace mozilla { +namespace dom { + +class VolumeStateObserver; + +class DeviceStorageAreaListener final : public DOMEventTargetHelper +{ +public: + NS_DECL_ISUPPORTS_INHERITED + IMPL_EVENT_HANDLER(storageareachanged) + + explicit DeviceStorageAreaListener(nsPIDOMWindow* aWindow); + + virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; + +private: + friend class VolumeStateObserver; + + typedef std::map StateMapType; + StateMapType mStorageAreaStateMap; + + nsRefPtr mVolumeStateObserver; + + ~DeviceStorageAreaListener(); + + void DispatchStorageAreaChangedEvent( + const nsString& aStorageName, + DeviceStorageAreaChangedEventOperation aOperation); +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_DeviceStorageAreaListener_h diff --git a/dom/devicestorage/ipc/ipc.json b/dom/devicestorage/ipc/ipc.json index b5d793b52b69..747179bccb3d 100644 --- a/dom/devicestorage/ipc/ipc.json +++ b/dom/devicestorage/ipc/ipc.json @@ -2,6 +2,7 @@ "runtests":{ }, "excludetests":{ - "dom/devicestorage/test/test_dirs.html":"excluded" + "dom/devicestorage/test/test_dirs.html":"excluded", + "dom/devicestorage/test/test_storageAreaListener.html":"excluded" } } diff --git a/dom/devicestorage/moz.build b/dom/devicestorage/moz.build index 919707ed213e..e14c29cde712 100644 --- a/dom/devicestorage/moz.build +++ b/dom/devicestorage/moz.build @@ -10,12 +10,17 @@ EXPORTS += [ 'nsDeviceStorage.h', ] +EXPORTS.mozilla.dom += [ + 'DeviceStorageAreaListener.h', +] + EXPORTS.mozilla.dom.devicestorage += [ 'DeviceStorageRequestChild.h', 'DeviceStorageRequestParent.h', ] UNIFIED_SOURCES += [ + 'DeviceStorageAreaListener.cpp', 'DeviceStorageRequestChild.cpp', 'DeviceStorageRequestParent.cpp', 'nsDeviceStorage.cpp', diff --git a/dom/devicestorage/nsDeviceStorage.cpp b/dom/devicestorage/nsDeviceStorage.cpp index b51f2c86b2ab..9093107e7012 100644 --- a/dom/devicestorage/nsDeviceStorage.cpp +++ b/dom/devicestorage/nsDeviceStorage.cpp @@ -3579,6 +3579,30 @@ nsDOMDeviceStorage::CreateDeviceStoragesFor( } } +// static +void +nsDOMDeviceStorage::CreateDeviceStorageByNameAndType( + nsPIDOMWindow* aWin, + const nsAString& aName, + const nsAString& aType, + nsDOMDeviceStorage** aStore) +{ + if (!DeviceStorageTypeChecker::IsVolumeBased(aType)) { + nsRefPtr storage = new nsDOMDeviceStorage(aWin); + if (NS_FAILED(storage->Init(aWin, aType, EmptyString()))) { + *aStore = nullptr; + return; + } + NS_ADDREF(*aStore = storage.get()); + return; + } + + nsRefPtr storage = GetStorageByNameAndType(aWin, + aName, + aType); + NS_ADDREF(*aStore = storage.get()); +} + // static bool nsDOMDeviceStorage::ParseFullPath(const nsAString& aFullPath, @@ -3638,14 +3662,28 @@ nsDOMDeviceStorage::GetStorageByName(const nsAString& aStorageName) ds = this; return ds.forget(); } + + return GetStorageByNameAndType(GetOwner(), aStorageName, mStorageType); +} + +// static +already_AddRefed +nsDOMDeviceStorage::GetStorageByNameAndType(nsPIDOMWindow* aWin, + const nsAString& aStorageName, + const nsAString& aType) +{ + MOZ_ASSERT(NS_IsMainThread()); + + nsRefPtr ds; + VolumeNameArray volNames; GetOrderedVolumeNames(volNames); VolumeNameArray::size_type numVolumes = volNames.Length(); VolumeNameArray::index_type i; for (i = 0; i < numVolumes; i++) { if (volNames[i].Equals(aStorageName)) { - ds = new nsDOMDeviceStorage(GetOwner()); - nsresult rv = ds->Init(GetOwner(), mStorageType, aStorageName); + ds = new nsDOMDeviceStorage(aWin); + nsresult rv = ds->Init(aWin, aType, aStorageName); if (NS_FAILED(rv)) { return nullptr; } diff --git a/dom/devicestorage/test/mochitest.ini b/dom/devicestorage/test/mochitest.ini index 6a946d0299dd..6801df9584cb 100644 --- a/dom/devicestorage/test/mochitest.ini +++ b/dom/devicestorage/test/mochitest.ini @@ -24,6 +24,8 @@ support-files = devicestorage_common.js [test_usedSpace.html] [test_watch.html] [test_watchOther.html] +[test_storageAreaListener.html] +skip-if = toolkit != 'gonk' # FileSystem API tests [test_fs_basic.html] diff --git a/dom/devicestorage/test/test_storageAreaListener.html b/dom/devicestorage/test/test_storageAreaListener.html new file mode 100644 index 000000000000..d7bdf7950cea --- /dev/null +++ b/dom/devicestorage/test/test_storageAreaListener.html @@ -0,0 +1,61 @@ + + + + + +Test for device storage area listener API + + + + + + +Mozilla Bug 1126684 +

+ +
+
+
+ + diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 046e243eb2de..b97e02b43e7f 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -2361,6 +2361,21 @@ ContentChild::RecvFileSystemUpdate(const nsString& aFsName, return true; } +bool +ContentChild::RecvVolumeRemoved(const nsString& aFsName) +{ +#ifdef MOZ_WIDGET_GONK + nsRefPtr vs = nsVolumeService::GetSingleton(); + if (vs) { + vs->RemoveVolumeByName(aFsName); + } +#else + // Remove warnings about unused arguments + unused << aFsName; +#endif + return true; +} + bool ContentChild::RecvNotifyProcessPriorityChanged( const hal::ProcessPriority& aPriority) diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index a5b0dae1fffa..d8a657d21049 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -360,6 +360,7 @@ public: const bool& aIsUnmounting, const bool& aIsRemovable, const bool& aIsHotSwappable) override; + virtual bool RecvVolumeRemoved(const nsString& aFsName) override; virtual bool RecvNuwaFork() override; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index 2990d34a0771..749314c4296a 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -654,6 +654,7 @@ static const char* sObserverTopics[] = { "file-watcher-update", #ifdef MOZ_WIDGET_GONK NS_VOLUME_STATE_CHANGED, + NS_VOLUME_REMOVED, "phone-state-changed", #endif #ifdef ACCESSIBILITY @@ -3166,6 +3167,15 @@ ContentParent::Observe(nsISupports* aSubject, nsString state(aData); unused << SendNotifyPhoneStateChange(state); } + else if(!strcmp(aTopic, NS_VOLUME_REMOVED)) { +#ifdef MOZ_NUWA_PROCESS + if (!(IsNuwaReady() && IsNuwaProcess())) +#endif + { + nsString volName(aData); + unused << SendVolumeRemoved(volName); + } + } #endif #ifdef ACCESSIBILITY // Make sure accessibility is running in content process when accessibility @@ -4561,6 +4571,22 @@ ContentParent::RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsS #endif } +bool +ContentParent::RecvRemoveFakeVolume(const nsString& fsName) +{ +#ifdef MOZ_WIDGET_GONK + nsresult rv; + nsCOMPtr vs = do_GetService(NS_VOLUMESERVICE_CONTRACTID, &rv); + if (vs) { + vs->RemoveFakeVolume(fsName); + } + return true; +#else + NS_WARNING("ContentParent::RecvRemoveFakeVolume shouldn't be called when MOZ_WIDGET_GONK is not defined"); + return false; +#endif +} + bool ContentParent::RecvKeywordToURI(const nsCString& aKeyword, nsString* aProviderName, diff --git a/dom/ipc/ContentParent.h b/dom/ipc/ContentParent.h index 5503fd5ed3ed..79de320af058 100644 --- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -787,6 +787,8 @@ private: virtual bool RecvSetFakeVolumeState(const nsString& fsName, const int32_t& fsState) override; + virtual bool RecvRemoveFakeVolume(const nsString& fsName) override; + virtual bool RecvKeywordToURI(const nsCString& aKeyword, nsString* aProviderName, OptionalInputStreamParams* aPostData, diff --git a/dom/ipc/PContent.ipdl b/dom/ipc/PContent.ipdl index 3a204fcaf7dd..4124e784e8b8 100644 --- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -574,6 +574,9 @@ child: bool isSharing, bool isFormatting, bool isFake, bool isUnmounting, bool isRemovable, bool isHotSwappable); + // Notify volume is removed. + VolumeRemoved(nsString fsName); + // Ask the Nuwa process to create a new child process. NuwaFork(); @@ -898,6 +901,7 @@ parent: // called by the child (test code only) to propagate volume changes to the parent async CreateFakeVolume(nsString fsName, nsString mountPoint); async SetFakeVolumeState(nsString fsName, int32_t fsState); + async RemoveFakeVolume(nsString fsName); sync KeywordToURI(nsCString keyword) returns (nsString providerName, OptionalInputStreamParams postData, OptionalURIParams uri); diff --git a/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp b/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp index b1853ac5d749..666e1b7a9d2d 100644 --- a/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp +++ b/dom/media/fmp4/gonk/GonkAudioDecoderManager.cpp @@ -38,15 +38,13 @@ typedef android::MediaCodecProxy MediaCodecProxy; namespace mozilla { -GonkAudioDecoderManager::GonkAudioDecoderManager( - MediaTaskQueue* aTaskQueue, - const AudioInfo& aConfig) - : GonkDecoderManager(aTaskQueue) - , mAudioChannels(aConfig.mChannels) +GonkAudioDecoderManager::GonkAudioDecoderManager(const AudioInfo& aConfig) + : mAudioChannels(aConfig.mChannels) , mAudioRate(aConfig.mRate) , mAudioProfile(aConfig.mProfile) , mUseAdts(true) , mAudioBuffer(nullptr) + , mMonitor("GonkAudioDecoderManager") { MOZ_COUNT_CTOR(GonkAudioDecoderManager); MOZ_ASSERT(mAudioChannels); @@ -111,13 +109,53 @@ GonkAudioDecoderManager::Init(MediaDataDecoderCallback* aCallback) } } -status_t -GonkAudioDecoderManager::SendSampleToOMX(MediaRawData* aSample) +bool +GonkAudioDecoderManager::HasQueuedSample() { - return mDecoder->Input(reinterpret_cast(aSample->mData), - aSample->mSize, - aSample->mTime, - 0); + MonitorAutoLock mon(mMonitor); + return mQueueSample.Length(); +} + +nsresult +GonkAudioDecoderManager::Input(MediaRawData* aSample) +{ + MonitorAutoLock mon(mMonitor); + nsRefPtr sample; + + if (aSample) { + sample = aSample; + if (!PerformFormatSpecificProcess(sample)) { + return NS_ERROR_FAILURE; + } + } else { + // It means EOS with empty sample. + sample = new MediaRawData(); + } + + mQueueSample.AppendElement(sample); + + status_t rv; + while (mQueueSample.Length()) { + nsRefPtr data = mQueueSample.ElementAt(0); + { + MonitorAutoUnlock mon_exit(mMonitor); + rv = mDecoder->Input(reinterpret_cast(data->mData), + data->mSize, + data->mTime, + 0); + } + if (rv == OK) { + mQueueSample.RemoveElementAt(0); + } else if (rv == -EAGAIN || rv == -ETIMEDOUT) { + // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill + // buffer on time. + return NS_OK; + } else { + return NS_ERROR_UNEXPECTED; + } + } + + return NS_OK; } bool @@ -182,6 +220,21 @@ GonkAudioDecoderManager::CreateAudioData(int64_t aStreamOffset, AudioData **v) { return NS_OK; } +nsresult +GonkAudioDecoderManager::Flush() +{ + { + MonitorAutoLock mon(mMonitor); + mQueueSample.Clear(); + } + + if (mDecoder->flush() != OK) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + nsresult GonkAudioDecoderManager::Output(int64_t aStreamOffset, nsRefPtr& aOutData) @@ -258,15 +311,4 @@ void GonkAudioDecoderManager::ReleaseAudioBuffer() { mAudioBuffer = nullptr; } } - -nsresult -GonkAudioDecoderManager::Flush() -{ - GonkDecoderManager::Flush(); - status_t err = mDecoder->flush(); - if (err != OK) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} } // namespace mozilla diff --git a/dom/media/fmp4/gonk/GonkAudioDecoderManager.h b/dom/media/fmp4/gonk/GonkAudioDecoderManager.h index e6a69a046b47..47e5d3cd8ac9 100644 --- a/dom/media/fmp4/gonk/GonkAudioDecoderManager.h +++ b/dom/media/fmp4/gonk/GonkAudioDecoderManager.h @@ -23,30 +23,28 @@ namespace mozilla { class GonkAudioDecoderManager : public GonkDecoderManager { typedef android::MediaCodecProxy MediaCodecProxy; public: - GonkAudioDecoderManager(MediaTaskQueue* aTaskQueue, - const AudioInfo& aConfig); - ~GonkAudioDecoderManager(); + GonkAudioDecoderManager(const AudioInfo& aConfig); + + virtual ~GonkAudioDecoderManager() override; virtual android::sp Init(MediaDataDecoderCallback* aCallback) override; + virtual nsresult Input(MediaRawData* aSample) override; + virtual nsresult Output(int64_t aStreamOffset, nsRefPtr& aOutput) override; virtual nsresult Flush() override; -protected: - virtual bool PerformFormatSpecificProcess(MediaRawData* aSample) override; - - virtual status_t SendSampleToOMX(MediaRawData* aSample) override; + virtual bool HasQueuedSample() override; private: + bool PerformFormatSpecificProcess(MediaRawData* aSample); nsresult CreateAudioData(int64_t aStreamOffset, AudioData** aOutData); void ReleaseAudioBuffer(); - // MediaCodedc's wrapper that performs the decoding. - android::sp mDecoder; const uint32_t mAudioChannels; const uint32_t mAudioRate; @@ -56,6 +54,17 @@ private: MediaDataDecoderCallback* mReaderCallback; android::MediaBuffer* mAudioBuffer; android::sp mLooper; + + // MediaCodedc's wrapper that performs the decoding. + android::sp mDecoder; + + // This monitor protects mQueueSample. + Monitor mMonitor; + + // An queue with the MP4 samples which are waiting to be sent into OMX. + // If an element is an empty MP4Sample, that menas EOS. There should not + // any sample be queued after EOS. + nsTArray> mQueueSample; }; } // namespace mozilla diff --git a/dom/media/fmp4/gonk/GonkDecoderModule.cpp b/dom/media/fmp4/gonk/GonkDecoderModule.cpp index 6abee4c28f9b..b95010778e4d 100644 --- a/dom/media/fmp4/gonk/GonkDecoderModule.cpp +++ b/dom/media/fmp4/gonk/GonkDecoderModule.cpp @@ -34,8 +34,7 @@ GonkDecoderModule::CreateVideoDecoder(const VideoInfo& aConfig, MediaDataDecoderCallback* aCallback) { nsRefPtr decoder = - new GonkMediaDataDecoder(new GonkVideoDecoderManager(aVideoTaskQueue, - aImageContainer, aConfig), + new GonkMediaDataDecoder(new GonkVideoDecoderManager(aImageContainer, aConfig), aVideoTaskQueue, aCallback); return decoder.forget(); } @@ -46,7 +45,7 @@ GonkDecoderModule::CreateAudioDecoder(const AudioInfo& aConfig, MediaDataDecoderCallback* aCallback) { nsRefPtr decoder = - new GonkMediaDataDecoder(new GonkAudioDecoderManager(aAudioTaskQueue, aConfig), + new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig), aAudioTaskQueue, aCallback); return decoder.forget(); } diff --git a/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp b/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp index 7e33c67c67ad..359c8a8956fa 100644 --- a/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp +++ b/dom/media/fmp4/gonk/GonkMediaDataDecoder.cpp @@ -25,58 +25,6 @@ using namespace android; namespace mozilla { -GonkDecoderManager::GonkDecoderManager(MediaTaskQueue* aTaskQueue) - : mMonitor("GonkDecoderManager") -{ -} - -nsresult -GonkDecoderManager::Input(MediaRawData* aSample) -{ - ReentrantMonitorAutoEnter mon(mMonitor); - nsRefPtr sample; - - if (!aSample) { - // It means EOS with empty sample. - sample = new MediaRawData(); - } else { - sample = aSample; - if (!PerformFormatSpecificProcess(sample)) { - return NS_ERROR_FAILURE; - } - } - - mQueueSample.AppendElement(sample); - - status_t rv; - while (mQueueSample.Length()) { - nsRefPtr data = mQueueSample.ElementAt(0); - { - ReentrantMonitorAutoExit mon_exit(mMonitor); - rv = SendSampleToOMX(data); - } - if (rv == OK) { - mQueueSample.RemoveElementAt(0); - } else if (rv == -EAGAIN || rv == -ETIMEDOUT) { - // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill - // buffer on time. - return NS_OK; - } else { - return NS_ERROR_UNEXPECTED; - } - } - - return NS_OK; -} - -nsresult -GonkDecoderManager::Flush() -{ - ReentrantMonitorAutoEnter mon(mMonitor); - mQueueSample.Clear(); - return NS_OK; -} - GonkMediaDataDecoder::GonkMediaDataDecoder(GonkDecoderManager* aManager, FlushableMediaTaskQueue* aTaskQueue, MediaDataDecoderCallback* aCallback) diff --git a/dom/media/fmp4/gonk/GonkMediaDataDecoder.h b/dom/media/fmp4/gonk/GonkMediaDataDecoder.h index a169df5f5e95..fe0772189482 100644 --- a/dom/media/fmp4/gonk/GonkMediaDataDecoder.h +++ b/dom/media/fmp4/gonk/GonkMediaDataDecoder.h @@ -19,8 +19,6 @@ class MediaRawData; // Manage the data flow from inputting encoded data and outputting decode data. class GonkDecoderManager { public: - GonkDecoderManager(MediaTaskQueue* aTaskQueue); - virtual ~GonkDecoderManager() {} // Creates and initializs the GonkDecoder. @@ -28,7 +26,7 @@ public: virtual android::sp Init(MediaDataDecoderCallback* aCallback) = 0; // Add samples into OMX decoder or queue them if decoder is out of input buffer. - virtual nsresult Input(MediaRawData* aSample); + virtual nsresult Input(MediaRawData* aSample) = 0; // Produces decoded output, it blocks until output can be produced or a timeout // is expired or until EOS. Returns NS_OK on success, or NS_ERROR_NOT_AVAILABLE @@ -40,32 +38,12 @@ public: nsRefPtr& aOutput) = 0; // Flush the queued sample. - // It this function is overrided by subclass, this functino should be called - // in the overrided function. - virtual nsresult Flush(); + virtual nsresult Flush() = 0; - // It should be called in MediaTask thread. - bool HasQueuedSample() { - ReentrantMonitorAutoEnter mon(mMonitor); - return mQueueSample.Length(); - } + // True if sample is queued. + virtual bool HasQueuedSample() = 0; protected: - // It performs special operation to MP4 sample, the real action is depended on - // the codec type. - virtual bool PerformFormatSpecificProcess(MediaRawData* aSample) { return true; } - - // It sends MP4Sample to OMX layer. It must be overrided by subclass. - virtual android::status_t SendSampleToOMX(MediaRawData* aSample) = 0; - - // This monitor protects mQueueSample. - ReentrantMonitor mMonitor; - - // An queue with the MP4 samples which are waiting to be sent into OMX. - // If an element is an empty MP4Sample, that menas EOS. There should not - // any sample be queued after EOS. - nsTArray> mQueueSample; - nsRefPtr mCodecSpecificData; nsAutoCString mMimeType; diff --git a/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp b/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp index c60c5ee5aa7c..b092764f9f3c 100644 --- a/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp +++ b/dom/media/fmp4/gonk/GonkVideoDecoderManager.cpp @@ -44,16 +44,15 @@ typedef android::MediaCodecProxy MediaCodecProxy; namespace mozilla { GonkVideoDecoderManager::GonkVideoDecoderManager( - MediaTaskQueue* aTaskQueue, mozilla::layers::ImageContainer* aImageContainer, const VideoInfo& aConfig) - : GonkDecoderManager(aTaskQueue) - , mImageContainer(aImageContainer) + : mImageContainer(aImageContainer) , mReaderCallback(nullptr) , mLastDecodedTime(0) , mColorConverterBufferSize(0) , mNativeWindow(nullptr) , mPendingVideoBuffersLock("GonkVideoDecoderManager::mPendingVideoBuffersLock") + , mMonitor("GonkVideoDecoderManager") { MOZ_COUNT_CTOR(GonkVideoDecoderManager); mMimeType = aConfig.mMimeType; @@ -117,6 +116,52 @@ GonkVideoDecoderManager::Init(MediaDataDecoderCallback* aCallback) return mDecoder; } +nsresult +GonkVideoDecoderManager::Input(MediaRawData* aSample) +{ + MonitorAutoLock mon(mMonitor); + nsRefPtr sample; + + if (!aSample) { + // It means EOS with empty sample. + sample = new MediaRawData(); + } else { + sample = aSample; + } + + mQueueSample.AppendElement(sample); + + status_t rv; + while (mQueueSample.Length()) { + nsRefPtr data = mQueueSample.ElementAt(0); + { + MonitorAutoUnlock mon_unlock(mMonitor); + rv = mDecoder->Input(reinterpret_cast(data->mData), + data->mSize, + data->mTime, + 0); + } + if (rv == OK) { + mQueueSample.RemoveElementAt(0); + } else if (rv == -EAGAIN || rv == -ETIMEDOUT) { + // In most cases, EAGAIN or ETIMEOUT are safe because OMX can't fill + // buffer on time. + return NS_OK; + } else { + return NS_ERROR_UNEXPECTED; + } + } + + return NS_OK; +} + +bool +GonkVideoDecoderManager::HasQueuedSample() +{ + MonitorAutoLock mon(mMonitor); + return mQueueSample.Length(); +} + nsresult GonkVideoDecoderManager::CreateVideoData(int64_t aStreamOffset, VideoData **v) { @@ -305,6 +350,23 @@ GonkVideoDecoderManager::SetVideoFormat() return false; } +nsresult +GonkVideoDecoderManager::Flush() +{ + { + MonitorAutoLock mon(mMonitor); + mQueueSample.Clear(); + } + + mLastDecodedTime = 0; + + if (mDecoder->flush() != OK) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + // Blocks until decoded sample is produced by the deoder. nsresult GonkVideoDecoderManager::Output(int64_t aStreamOffset, @@ -393,27 +455,6 @@ void GonkVideoDecoderManager::ReleaseVideoBuffer() { } } -status_t -GonkVideoDecoderManager::SendSampleToOMX(MediaRawData* aSample) -{ - return mDecoder->Input(reinterpret_cast(aSample->mData), - aSample->mSize, - aSample->mTime, - 0); -} - -nsresult -GonkVideoDecoderManager::Flush() -{ - GonkDecoderManager::Flush(); - mLastDecodedTime = 0; - status_t err = mDecoder->flush(); - if (err != OK) { - return NS_ERROR_FAILURE; - } - return NS_OK; -} - void GonkVideoDecoderManager::codecReserved() { @@ -574,12 +615,4 @@ void GonkVideoDecoderManager::ReleaseAllPendingVideoBuffers() releasingVideoBuffers.clear(); } -void GonkVideoDecoderManager::ReleaseMediaResources() { - GVDM_LOG("ReleseMediaResources"); - if (mDecoder == nullptr) { - return; - } - ReleaseAllPendingVideoBuffers(); - mDecoder->ReleaseMediaResources(); -} } // namespace mozilla diff --git a/dom/media/fmp4/gonk/GonkVideoDecoderManager.h b/dom/media/fmp4/gonk/GonkVideoDecoderManager.h index 1c2a2ebd5ad3..45f802cf30bd 100644 --- a/dom/media/fmp4/gonk/GonkVideoDecoderManager.h +++ b/dom/media/fmp4/gonk/GonkVideoDecoderManager.h @@ -38,26 +38,24 @@ typedef android::MediaCodecProxy MediaCodecProxy; typedef mozilla::layers::TextureClient TextureClient; public: - GonkVideoDecoderManager(MediaTaskQueue* aTaskQueue, - mozilla::layers::ImageContainer* aImageContainer, + GonkVideoDecoderManager(mozilla::layers::ImageContainer* aImageContainer, const VideoInfo& aConfig); - ~GonkVideoDecoderManager(); + virtual ~GonkVideoDecoderManager() override; virtual android::sp Init(MediaDataDecoderCallback* aCallback) override; + virtual nsresult Input(MediaRawData* aSample) override; + virtual nsresult Output(int64_t aStreamOffset, nsRefPtr& aOutput) override; virtual nsresult Flush() override; - virtual void ReleaseMediaResources(); + virtual bool HasQueuedSample() override; static void RecycleCallback(TextureClient* aClient, void* aClosure); -protected: - virtual android::status_t SendSampleToOMX(MediaRawData* aSample) override; - private: struct FrameInfo { @@ -129,7 +127,6 @@ private: nsIntRect mPicture; nsIntSize mInitialFrame; - android::sp mDecoder; nsRefPtr mImageContainer; android::MediaBuffer* mVideoBuffer; @@ -160,6 +157,16 @@ private: // The lock protects mPendingVideoBuffers. Mutex mPendingVideoBuffersLock; + // MediaCodedc's wrapper that performs the decoding. + android::sp mDecoder; + + // This monitor protects mQueueSample. + Monitor mMonitor; + + // An queue with the MP4 samples which are waiting to be sent into OMX. + // If an element is an empty MP4Sample, that menas EOS. There should not + // any sample be queued after EOS. + nsTArray> mQueueSample; }; } // namespace mozilla diff --git a/dom/system/gonk/nsIVolume.idl b/dom/system/gonk/nsIVolume.idl index ac7d3480412b..60785f0a42b5 100644 --- a/dom/system/gonk/nsIVolume.idl +++ b/dom/system/gonk/nsIVolume.idl @@ -101,6 +101,7 @@ interface nsIVolume : nsISupports %{C++ // For use with the ObserverService #define NS_VOLUME_STATE_CHANGED "volume-state-changed" +#define NS_VOLUME_REMOVED "volume-removed" namespace mozilla { namespace system { diff --git a/dom/system/gonk/nsIVolumeService.idl b/dom/system/gonk/nsIVolumeService.idl index 44f19e09d442..d3752e201980 100644 --- a/dom/system/gonk/nsIVolumeService.idl +++ b/dom/system/gonk/nsIVolumeService.idl @@ -8,7 +8,7 @@ interface nsIArray; -[scriptable, uuid(879874c6-5532-437a-bf76-703d0c2e7e77)] +[scriptable, uuid(cfbf9880-cba5-11e4-8830-0800200c9a66)] interface nsIVolumeService : nsISupports { nsIVolume getVolumeByName(in DOMString volName); @@ -24,6 +24,9 @@ interface nsIVolumeService : nsISupports /* for test case only to simulate sdcard insertion/removal */ void createFakeVolume(in DOMString name, in DOMString path); void SetFakeVolumeState(in DOMString name, in long state); + + /* for test case only to test removal of storage area */ + void removeFakeVolume(in DOMString name); }; %{C++ diff --git a/dom/system/gonk/nsVolumeService.cpp b/dom/system/gonk/nsVolumeService.cpp index a8200dcbbfc4..80fa8c871456 100644 --- a/dom/system/gonk/nsVolumeService.cpp +++ b/dom/system/gonk/nsVolumeService.cpp @@ -439,7 +439,7 @@ NS_IMETHODIMP nsVolumeService::CreateFakeVolume(const nsAString& name, const nsAString& path) { if (XRE_GetProcessType() == GeckoProcessType_Default) { - nsRefPtr vol = new nsVolume(name, path, nsIVolume::STATE_INIT, + nsRefPtr vol = new nsVolume(name, path, nsIVolume::STATE_MOUNTED, -1 /* mountGeneration */, true /* isMediaPresent */, false /* isSharing */, @@ -469,9 +469,15 @@ nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state) if (!vol || !vol->IsFake()) { return NS_ERROR_NOT_AVAILABLE; } - vol->SetState(state); - vol->LogState(); - UpdateVolume(vol.get()); + + // UpdateVolume expects the volume passed in to NOT be the + // same pointer as what CreateOrFindVolumeByName would return, + // which is why we allocate a temporary volume here. + nsRefPtr volume = new nsVolume(name); + volume->Set(vol); + volume->SetState(state); + volume->LogState(); + UpdateVolume(volume.get()); return NS_OK; } @@ -479,6 +485,41 @@ nsVolumeService::SetFakeVolumeState(const nsAString& name, int32_t state) return NS_OK; } +NS_IMETHODIMP +nsVolumeService::RemoveFakeVolume(const nsAString& name) +{ + if (XRE_GetProcessType() == GeckoProcessType_Default) { + SetFakeVolumeState(name, nsIVolume::STATE_NOMEDIA); + RemoveVolumeByName(name); + return NS_OK; + } + + ContentChild::GetSingleton()->SendRemoveFakeVolume(nsString(name)); + return NS_OK; +} + +void +nsVolumeService::RemoveVolumeByName(const nsAString& aName) +{ + nsRefPtr vol; + { + MonitorAutoLock autoLock(mArrayMonitor); + vol = FindVolumeByName(aName); + } + if (!vol) { + return; + } + mVolumeArray.RemoveElement(vol); + + if (XRE_GetProcessType() == GeckoProcessType_Default) { + nsCOMPtr obs = GetObserverService(); + if (!obs) { + return; + } + obs->NotifyObservers(nullptr, NS_VOLUME_REMOVED, nsString(aName).get()); + } +} + /*************************************************************************** * The UpdateVolumeRunnable creates an nsVolume and updates the main thread * data structure while running on the main thread. diff --git a/dom/system/gonk/nsVolumeService.h b/dom/system/gonk/nsVolumeService.h index d3a615a4536f..9c1f11cc4820 100644 --- a/dom/system/gonk/nsVolumeService.h +++ b/dom/system/gonk/nsVolumeService.h @@ -46,12 +46,15 @@ public: void DumpNoLock(const char* aLabel); + // To use this function, you have to create a new volume and pass it in. void UpdateVolume(nsIVolume* aVolume, bool aNotifyObservers = true); void UpdateVolumeIOThread(const Volume* aVolume); void RecvVolumesFromParent(const nsTArray& aVolumes); void GetVolumesForIPC(nsTArray* aResult); + void RemoveVolumeByName(const nsAString& aName); + private: ~nsVolumeService(); diff --git a/dom/tests/mochitest/general/test_interfaces.html b/dom/tests/mochitest/general/test_interfaces.html index 21ad5985a526..893817a31bec 100644 --- a/dom/tests/mochitest/general/test_interfaces.html +++ b/dom/tests/mochitest/general/test_interfaces.html @@ -342,6 +342,8 @@ var interfaceNamesInGlobalScope = "DeviceProximityEvent", // IMPORTANT: Do not change this list without review from a DOM peer! { name: "DeviceStorageAreaChangedEvent", desktop: false}, +// IMPORTANT: Do not change this list without review from a DOM peer! + { name: "DeviceStorageAreaListener", desktop: false}, // IMPORTANT: Do not change this list without review from a DOM peer! { name: "DeviceStorage", desktop: false}, // IMPORTANT: Do not change this list without review from a DOM peer! diff --git a/dom/webidl/DeviceStorageAreaListener.webidl b/dom/webidl/DeviceStorageAreaListener.webidl new file mode 100644 index 000000000000..a735ed8fb48f --- /dev/null +++ b/dom/webidl/DeviceStorageAreaListener.webidl @@ -0,0 +1,10 @@ +/* -*- Mode: IDL; 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/. */ + +[Pref="device.storage.enabled"] +interface DeviceStorageAreaListener : EventTarget { + // Fired when a storage area is added or removed. + attribute EventHandler onstorageareachanged; +}; diff --git a/dom/webidl/Navigator.webidl b/dom/webidl/Navigator.webidl index 175e75262489..11d41501ce2e 100644 --- a/dom/webidl/Navigator.webidl +++ b/dom/webidl/Navigator.webidl @@ -245,12 +245,19 @@ partial interface Navigator { MozWakeLock requestWakeLock(DOMString aTopic); }; +partial interface Navigator { + [Throws, Pref="device.storage.enabled"] + readonly attribute DeviceStorageAreaListener deviceStorageAreaListener; +}; + // nsIDOMNavigatorDeviceStorage partial interface Navigator { [Throws, Pref="device.storage.enabled"] DeviceStorage? getDeviceStorage(DOMString type); [Throws, Pref="device.storage.enabled"] sequence getDeviceStorages(DOMString type); + [Throws, Pref="device.storage.enabled"] + DeviceStorage? getDeviceStorageByNameAndType(DOMString name, DOMString type); }; // nsIDOMNavigatorDesktopNotification diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index ea8c21b5c98e..ef3bee551ae9 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -103,6 +103,7 @@ WEBIDL_FILES = [ 'DesktopNotification.webidl', 'DeviceMotionEvent.webidl', 'DeviceStorage.webidl', + 'DeviceStorageAreaListener.webidl', 'Directory.webidl', 'DisplayPortInputPort.webidl', 'Document.webidl', diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index bffa50db63b3..6654f70aca80 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -224,6 +224,7 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle aValu AutoCancel autoCancel(this); if (!aValue.isObject()) { + NS_WARNING("FetchEvent::RespondWith was passed a promise resolved to a non-Object value"); return; } diff --git a/gfx/layers/D3D11ShareHandleImage.cpp b/gfx/layers/D3D11ShareHandleImage.cpp index 94b890651d91..fc8e69453912 100644 --- a/gfx/layers/D3D11ShareHandleImage.cpp +++ b/gfx/layers/D3D11ShareHandleImage.cpp @@ -43,12 +43,11 @@ TextureClient* D3D11ShareHandleImage::GetTextureClient(CompositableClient* aClient) { if (!mTextureClient) { - RefPtr textureClient = - new TextureClientD3D11(aClient->GetForwarder(), - mFormat, - TextureFlags::DEFAULT); - textureClient->InitWith(mTexture, mSize); - mTextureClient = textureClient; + mTextureClient = TextureClientD3D11::Create(aClient->GetForwarder(), + mFormat, + TextureFlags::DEFAULT, + mTexture, + mSize); } return mTextureClient; } diff --git a/gfx/layers/D3D9SurfaceImage.cpp b/gfx/layers/D3D9SurfaceImage.cpp index cc6010332599..f5b2f744ee16 100644 --- a/gfx/layers/D3D9SurfaceImage.cpp +++ b/gfx/layers/D3D9SurfaceImage.cpp @@ -202,12 +202,12 @@ D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient) { EnsureSynchronized(); if (!mTextureClient) { - RefPtr textureClient = - new SharedTextureClientD3D9(aClient->GetForwarder(), - gfx::SurfaceFormat::B8G8R8X8, - TextureFlags::DEFAULT); - textureClient->InitWith(mTexture, mShareHandle, mDesc); - mTextureClient = textureClient; + mTextureClient = SharedTextureClientD3D9::Create(aClient->GetForwarder(), + gfx::SurfaceFormat::B8G8R8X8, + TextureFlags::DEFAULT, + mTexture, + mShareHandle, + mDesc); } return mTextureClient; } diff --git a/gfx/layers/IMFYCbCrImage.cpp b/gfx/layers/IMFYCbCrImage.cpp index 33d6279035df..848ac055b1c1 100644 --- a/gfx/layers/IMFYCbCrImage.cpp +++ b/gfx/layers/IMFYCbCrImage.cpp @@ -190,12 +190,17 @@ IMFYCbCrImage::GetD3D9TextureClient(CompositableClient* aClient) return nullptr; } - RefPtr texClient = - new DXGIYCbCrTextureClient(aClient->GetForwarder(), TextureFlags::DEFAULT); - texClient->InitWith(textureY, textureCb, textureCr, - shareHandleY, shareHandleCb, shareHandleCr, - GetSize(), mData.mYSize, mData.mCbCrSize); - mTextureClient = texClient; + mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(), + TextureFlags::DEFAULT, + textureY, + textureCb, + textureCr, + shareHandleY, + shareHandleCb, + shareHandleCr, + GetSize(), + mData.mYSize, + mData.mCbCrSize); return mTextureClient; } @@ -268,12 +273,17 @@ IMFYCbCrImage::GetTextureClient(CompositableClient* aClient) textureCr->QueryInterface((IDXGIResource**)byRef(resource)); hr = resource->GetSharedHandle(&shareHandleCr); - RefPtr texClient = - new DXGIYCbCrTextureClient(aClient->GetForwarder(), TextureFlags::DEFAULT); - texClient->InitWith(textureY, textureCb, textureCr, - shareHandleY, shareHandleCb, shareHandleCr, - GetSize(), mData.mYSize, mData.mCbCrSize); - mTextureClient = texClient; + mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(), + TextureFlags::DEFAULT, + textureY, + textureCb, + textureCr, + shareHandleY, + shareHandleCb, + shareHandleCr, + GetSize(), + mData.mYSize, + mData.mCbCrSize); return mTextureClient; } diff --git a/gfx/layers/MacIOSurfaceImage.cpp b/gfx/layers/MacIOSurfaceImage.cpp index 000a308686ca..ce8c095da680 100644 --- a/gfx/layers/MacIOSurfaceImage.cpp +++ b/gfx/layers/MacIOSurfaceImage.cpp @@ -15,10 +15,9 @@ TextureClient* MacIOSurfaceImage::GetTextureClient(CompositableClient* aClient) { if (!mTextureClient) { - RefPtr buffer = - new MacIOSurfaceTextureClientOGL(aClient->GetForwarder(), TextureFlags::DEFAULT); - buffer->InitWith(mSurface); - mTextureClient = buffer; + mTextureClient = MacIOSurfaceTextureClientOGL::Create(aClient->GetForwarder(), + TextureFlags::DEFAULT, + mSurface); } return mTextureClient; } diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index c5b1a5a0859d..bde6f4fc7b35 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -1318,6 +1318,10 @@ APZCTreeManager::BuildOverscrollHandoffChain(const nsRefPtrGetScrollHandoffParentId() != apzc->GetGuid().mScrollId); + // Find the AsyncPanZoomController instance with a matching layersId and // the scroll id that matches apzc->GetScrollHandoffParentId(). To do this // search the subtree with the same layersId for the apzc with the specified diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index 95e7bd9cac4a..1d4e0dce1a14 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -212,6 +212,22 @@ TextureClientD3D11::~TextureClientD3D11() #endif } +// static +TemporaryRef +TextureClientD3D11::Create(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + TextureFlags aFlags, + ID3D11Texture2D* aTexture, + gfx::IntSize aSize) +{ + RefPtr texture = new TextureClientD3D11(aAllocator, + aFormat, + aFlags); + texture->mTexture = aTexture; + texture->mSize = aSize; + return texture; +} + TemporaryRef TextureClientD3D11::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const @@ -534,6 +550,34 @@ DXGIYCbCrTextureClient::~DXGIYCbCrTextureClient() MOZ_COUNT_DTOR(DXGIYCbCrTextureClient); } +// static +TemporaryRef +DXGIYCbCrTextureClient::Create(ISurfaceAllocator* aAllocator, + TextureFlags aFlags, + IUnknown* aTextureY, + IUnknown* aTextureCb, + IUnknown* aTextureCr, + HANDLE aHandleY, + HANDLE aHandleCb, + HANDLE aHandleCr, + const gfx::IntSize& aSize, + const gfx::IntSize& aSizeY, + const gfx::IntSize& aSizeCbCr) +{ + RefPtr texture = + new DXGIYCbCrTextureClient(aAllocator, aFlags); + texture->mHandles[0] = aHandleY; + texture->mHandles[1] = aHandleCb; + texture->mHandles[2] = aHandleCr; + texture->mHoldRefs[0] = aTextureY; + texture->mHoldRefs[1] = aTextureCb; + texture->mHoldRefs[2] = aTextureCr; + texture->mSize = aSize; + texture->mSizeY = aSizeY; + texture->mSizeCbCr = aSizeCbCr; + return texture; +} + bool DXGIYCbCrTextureClient::Lock(OpenMode) { diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index c47830dc5b45..f54e829f40cb 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -32,11 +32,13 @@ public: virtual ~TextureClientD3D11(); - void InitWith(ID3D11Texture2D* aTexture, const gfx::IntSize& aSize) - { - mTexture = aTexture; - mSize = aSize; - } + // Creates a TextureClient and init width. + static TemporaryRef + Create(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + TextureFlags aFlags, + ID3D11Texture2D* aTexture, + gfx::IntSize aSize); // TextureClient @@ -90,6 +92,20 @@ public: virtual ~DXGIYCbCrTextureClient(); + // Creates a TextureClient and init width. + static TemporaryRef + Create(ISurfaceAllocator* aAllocator, + TextureFlags aFlags, + IUnknown* aTextureY, + IUnknown* aTextureCb, + IUnknown* aTextureCr, + HANDLE aHandleY, + HANDLE aHandleCb, + HANDLE aHandleCr, + const gfx::IntSize& aSize, + const gfx::IntSize& aSizeY, + const gfx::IntSize& aSizeCbCr); + // TextureClient virtual bool IsAllocated() const override{ return !!mHoldRefs[0]; } @@ -102,27 +118,6 @@ public: virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override; - void InitWith(IUnknown* aTextureY, - IUnknown* aTextureCb, - IUnknown* aTextureCr, - HANDLE aHandleY, - HANDLE aHandleCb, - HANDLE aHandleCr, - const gfx::IntSize& aSize, - const gfx::IntSize& aSizeY, - const gfx::IntSize& aSizeCbCr) - { - mHandles[0] = aHandleY; - mHandles[1] = aHandleCb; - mHandles[2] = aHandleCr; - mHoldRefs[0] = aTextureY; - mHoldRefs[1] = aTextureCb; - mHoldRefs[2] = aTextureCr; - mSize = aSize; - mSizeY = aSizeY; - mSizeCbCr = aSizeCbCr; - } - virtual gfx::IntSize GetSize() const { return mSize; diff --git a/gfx/layers/d3d9/TextureD3D9.cpp b/gfx/layers/d3d9/TextureD3D9.cpp index e630f22b9141..a77065c447ef 100644 --- a/gfx/layers/d3d9/TextureD3D9.cpp +++ b/gfx/layers/d3d9/TextureD3D9.cpp @@ -762,6 +762,29 @@ SharedTextureClientD3D9::~SharedTextureClientD3D9() MOZ_COUNT_DTOR(SharedTextureClientD3D9); } +// static +TemporaryRef +SharedTextureClientD3D9::Create(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + TextureFlags aFlags, + IDirect3DTexture9* aTexture, + HANDLE aSharedHandle, + D3DSURFACE_DESC aDesc) +{ + RefPtr texture = + new SharedTextureClientD3D9(aAllocator, + aFormat, + aFlags); + MOZ_ASSERT(!texture->mTexture); + texture->mTexture = aTexture; + texture->mHandle = aSharedHandle; + texture->mDesc = aDesc; + if (texture->mTexture) { + gfxWindowsPlatform::sD3D9SharedTextureUsed += texture->mDesc.Width * texture->mDesc.Height * 4; + } + return texture; +} + bool SharedTextureClientD3D9::Lock(OpenMode) { diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h index 92779a632576..b41e82b8f53d 100644 --- a/gfx/layers/d3d9/TextureD3D9.h +++ b/gfx/layers/d3d9/TextureD3D9.h @@ -248,6 +248,15 @@ public: virtual ~SharedTextureClientD3D9(); + // Creates a TextureClient and init width. + static TemporaryRef + Create(ISurfaceAllocator* aAllocator, + gfx::SurfaceFormat aFormat, + TextureFlags aFlags, + IDirect3DTexture9* aTexture, + HANDLE aSharedHandle, + D3DSURFACE_DESC aDesc); + // TextureClient virtual bool IsAllocated() const override { return !!mTexture; } @@ -260,17 +269,6 @@ public: virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override; - void InitWith(IDirect3DTexture9* aTexture, HANDLE aSharedHandle, D3DSURFACE_DESC aDesc) - { - MOZ_ASSERT(!mTexture); - mTexture = aTexture; - mHandle = aSharedHandle; - mDesc = aDesc; - if (mTexture) { - gfxWindowsPlatform::sD3D9SharedTextureUsed += mDesc.Width * mDesc.Height * 4; - } - } - virtual gfx::IntSize GetSize() const { return gfx::IntSize(mDesc.Width, mDesc.Height); diff --git a/gfx/layers/opengl/GrallocTextureClient.cpp b/gfx/layers/opengl/GrallocTextureClient.cpp index f86df1fbc936..8d3cae28f567 100644 --- a/gfx/layers/opengl/GrallocTextureClient.cpp +++ b/gfx/layers/opengl/GrallocTextureClient.cpp @@ -59,16 +59,6 @@ GrallocTextureClientOGL::CreateSimilar(TextureFlags aFlags, return tex; } -void -GrallocTextureClientOGL::InitWith(MaybeMagicGrallocBufferHandle aHandle, gfx::IntSize aSize) -{ - MOZ_ASSERT(!IsAllocated()); - MOZ_ASSERT(IsValid()); - mGrallocHandle = aHandle; - mGraphicBuffer = GetGraphicBufferFrom(aHandle); - mSize = aSize; -} - bool GrallocTextureClientOGL::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) { diff --git a/gfx/layers/opengl/GrallocTextureClient.h b/gfx/layers/opengl/GrallocTextureClient.h index b031766e0aff..a352d51d48f1 100644 --- a/gfx/layers/opengl/GrallocTextureClient.h +++ b/gfx/layers/opengl/GrallocTextureClient.h @@ -60,8 +60,6 @@ public: virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override; - void InitWith(MaybeMagicGrallocBufferHandle aDesc, gfx::IntSize aSize); - void SetTextureFlags(TextureFlags aFlags) { AddFlags(aFlags); } gfx::IntSize GetSize() const override { return mSize; } diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp index aad857671c2d..c3898b5534a0 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.cpp @@ -22,12 +22,18 @@ MacIOSurfaceTextureClientOGL::~MacIOSurfaceTextureClientOGL() } } -void -MacIOSurfaceTextureClientOGL::InitWith(MacIOSurface* aSurface) +// static +TemporaryRef +MacIOSurfaceTextureClientOGL::Create(ISurfaceAllocator* aAllocator, + TextureFlags aFlags, + MacIOSurface* aSurface) { - MOZ_ASSERT(IsValid()); - MOZ_ASSERT(!IsAllocated()); - mSurface = aSurface; + RefPtr texture = + new MacIOSurfaceTextureClientOGL(aAllocator, aFlags); + MOZ_ASSERT(texture->IsValid()); + MOZ_ASSERT(!texture->IsAllocated()); + texture->mSurface = aSurface; + return texture; } bool diff --git a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h index 80d5135cd633..b7e2fa0550ae 100644 --- a/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h +++ b/gfx/layers/opengl/MacIOSurfaceTextureClientOGL.h @@ -21,7 +21,11 @@ public: virtual ~MacIOSurfaceTextureClientOGL(); - void InitWith(MacIOSurface* aSurface); + // Creates a TextureClient and init width. + static TemporaryRef + Create(ISurfaceAllocator* aAllocator, + TextureFlags aFlags, + MacIOSurface* aSurface); virtual bool Lock(OpenMode aMode) override; diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 7eab4abf8658..a85df7a3240b 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -8186,6 +8186,10 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame, } } + // If we have the scrollparent being the same as the scroll id, the + // compositor-side code could get into an infinite loop while building the + // overscroll handoff chain. + MOZ_ASSERT(aScrollParentId == FrameMetrics::NULL_SCROLL_ID || scrollId != aScrollParentId); metrics.SetScrollId(scrollId); metrics.SetIsRoot(aIsRoot); metrics.SetScrollParentId(aScrollParentId); diff --git a/layout/style/FontFace.cpp b/layout/style/FontFace.cpp index 53a01aad1a71..fd32fd73b07c 100644 --- a/layout/style/FontFace.cpp +++ b/layout/style/FontFace.cpp @@ -485,10 +485,11 @@ FontFace::ParseDescriptor(nsCSSFontDesc aDescID, nsCOMPtr principal = global->PrincipalOrNull(); nsCOMPtr window = do_QueryInterface(mParent); + nsCOMPtr docURI = window->GetDocumentURI(); nsCOMPtr base = window->GetDocBaseURI(); if (!parser.ParseFontFaceDescriptor(aDescID, aString, - nullptr, // aSheetURL + docURI, // aSheetURL base, principal, aResult)) { diff --git a/layout/style/crashtests/1161366-1.html b/layout/style/crashtests/1161366-1.html new file mode 100644 index 000000000000..d4eacccdc9e6 --- /dev/null +++ b/layout/style/crashtests/1161366-1.html @@ -0,0 +1,7 @@ + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index c775d0d32179..d3b88066a22d 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -113,5 +113,6 @@ load 1074651-1.html pref(dom.webcomponents.enabled,true) load 1089463-1.html pref(layout.css.expensive-style-struct-assertions.enabled,true) load 1136010-1.html load 1153693-1.html +load 1161366-1.html load large_border_image_width.html load border-image-visited-link.html diff --git a/layout/style/forms.css b/layout/style/forms.css index 4b35e5c7a644..fa6fd67136e8 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -827,8 +827,8 @@ input[type=range] { display: inline-block; inline-size: 12em; block-size: 1.3em; - margin-inline-start: 0.7em; - margin-inline-end: 0.7em; + -moz-margin-start: 0.7em; + -moz-margin-end: 0.7em; margin-block-start: 0; margin-block-end: 0; /* Override some rules that apply on all input types: */ @@ -843,8 +843,8 @@ input[type=range] { input[type=range][orient=block] { inline-size: 1.3em; block-size: 12em; - margin-inline-start: 0; - margin-inline-end: 0; + -moz-margin-start: 0; + -moz-margin-end: 0; margin-block-start: 0.7em; margin-block-end: 0.7em; } diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 35ae6073b0c8..52fe33f7ae63 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -2611,7 +2611,12 @@ nsRuleNode::SetDefaultOnRoot(const nsStyleStructID aSID, nsStyleContext* aContex parentdata_ = maybeFakeParentData.ptr(); \ } \ } \ - if (aStartStruct) \ + if (eStyleStruct_##type_ == eStyleStruct_Variables) \ + /* no need to copy construct an nsStyleVariables, as we will copy */ \ + /* inherited variables (and set canStoreInRuleTree to false) in */ \ + /* ComputeVariablesData */ \ + data_ = new (mPresContext) nsStyle##type_ ctorargs_; \ + else if (aStartStruct) \ /* We only need to compute the delta between this computed data and */ \ /* our computed data. */ \ data_ = new (mPresContext) \ diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 8d31c0125816..3b608bad32b2 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3643,6 +3643,7 @@ nsStyleVariables::nsStyleVariables() nsStyleVariables::nsStyleVariables(const nsStyleVariables& aSource) { MOZ_COUNT_CTOR(nsStyleVariables); + mVariables = aSource.mVariables; } nsStyleVariables::~nsStyleVariables(void) diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp index c534f14c850e..ba5e1f27d47f 100755 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -1300,7 +1300,7 @@ int WebrtcVideoConduit::SendRTCPPacket(int channel, const void* data, int len) CSFLogDebug(logTag, "%s Sent RTCP Packet ", __FUNCTION__); return len; } else if(mTransmitterTransport && - (mTransmitterTransport->SendRtpPacket(data, len) == NS_OK)) { + (mTransmitterTransport->SendRtcpPacket(data, len) == NS_OK)) { CSFLogDebug(logTag, "%s Sent RTCP Packet (sender report) ", __FUNCTION__); return len; } else { diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 487e5dadd695..3c065f66bbb0 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -401,7 +401,6 @@ xul|textbox[disabled="true"] { html|a, .text-link, .inline-link { - line-height: 22px; color: #0095dd; text-decoration: none; } diff --git a/xpcom/io/nsLinebreakConverter.cpp b/xpcom/io/nsLinebreakConverter.cpp index 67bee7a1d774..db4487fb00af 100644 --- a/xpcom/io/nsLinebreakConverter.cpp +++ b/xpcom/io/nsLinebreakConverter.cpp @@ -100,7 +100,7 @@ ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak, // handle the no conversion case if (nsCRT::strcmp(aSrcBreak, aDestBreak) == 0) { - resultString = (T*)moz_xmalloc(sizeof(T) * aIoLen); + resultString = (T*)malloc(sizeof(T) * aIoLen); if (!resultString) { return nullptr; } @@ -114,7 +114,7 @@ ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak, // handle the easy case, where the string length does not change, and the // breaks are only 1 char long, i.e. CR <-> LF if (srcBreakLen == destBreakLen && srcBreakLen == 1) { - resultString = (T*)moz_xmalloc(sizeof(T) * aIoLen); + resultString = (T*)malloc(sizeof(T) * aIoLen); if (!resultString) { return nullptr; } @@ -144,7 +144,7 @@ ConvertBreaks(const T* aInSrc, int32_t& aIoLen, const char* aSrcBreak, int32_t newBufLen = aIoLen - (numLinebreaks * srcBreakLen) + (numLinebreaks * destBreakLen); - resultString = (T*)moz_xmalloc(sizeof(T) * newBufLen); + resultString = (T*)malloc(sizeof(T) * newBufLen); if (!resultString) { return nullptr; } @@ -235,7 +235,7 @@ ConvertUnknownBreaks(const T* aInSrc, int32_t& aIoLen, const char* aDestBreak) src++; } - T* resultString = (T*)moz_xmalloc(sizeof(T) * finalLen); + T* resultString = (T*)malloc(sizeof(T) * finalLen); if (!resultString) { return nullptr; } diff --git a/xpcom/io/nsStreamUtils.cpp b/xpcom/io/nsStreamUtils.cpp index e38c037302e7..e23cda49e07a 100644 --- a/xpcom/io/nsStreamUtils.cpp +++ b/xpcom/io/nsStreamUtils.cpp @@ -853,6 +853,10 @@ nsresult NS_CloneInputStream(nsIInputStream* aSource, nsIInputStream** aCloneOut, nsIInputStream** aReplacementOut) { + if (NS_WARN_IF(!aSource)) { + return NS_ERROR_FAILURE; + } + // Attempt to perform the clone directly on the source stream nsCOMPtr cloneable = do_QueryInterface(aSource); if (cloneable && cloneable->GetCloneable()) { diff --git a/xpcom/tests/gtest/TestCloneInputStream.cpp b/xpcom/tests/gtest/TestCloneInputStream.cpp index d9b2dc28dde2..633d207988f9 100644 --- a/xpcom/tests/gtest/TestCloneInputStream.cpp +++ b/xpcom/tests/gtest/TestCloneInputStream.cpp @@ -12,6 +12,14 @@ #include "nsStreamUtils.h" #include "nsStringStream.h" +TEST(CloneInputStream, InvalidInput) +{ + nsCOMPtr clone; + nsresult rv = NS_CloneInputStream(nullptr, getter_AddRefs(clone)); + ASSERT_TRUE(NS_FAILED(rv)); + ASSERT_FALSE(clone); +} + TEST(CloneInputStream, CloneableInput) { nsTArray inputData;