From 0846dc4263d256c8353cc19f68c4591bc85faf7e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 11 Dec 2014 14:11:43 -0800 Subject: [PATCH 01/36] Bug 1109407 - Give SegmentedVector a default segment size. r=froydnj. --HG-- extra : rebase_source : 0ceae77c9fec06bbd8c3231434f62fc0e83d9bf1 --- mfbt/SegmentedVector.h | 24 ++++++++++++++++++------ mfbt/tests/TestSegmentedVector.cpp | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/mfbt/SegmentedVector.h b/mfbt/SegmentedVector.h index 1223bedea6c7..e583e4e44829 100644 --- a/mfbt/SegmentedVector.h +++ b/mfbt/SegmentedVector.h @@ -32,12 +32,24 @@ namespace mozilla { -// IdealSegmentSize is how big each segment will be in bytes (or as close as is -// possible). It's best to choose a size that's a power-of-two (to avoid slop) -// and moderately large (not too small so segment allocations are infrequent, -// and not too large so that not too much space is wasted when the final -// segment is not full). Something like 4096 or 8192 is probably good. -template class SegmentedVector : private AllocPolicy { diff --git a/mfbt/tests/TestSegmentedVector.cpp b/mfbt/tests/TestSegmentedVector.cpp index 265e7cde3ffc..c426f6d927c8 100644 --- a/mfbt/tests/TestSegmentedVector.cpp +++ b/mfbt/tests/TestSegmentedVector.cpp @@ -147,7 +147,7 @@ void TestSegmentCapacitiesAndAlignments() SegmentedVector v3(999); SegmentedVector v4(10); SegmentedVector v5(1234); - SegmentedVector v6(4096); + SegmentedVector v6(4096); // 4096 is the default segment size SegmentedVector, 100> v7(100); } From 7867c261cc83624f62aecadbde916a1d4b8cafe4 Mon Sep 17 00:00:00 2001 From: Matthew Gregan Date: Thu, 11 Dec 2014 12:17:19 +1300 Subject: [PATCH 02/36] Bug 1109802 - Release IAudioStreamVolume after use in libcubeb's WASAPI backend. r=padenot --- media/libcubeb/src/cubeb_wasapi.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/media/libcubeb/src/cubeb_wasapi.cpp b/media/libcubeb/src/cubeb_wasapi.cpp index 8a272b0d89cd..b22b3b44ba2a 100644 --- a/media/libcubeb/src/cubeb_wasapi.cpp +++ b/media/libcubeb/src/cubeb_wasapi.cpp @@ -831,6 +831,7 @@ void wasapi_stream_destroy(cubeb_stream * stm) SafeRelease(stm->client); SafeRelease(stm->render_client); SafeRelease(stm->audio_clock); + SafeRelease(stm->audio_stream_volume); cubeb_resampler_destroy(stm->resampler); From 6bd9ba41ecdcb0994dc67da7c1a7ef3df1e4a69e Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Sun, 7 Dec 2014 19:53:33 -0800 Subject: [PATCH 03/36] Bug 1104623 - Inherit security flags if channel already has a loadinfo attached in NS_NewChannel (r=bz,sworkman) --- docshell/base/LoadInfo.cpp | 6 +++ docshell/base/nsILoadInfo.idl | 12 ++++-- netwerk/base/public/nsNetUtil.h | 74 ++++++++++++++++++++++----------- 3 files changed, 65 insertions(+), 27 deletions(-) diff --git a/docshell/base/LoadInfo.cpp b/docshell/base/LoadInfo.cpp index 79ac48e51aa1..068408c9f350 100644 --- a/docshell/base/LoadInfo.cpp +++ b/docshell/base/LoadInfo.cpp @@ -122,4 +122,10 @@ LoadInfo::GetBaseURI(nsIURI** aBaseURI) return NS_OK; } +nsIURI* +LoadInfo::BaseURI() +{ + return mBaseURI; +} + } // namespace mozilla diff --git a/docshell/base/nsILoadInfo.idl b/docshell/base/nsILoadInfo.idl index 4ca48c2b195d..2e516d821388 100644 --- a/docshell/base/nsILoadInfo.idl +++ b/docshell/base/nsILoadInfo.idl @@ -17,7 +17,7 @@ typedef unsigned long nsSecurityFlags; /** * An nsILoadOwner represents per-load information about who started the load. */ -[scriptable, builtinclass, uuid(da363267-236d-49bf-83a2-33da8d892728)] +[scriptable, builtinclass, uuid(768a1f20-57d4-462a-812a-41c04e5d1e19)] interface nsILoadInfo : nsISupports { /** @@ -156,7 +156,7 @@ interface nsILoadInfo : nsISupports * The contentPolicyType of the channel, used for security checks * like Mixed Content Blocking and Content Security Policy. */ - readonly attribute nsContentPolicyType contentPolicyType; + readonly attribute nsContentPolicyType contentPolicyType; %{ C++ inline nsContentPolicyType GetContentPolicyType() @@ -173,5 +173,11 @@ interface nsILoadInfo : nsISupports * This attribute may be null. The value of this attribute may be * ignored if the base URI can be inferred by the channel's URI. */ - readonly attribute nsIURI baseURI; + readonly attribute nsIURI baseURI; + + /** + * A C++-friendly version of baseURI. + */ + [noscript, notxpcom, nostdcall, binaryname(BaseURI)] + nsIURI binaryBaseURI(); }; diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index b58f043b57c2..9fe75cf5489d 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -200,13 +200,17 @@ NS_NewFileURI(nsIURI* *result, inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, nsIURI* aUri, - nsILoadInfo* aLoadInfo, + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aTriggeringPrincipal, + nsSecurityFlags aSecurityFlags, + nsContentPolicyType aContentPolicyType, + nsIURI* aBaseURI = nullptr, nsILoadGroup* aLoadGroup = nullptr, nsIInterfaceRequestor* aCallbacks = nullptr, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aLoadInfo, "Can not create channel without aLoadInfo!"); NS_ENSURE_ARG_POINTER(outChannel); nsCOMPtr grip; @@ -234,11 +238,31 @@ NS_NewChannelInternal(nsIChannel** outChannel, rv = channel->SetLoadFlags(aLoadFlags | (normalLoadFlags & nsIChannel::LOAD_REPLACE)); NS_ENSURE_SUCCESS(rv, rv); } - channel->SetLoadInfo(aLoadInfo); + + // Some channels might already have a loadInfo attached at this + // point (see bug 1104623). We have to make sure to update + // security flags in such cases before we set the loadinfo. + // Once bug 1087442 lands, this problem disappears because we + // attach the loadinfo in each individual protocol handler. + nsCOMPtr loadInfo; + channel->GetLoadInfo(getter_AddRefs(loadInfo)); + if (loadInfo) { + aSecurityFlags |= loadInfo->GetSecurityFlags(); + } + + // create a new Loadinfo with the potentially updated securityFlags + loadInfo = + new mozilla::LoadInfo(aRequestingPrincipal, aTriggeringPrincipal, + aRequestingNode, aSecurityFlags, + aContentPolicyType, aBaseURI); + if (!loadInfo) { + return NS_ERROR_UNEXPECTED; + } + channel->SetLoadInfo(loadInfo); // If we're sandboxed, make sure to clear any owner the channel // might already have. - if (aLoadInfo->GetLoadingSandboxed()) { + if (loadInfo->GetLoadingSandboxed()) { channel->SetOwner(nullptr); } @@ -249,31 +273,27 @@ NS_NewChannelInternal(nsIChannel** outChannel, inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, - nsIPrincipal* aTriggeringPrincipal, - nsSecurityFlags aSecurityFlags, - nsContentPolicyType aContentPolicyType, + nsILoadInfo* aLoadInfo, nsILoadGroup* aLoadGroup = nullptr, nsIInterfaceRequestor* aCallbacks = nullptr, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); - - nsCOMPtr loadInfo = - new mozilla::LoadInfo(aRequestingPrincipal, aTriggeringPrincipal, - aRequestingNode, aSecurityFlags, aContentPolicyType); - if (!loadInfo) { - return NS_ERROR_UNEXPECTED; - } - return NS_NewChannelInternal(outChannel, - aUri, - loadInfo, - aLoadGroup, - aCallbacks, - aLoadFlags, - aIoService); + MOZ_ASSERT(aLoadInfo, "Can not create a channel without a loadInfo"); + nsresult rv = NS_NewChannelInternal(outChannel, + aUri, + aLoadInfo->LoadingNode(), + aLoadInfo->LoadingPrincipal(), + aLoadInfo->TriggeringPrincipal(), + aLoadInfo->GetSecurityFlags(), + aLoadInfo->GetContentPolicyType(), + aLoadInfo->BaseURI(), + aLoadGroup, + aCallbacks, + aLoadFlags, + aIoService); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; } inline nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */ @@ -297,6 +317,7 @@ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -323,6 +344,7 @@ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -348,6 +370,7 @@ NS_NewChannel(nsIChannel** outChannel, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -372,6 +395,7 @@ NS_NewChannel(nsIChannel** outChannel, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -406,6 +430,7 @@ NS_OpenURIInternal(nsIInputStream** outStream, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -962,6 +987,7 @@ NS_NewStreamLoaderInternal(nsIStreamLoader** outStream, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags); From 3f3a7ab1cfb20c9f1986e46d07e89ce644391283 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 11 Dec 2014 13:03:27 -0800 Subject: [PATCH 04/36] Don't reuse input blocks with dead APZCs. (bug 1110038, r=kats) --HG-- extra : rebase_source : 458816195b9e8e0394bfdf662b7173328015415c --- gfx/layers/apz/src/InputQueue.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gfx/layers/apz/src/InputQueue.cpp b/gfx/layers/apz/src/InputQueue.cpp index 8b10fe998cae..3cc424aafe19 100644 --- a/gfx/layers/apz/src/InputQueue.cpp +++ b/gfx/layers/apz/src/InputQueue.cpp @@ -127,7 +127,12 @@ InputQueue::ReceiveScrollWheelInput(const nsRefPtr& aTar uint64_t* aOutInputBlockId) { WheelBlockState* block = nullptr; if (!mInputBlockQueue.IsEmpty()) { - block = mInputBlockQueue.LastElement().get()->AsWheelBlock(); + block = mInputBlockQueue.LastElement()->AsWheelBlock(); + + // If the block's APZC has been destroyed, request a new block. + if (block && block->GetTargetApzc()->IsDestroyed()) { + block = nullptr; + } } if (!block) { From ddf2a093e3927032927bc2f59c6da5ee2d82cc09 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Thu, 11 Dec 2014 21:53:12 -0500 Subject: [PATCH 05/36] Bug 1095927 - expose HTML time element semantics in acc layer, r=tbsaunde --- accessible/base/nsAccessibilityService.cpp | 3 ++- accessible/generic/HyperTextAccessible.cpp | 9 +++++++++ accessible/tests/mochitest/elm/test_HTMLSpec.html | 7 ++++++- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/accessible/base/nsAccessibilityService.cpp b/accessible/base/nsAccessibilityService.cpp index eb5e028312f1..a765bb92d2f2 100644 --- a/accessible/base/nsAccessibilityService.cpp +++ b/accessible/base/nsAccessibilityService.cpp @@ -1480,7 +1480,8 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame, tag == nsGkAtoms::h6 || tag == nsGkAtoms::nav || tag == nsGkAtoms::q || - tag == nsGkAtoms::section) { + tag == nsGkAtoms::section || + tag == nsGkAtoms::time) { nsRefPtr accessible = new HyperTextAccessibleWrap(aContent, document); return accessible.forget(); diff --git a/accessible/generic/HyperTextAccessible.cpp b/accessible/generic/HyperTextAccessible.cpp index 5e8718e432bb..a9de7f3ad022 100644 --- a/accessible/generic/HyperTextAccessible.cpp +++ b/accessible/generic/HyperTextAccessible.cpp @@ -982,6 +982,15 @@ HyperTextAccessible::NativeAttributes() } else if (tag == nsGkAtoms::main) { nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, NS_LITERAL_STRING("main")); + } else if (tag == nsGkAtoms::time) { + nsAccUtils::SetAccAttr(attributes, nsGkAtoms::xmlroles, + NS_LITERAL_STRING("time")); + + if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::datetime)) { + nsAutoString datetime; + mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::datetime, datetime); + nsAccUtils::SetAccAttr(attributes, nsGkAtoms::datetime, datetime); + } } return attributes.forget(); diff --git a/accessible/tests/mochitest/elm/test_HTMLSpec.html b/accessible/tests/mochitest/elm/test_HTMLSpec.html index b2978a1f979b..867b334ab9f5 100644 --- a/accessible/tests/mochitest/elm/test_HTMLSpec.html +++ b/accessible/tests/mochitest/elm/test_HTMLSpec.html @@ -1232,7 +1232,12 @@ ////////////////////////////////////////////////////////////////////////// // HTML:time - ok(!isAccessible("time"), "time element is not accessible"); + obj = { + role: ROLE_TEXT_CONTAINER, + attributes: { "xml-roles": "time", "datetime": "2001-05-15 19:00" }, + interfaces: [ nsIAccessibleText, nsIAccessibleHyperText ] + }; + testElm("time", obj); ////////////////////////////////////////////////////////////////////////// // HTML:u contained by paragraph From 9a1f2f231f6c350904a5d3e3d8419f798be3bb23 Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Wed, 15 Oct 2014 21:56:52 -0700 Subject: [PATCH 06/36] Bug 1092311 - Fix IndexedDB profiler markers and logging, r=khuey. --- dom/indexedDB/ActorsChild.cpp | 98 ++++- dom/indexedDB/ActorsChild.h | 89 +++- dom/indexedDB/ActorsParent.cpp | 387 ++++++++++++++---- dom/indexedDB/ActorsParent.h | 7 +- dom/indexedDB/IDBCursor.cpp | 249 +++++------ dom/indexedDB/IDBDatabase.cpp | 55 ++- dom/indexedDB/IDBFactory.cpp | 118 ++++-- dom/indexedDB/IDBFactory.h | 7 +- dom/indexedDB/IDBIndex.cpp | 162 +++++--- dom/indexedDB/IDBObjectStore.cpp | 286 +++++++------ dom/indexedDB/IDBObjectStore.h | 24 +- dom/indexedDB/IDBRequest.cpp | 36 +- dom/indexedDB/IDBRequest.h | 18 +- dom/indexedDB/IDBTransaction.cpp | 85 +++- dom/indexedDB/IDBTransaction.h | 14 +- dom/indexedDB/IndexedDatabaseManager.cpp | 111 ++++- dom/indexedDB/IndexedDatabaseManager.h | 35 ++ dom/indexedDB/PBackgroundIDBFactory.ipdl | 2 + dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh | 10 + dom/indexedDB/ProfilerHelpers.h | 294 +++++++++---- dom/indexedDB/TransactionThreadPool.cpp | 120 +++--- dom/indexedDB/TransactionThreadPool.h | 21 +- ipc/glue/BackgroundChildImpl.cpp | 10 +- ipc/glue/BackgroundChildImpl.h | 14 +- ipc/glue/BackgroundParentImpl.cpp | 14 +- ipc/glue/BackgroundParentImpl.h | 6 +- ipc/glue/PBackground.ipdl | 3 +- ipc/glue/moz.build | 1 + modules/libpref/init/all.js | 6 + 29 files changed, 1622 insertions(+), 660 deletions(-) diff --git a/dom/indexedDB/ActorsChild.cpp b/dom/indexedDB/ActorsChild.cpp index 5043d4265211..bebcbab12bea 100644 --- a/dom/indexedDB/ActorsChild.cpp +++ b/dom/indexedDB/ActorsChild.cpp @@ -56,6 +56,37 @@ namespace mozilla { namespace dom { namespace indexedDB { +/******************************************************************************* + * ThreadLocal + ******************************************************************************/ + +ThreadLocal::ThreadLocal(const nsID& aBackgroundChildLoggingId) + : mLoggingInfo(aBackgroundChildLoggingId, 1, -1, 1) + , mCurrentTransaction(0) +#ifdef DEBUG + , mOwningThread(PR_GetCurrentThread()) +#endif +{ + MOZ_ASSERT(mOwningThread); + + MOZ_COUNT_CTOR(mozilla::dom::indexedDB::ThreadLocal); +} + +ThreadLocal::~ThreadLocal() +{ + MOZ_COUNT_DTOR(mozilla::dom::indexedDB::ThreadLocal); +} + +#ifdef DEBUG + +void +ThreadLocal::AssertIsOnOwningThread() const +{ + MOZ_ASSERT(PR_GetCurrentThread() == mOwningThread); +} + +#endif // DEBUG + /******************************************************************************* * Helpers ******************************************************************************/ @@ -104,39 +135,40 @@ class MOZ_STACK_CLASS AutoSetCurrentTransaction MOZ_FINAL IDBTransaction* const mTransaction; IDBTransaction* mPreviousTransaction; - IDBTransaction** mThreadLocalSlot; + ThreadLocal* mThreadLocal; public: explicit AutoSetCurrentTransaction(IDBTransaction* aTransaction) : mTransaction(aTransaction) , mPreviousTransaction(nullptr) - , mThreadLocalSlot(nullptr) + , mThreadLocal(nullptr) { if (aTransaction) { BackgroundChildImpl::ThreadLocal* threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); MOZ_ASSERT(threadLocal); - // Hang onto this location for resetting later. - mThreadLocalSlot = &threadLocal->mCurrentTransaction; + // Hang onto this for resetting later. + mThreadLocal = threadLocal->mIndexedDBThreadLocal; + MOZ_ASSERT(mThreadLocal); // Save the current value. - mPreviousTransaction = *mThreadLocalSlot; + mPreviousTransaction = mThreadLocal->GetCurrentTransaction(); // Set the new value. - *mThreadLocalSlot = aTransaction; + mThreadLocal->SetCurrentTransaction(aTransaction); } } ~AutoSetCurrentTransaction() { - MOZ_ASSERT_IF(mThreadLocalSlot, mTransaction); - - if (mThreadLocalSlot) { - MOZ_ASSERT(*mThreadLocalSlot == mTransaction); + MOZ_ASSERT_IF(mThreadLocal, mTransaction); + MOZ_ASSERT_IF(mThreadLocal, + mThreadLocal->GetCurrentTransaction() == mTransaction); + if (mThreadLocal) { // Reset old value. - *mThreadLocalSlot = mPreviousTransaction; + mThreadLocal->SetCurrentTransaction(mPreviousTransaction); } } @@ -589,6 +621,25 @@ DispatchErrorEvent(IDBRequest* aRequest, asct.emplace(aTransaction); } + if (transaction) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "Firing %s event with error 0x%x", + "IndexedDB %s: C T[%lld] R[%llu]: %s (0x%x)", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(aEvent, kErrorEventType), + aErrorCode); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " + "Firing %s event with error 0x%x", + "IndexedDB %s: C R[%llu]: %s (0x%x)", + IDB_LOG_ID_STRING(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(aEvent, kErrorEventType), + aErrorCode); + } + bool doDefault; nsresult rv = request->DispatchEvent(aEvent, &doDefault); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -648,6 +699,22 @@ DispatchSuccessEvent(ResultHelper* aResultHelper, MOZ_ASSERT(aEvent); MOZ_ASSERT_IF(transaction, transaction->IsOpen()); + if (transaction) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "Firing %s event", + "IndexedDB %s: C T[%lld] R[%llu]: %s", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(aEvent, kSuccessEventType)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: Firing %s event", + "IndexedDB %s: C R[%llu]: %s", + IDB_LOG_ID_STRING(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(aEvent, kSuccessEventType)); + } + bool dummy; nsresult rv = request->DispatchEvent(aEvent, &dummy); if (NS_WARN_IF(NS_FAILED(rv))) { @@ -1068,6 +1135,11 @@ BackgroundFactoryRequestChild::RecvBlocked(const uint64_t& aCurrentVersion) nsRefPtr kungFuDeathGrip = mRequest; + IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: Firing \"blocked\" event", + "IndexedDB %s: C R[%llu]: \"blocked\"", + IDB_LOG_ID_STRING(), + mRequest->LoggingSerialNumber()); + bool dummy; if (NS_FAILED(mRequest->DispatchEvent(blockedEvent, &dummy))) { NS_WARNING("Failed to dispatch event!"); @@ -1357,6 +1429,10 @@ BackgroundDatabaseChild::RecvVersionChange(const uint64_t& aOldVersion, return false; } + IDB_LOG_MARK("IndexedDB %s: Child : Firing \"versionchange\" event", + "IndexedDB %s: C: IDBDatabase \"versionchange\" event", + IDB_LOG_ID_STRING()); + bool dummy; if (NS_FAILED(mDatabase->DispatchEvent(versionChangeEvent, &dummy))) { NS_WARNING("Failed to dispatch event!"); diff --git a/dom/indexedDB/ActorsChild.h b/dom/indexedDB/ActorsChild.h index d77ff27db1b3..f93cbc89e842 100644 --- a/dom/indexedDB/ActorsChild.h +++ b/dom/indexedDB/ActorsChild.h @@ -5,6 +5,7 @@ #ifndef mozilla_dom_indexeddb_actorschild_h__ #define mozilla_dom_indexeddb_actorschild_h__ +#include "IDBTransaction.h" #include "js/RootingAPI.h" #include "mozilla/Attributes.h" #include "mozilla/dom/indexedDB/PBackgroundIDBCursorChild.h" @@ -12,6 +13,7 @@ #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h" #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryRequestChild.h" #include "mozilla/dom/indexedDB/PBackgroundIDBRequestChild.h" +#include "mozilla/dom/indexedDB/PBackgroundIDBSharedTypes.h" #include "mozilla/dom/indexedDB/PBackgroundIDBTransactionChild.h" #include "mozilla/dom/indexedDB/PBackgroundIDBVersionChangeTransactionChild.h" #include "nsAutoPtr.h" @@ -19,6 +21,7 @@ #include "nsTArray.h" class nsIEventTarget; +struct nsID; struct PRThread; namespace mozilla { @@ -38,13 +41,97 @@ class IDBFactory; class IDBMutableFile; class IDBOpenDBRequest; class IDBRequest; -class IDBTransaction; class Key; class PBackgroundIDBFileChild; class PermissionRequestChild; class PermissionRequestParent; class SerializedStructuredCloneReadInfo; +class ThreadLocal +{ + friend class nsAutoPtr; + friend class IDBFactory; + + LoggingInfo mLoggingInfo; + IDBTransaction* mCurrentTransaction; + +#ifdef DEBUG + PRThread* mOwningThread; +#endif + +public: + void + AssertIsOnOwningThread() const +#ifdef DEBUG + ; +#else + { } +#endif + + const LoggingInfo& + GetLoggingInfo() const + { + AssertIsOnOwningThread(); + + return mLoggingInfo; + } + + const nsID& + Id() const + { + AssertIsOnOwningThread(); + + return mLoggingInfo.backgroundChildLoggingId(); + } + + int64_t + NextTransactionSN(IDBTransaction::Mode aMode) + { + AssertIsOnOwningThread(); + MOZ_ASSERT(mLoggingInfo.nextTransactionSerialNumber() < INT64_MAX); + MOZ_ASSERT(mLoggingInfo.nextVersionChangeTransactionSerialNumber() > + INT64_MIN); + + if (aMode == IDBTransaction::VERSION_CHANGE) { + return mLoggingInfo.nextVersionChangeTransactionSerialNumber()--; + } + + return mLoggingInfo.nextTransactionSerialNumber()++; + } + + uint64_t + NextRequestSN() + { + AssertIsOnOwningThread(); + MOZ_ASSERT(mLoggingInfo.nextRequestSerialNumber() < UINT64_MAX); + + return mLoggingInfo.nextRequestSerialNumber()++; + } + + void + SetCurrentTransaction(IDBTransaction* aCurrentTransaction) + { + AssertIsOnOwningThread(); + + mCurrentTransaction = aCurrentTransaction; + } + + IDBTransaction* + GetCurrentTransaction() const + { + AssertIsOnOwningThread(); + + return mCurrentTransaction; + } + +private: + ThreadLocal(const nsID& aBackgroundChildLoggingId); + ~ThreadLocal(); + + ThreadLocal() MOZ_DELETE; + ThreadLocal(const ThreadLocal& aOther) MOZ_DELETE; +}; + class BackgroundFactoryChild MOZ_FINAL : public PBackgroundIDBFactoryChild { diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp index 8944be1f04f0..620b04da1797 100644 --- a/dom/indexedDB/ActorsParent.cpp +++ b/dom/indexedDB/ActorsParent.cpp @@ -107,6 +107,7 @@ namespace { class Cursor; class Database; struct DatabaseActorInfo; +class DatabaseLoggingInfo; class DatabaseFile; class DatabaseOfflineStorage; class Factory; @@ -2553,17 +2554,14 @@ class DatabaseOperationBase : public nsRunnable , public mozIStorageProgressHandler { - // Uniquely tracks each operation for logging purposes. Only modified on the - // PBackground thread. - static uint64_t sNextSerialNumber; - protected: class AutoSetProgressHandler; typedef nsDataHashtable UniqueIndexTable; nsCOMPtr mOwningThread; - const uint64_t mSerialNumber; + const nsID mBackgroundChildLoggingId; + const uint64_t mLoggingSerialNumber; nsresult mResultCode; private: @@ -2610,10 +2608,16 @@ public: return mOperationMayProceed; } - uint64_t - SerialNumber() const + const nsID& + BackgroundChildLoggingId() const { - return mSerialNumber; + return mBackgroundChildLoggingId; + } + + uint64_t + LoggingSerialNumber() const + { + return mLoggingSerialNumber; } nsresult @@ -2632,9 +2636,11 @@ public: } protected: - DatabaseOperationBase() + DatabaseOperationBase(const nsID& aBackgroundChildLoggingId, + uint64_t aLoggingSerialNumber) : mOwningThread(NS_GetCurrentThread()) - , mSerialNumber(++sNextSerialNumber) + , mBackgroundChildLoggingId(aBackgroundChildLoggingId) + , mLoggingSerialNumber(aLoggingSerialNumber) , mResultCode(NS_OK) , mOperationMayProceed(true) , mActorDestroyed(false) @@ -2709,6 +2715,7 @@ class TransactionDatabaseOperationBase : public DatabaseOperationBase { nsRefPtr mTransaction; + const int64_t mTransactionLoggingSerialNumber; const bool mTransactionIsAborted; public: @@ -2736,7 +2743,11 @@ public: Cleanup(); protected: - explicit TransactionDatabaseOperationBase(TransactionBase* aTransaction); + explicit + TransactionDatabaseOperationBase(TransactionBase* aTransaction); + + TransactionDatabaseOperationBase(TransactionBase* aTransaction, + uint64_t aLoggingSerialNumber); virtual ~TransactionDatabaseOperationBase(); @@ -2779,17 +2790,29 @@ class Factory MOZ_FINAL // ActorDestroy called. static uint64_t sFactoryInstanceCount; + nsRefPtr mLoggingInfo; + DebugOnly mActorDestroyed; public: static already_AddRefed - Create(); + Create(const LoggingInfo& aLoggingInfo); + + DatabaseLoggingInfo* + GetLoggingInfo() const + { + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mLoggingInfo); + + return mLoggingInfo; + } NS_INLINE_DECL_THREADSAFE_REFCOUNTING(mozilla::dom::indexedDB::Factory) private: // Only constructed in Create(). - explicit Factory(); + explicit + Factory(already_AddRefed aLoggingInfo); // Reference counted. ~Factory(); @@ -2801,6 +2824,9 @@ private: virtual bool RecvDeleteMe() MOZ_OVERRIDE; + virtual bool + RecvIncrementLoggingRequestSerialNumber() MOZ_OVERRIDE; + virtual PBackgroundIDBFactoryRequestParent* AllocPBackgroundIDBFactoryRequestParent(const FactoryRequestParams& aParams) MOZ_OVERRIDE; @@ -2924,6 +2950,15 @@ public: return Manager()->Manager(); } + DatabaseLoggingInfo* + GetLoggingInfo() const + { + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mFactory); + + return mFactory->GetLoggingInfo(); + } + bool RegisterTransaction(TransactionBase* aTransaction); @@ -3130,6 +3165,7 @@ private: mModifiedAutoIncrementObjectStoreMetadataArray; const uint64_t mTransactionId; const nsCString mDatabaseId; + const int64_t mLoggingSerialNumber; uint64_t mActiveRequestCount; Atomic mInvalidatedOnAnyThread; Mode mMode; @@ -3248,6 +3284,21 @@ public: return mDatabase; } + DatabaseLoggingInfo* + GetLoggingInfo() const + { + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mDatabase); + + return mDatabase->GetLoggingInfo(); + } + + int64_t + LoggingSerialNumber() const + { + return mLoggingSerialNumber; + } + bool IsAborted() const { @@ -3297,8 +3348,7 @@ public: Invalidate(); protected: - TransactionBase(Database* aDatabase, - Mode aMode); + TransactionBase(Database* aDatabase, Mode aMode); virtual ~TransactionBase(); @@ -3420,13 +3470,7 @@ class TransactionBase::CommitOp MOZ_FINAL nsresult mResultCode; private: - CommitOp(TransactionBase* aTransaction, - nsresult aResultCode) - : mTransaction(aTransaction) - , mResultCode(aResultCode) - { - MOZ_ASSERT(aTransaction); - } + CommitOp(TransactionBase* aTransaction, nsresult aResultCode); ~CommitOp() { } @@ -3670,8 +3714,8 @@ class NormalTransaction MOZ_FINAL private: // This constructor is only called by Database. NormalTransaction(Database* aDatabase, - nsTArray>& aObjectStores, - TransactionBase::Mode aMode); + TransactionBase::Mode aMode, + nsTArray>& aObjectStores); // Reference counted. ~NormalTransaction() @@ -4133,9 +4177,11 @@ class OpenDatabaseOp::VersionChangeOp MOZ_FINAL uint64_t mPreviousVersion; private: - explicit VersionChangeOp(OpenDatabaseOp* aOpenDatabaseOp) + explicit + VersionChangeOp(OpenDatabaseOp* aOpenDatabaseOp) : TransactionDatabaseOperationBase( - aOpenDatabaseOp->mVersionChangeTransaction) + aOpenDatabaseOp->mVersionChangeTransaction, + aOpenDatabaseOp->LoggingSerialNumber()) , mOpenDatabaseOp(aOpenDatabaseOp) , mRequestedVersion(aOpenDatabaseOp->mRequestedVersion) , mPreviousVersion(aOpenDatabaseOp->mMetadata->mCommonMetadata.version()) @@ -4214,8 +4260,11 @@ class DeleteDatabaseOp::VersionChangeOp MOZ_FINAL nsRefPtr mDeleteDatabaseOp; private: - explicit VersionChangeOp(DeleteDatabaseOp* aDeleteDatabaseOp) - : mDeleteDatabaseOp(aDeleteDatabaseOp) + explicit + VersionChangeOp(DeleteDatabaseOp* aDeleteDatabaseOp) + : DatabaseOperationBase(aDeleteDatabaseOp->BackgroundChildLoggingId(), + aDeleteDatabaseOp->LoggingSerialNumber()) + , mDeleteDatabaseOp(aDeleteDatabaseOp) { MOZ_ASSERT(aDeleteDatabaseOp); MOZ_ASSERT(!aDeleteDatabaseOp->mDatabaseDirectoryPath.IsEmpty()); @@ -4991,7 +5040,7 @@ private: * Other class declarations ******************************************************************************/ -struct DatabaseActorInfo +struct DatabaseActorInfo MOZ_FINAL { friend class nsAutoPtr; @@ -5021,6 +5070,60 @@ private: } }; +class DatabaseLoggingInfo MOZ_FINAL +{ +#ifdef DEBUG + // Just for potential warnings. + friend class Factory; +#endif + + LoggingInfo mLoggingInfo; + +public: + DatabaseLoggingInfo(const LoggingInfo& aLoggingInfo) + : mLoggingInfo(aLoggingInfo) + { + AssertIsOnBackgroundThread(); + } + + const nsID& + Id() const + { + AssertIsOnBackgroundThread(); + + return mLoggingInfo.backgroundChildLoggingId(); + } + + int64_t + NextTransactionSN(IDBTransaction::Mode aMode) + { + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mLoggingInfo.nextTransactionSerialNumber() < INT64_MAX); + MOZ_ASSERT(mLoggingInfo.nextVersionChangeTransactionSerialNumber() > + INT64_MIN); + + if (aMode == IDBTransaction::VERSION_CHANGE) { + return mLoggingInfo.nextVersionChangeTransactionSerialNumber()--; + } + + return mLoggingInfo.nextTransactionSerialNumber()++; + } + + uint64_t + NextRequestSN() + { + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mLoggingInfo.nextRequestSerialNumber() < UINT64_MAX); + + return mLoggingInfo.nextRequestSerialNumber()++; + } + + NS_INLINE_DECL_REFCOUNTING(DatabaseLoggingInfo) + +private: + ~DatabaseLoggingInfo(); +}; + class NonMainThreadHackBlobImpl MOZ_FINAL : public FileImplFile { @@ -5524,6 +5627,11 @@ StaticRefPtr gStartTransactionRunnable; StaticRefPtr gTransactionThreadPool; +typedef nsDataHashtable + DatabaseLoggingInfoHashtable; + +StaticAutoPtr gLoggingInfoHashtable; + #ifdef DEBUG StaticRefPtr gDEBUGThreadSlower; @@ -5537,7 +5645,7 @@ StaticRefPtr gDEBUGThreadSlower; ******************************************************************************/ PBackgroundIDBFactoryParent* -AllocPBackgroundIDBFactoryParent() +AllocPBackgroundIDBFactoryParent(const LoggingInfo& aLoggingInfo) { AssertIsOnBackgroundThread(); @@ -5545,12 +5653,15 @@ AllocPBackgroundIDBFactoryParent() return nullptr; } - nsRefPtr actor = Factory::Create(); + nsRefPtr actor = Factory::Create(aLoggingInfo); + MOZ_ASSERT(actor); + return actor.forget().take(); } bool -RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor) +RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor, + const LoggingInfo& /* aLoggingInfo */) { AssertIsOnBackgroundThread(); MOZ_ASSERT(aActor); @@ -5727,14 +5838,29 @@ FullDatabaseMetadata::Duplicate() const return newMetadata.forget(); } +DatabaseLoggingInfo::~DatabaseLoggingInfo() +{ + AssertIsOnBackgroundThread(); + + if (gLoggingInfoHashtable) { + const nsID& backgroundChildLoggingId = + mLoggingInfo.backgroundChildLoggingId(); + + MOZ_ASSERT(gLoggingInfoHashtable->Get(backgroundChildLoggingId) == this); + + gLoggingInfoHashtable->Remove(backgroundChildLoggingId); + } +} + /******************************************************************************* * Factory ******************************************************************************/ uint64_t Factory::sFactoryInstanceCount = 0; -Factory::Factory() - : mActorDestroyed(false) +Factory::Factory(already_AddRefed aLoggingInfo) + : mLoggingInfo(Move(aLoggingInfo)) + , mActorDestroyed(false) { AssertIsOnBackgroundThread(); MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread()); @@ -5747,7 +5873,7 @@ Factory::~Factory() // static already_AddRefed -Factory::Create() +Factory::Create(const LoggingInfo& aLoggingInfo) { AssertIsOnBackgroundThread(); MOZ_ASSERT(!QuotaClient::IsShuttingDownOnNonMainThread()); @@ -5770,6 +5896,9 @@ Factory::Create() MOZ_ASSERT(!gStartTransactionRunnable); gStartTransactionRunnable = new nsRunnable(); + MOZ_ASSERT(!gLoggingInfoHashtable); + gLoggingInfoHashtable = new DatabaseLoggingInfoHashtable(); + #ifdef DEBUG if (kDEBUGThreadPriority != nsISupportsPriority::PRIORITY_NORMAL) { NS_WARNING("PBackground thread debugging enabled, priority has been " @@ -5795,7 +5924,29 @@ Factory::Create() #endif // DEBUG } - nsRefPtr actor = new Factory(); + nsRefPtr loggingInfo = + gLoggingInfoHashtable->Get(aLoggingInfo.backgroundChildLoggingId()); + if (loggingInfo) { + MOZ_ASSERT(aLoggingInfo.backgroundChildLoggingId() == loggingInfo->Id()); +#if !DISABLE_ASSERTS_FOR_FUZZING + NS_WARN_IF_FALSE(aLoggingInfo.nextTransactionSerialNumber() == + loggingInfo->mLoggingInfo.nextTransactionSerialNumber(), + "NextTransactionSerialNumber doesn't match!"); + NS_WARN_IF_FALSE(aLoggingInfo.nextVersionChangeTransactionSerialNumber() == + loggingInfo->mLoggingInfo. + nextVersionChangeTransactionSerialNumber(), + "NextVersionChangeTransactionSerialNumber doesn't match!"); + NS_WARN_IF_FALSE(aLoggingInfo.nextRequestSerialNumber() == + loggingInfo->mLoggingInfo.nextRequestSerialNumber(), + "NextRequestSerialNumber doesn't match!"); +#endif // !DISABLE_ASSERTS_FOR_FUZZING + } else { + loggingInfo = new DatabaseLoggingInfo(aLoggingInfo); + gLoggingInfoHashtable->Put(aLoggingInfo.backgroundChildLoggingId(), + loggingInfo); + } + + nsRefPtr actor = new Factory(loggingInfo.forget()); sFactoryInstanceCount++; @@ -5812,6 +5963,9 @@ Factory::ActorDestroy(ActorDestroyReason aWhy) // Clean up if there are no more instances. if (!(--sFactoryInstanceCount)) { + MOZ_ASSERT(gLoggingInfoHashtable); + gLoggingInfoHashtable = nullptr; + MOZ_ASSERT(gStartTransactionRunnable); gStartTransactionRunnable = nullptr; @@ -5853,6 +6007,16 @@ Factory::RecvDeleteMe() return PBackgroundIDBFactoryParent::Send__delete__(this); } +bool +Factory::RecvIncrementLoggingRequestSerialNumber() +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(mLoggingInfo); + + mLoggingInfo->NextRequestSN(); + return true; +} + PBackgroundIDBFactoryRequestParent* Factory::AllocPBackgroundIDBFactoryRequestParent( const FactoryRequestParams& aParams) @@ -6077,7 +6241,7 @@ Database::Invalidate() mInvalidated = true; - if (!mActorDestroyed) { + if (mActorWasAlive && !mActorDestroyed) { unused << SendInvalidate(); } @@ -6329,6 +6493,15 @@ Database::AllocPBackgroundIDBTransactionParent( for (uint32_t nameIndex = 0; nameIndex < nameCount; nameIndex++) { const nsString& name = aObjectStoreNames[nameIndex]; + + if (nameIndex) { + // Make sure that this name is sorted properly and not a duplicate. + if (NS_WARN_IF(name <= aObjectStoreNames[nameIndex - 1])) { + ASSERT_UNLESS_FUZZING(); + return nullptr; + } + } + const uint32_t oldLength = fallibleObjectStores.Length(); Closure closure(name, fallibleObjectStores); @@ -6343,7 +6516,7 @@ Database::AllocPBackgroundIDBTransactionParent( infallibleObjectStores.SwapElements(fallibleObjectStores); nsRefPtr transaction = - new NormalTransaction(this, infallibleObjectStores, aMode); + new NormalTransaction(this, aMode, infallibleObjectStores); MOZ_ASSERT(infallibleObjectStores.IsEmpty()); @@ -6372,13 +6545,13 @@ Database::RecvPBackgroundIDBTransactionConstructor( auto* transaction = static_cast(aActor); // Add a placeholder for this transaction immediately. - gTransactionThreadPool->Dispatch(transaction->TransactionId(), - mMetadata->mDatabaseId, - aObjectStoreNames, - aMode, - gStartTransactionRunnable, - /* aFinish */ false, - /* aFinishCallback */ nullptr); + gTransactionThreadPool->Start(transaction->TransactionId(), + mMetadata->mDatabaseId, + aObjectStoreNames, + aMode, + GetLoggingInfo()->Id(), + transaction->LoggingSerialNumber(), + gStartTransactionRunnable); transaction->SetActive(); @@ -6472,11 +6645,11 @@ Database::RecvClose() * TransactionBase ******************************************************************************/ -TransactionBase::TransactionBase(Database* aDatabase, - Mode aMode) +TransactionBase::TransactionBase(Database* aDatabase, Mode aMode) : mDatabase(aDatabase) , mTransactionId(gTransactionThreadPool->NextTransactionId()) , mDatabaseId(aDatabase->Id()) + , mLoggingSerialNumber(aDatabase->GetLoggingInfo()->NextTransactionSN(aMode)) , mActiveRequestCount(0) , mInvalidatedOnAnyThread(false) , mMode(aMode) @@ -6492,6 +6665,8 @@ TransactionBase::TransactionBase(Database* aDatabase, { AssertIsOnBackgroundThread(); MOZ_ASSERT(aDatabase); + MOZ_ASSERT(mTransactionId); + MOZ_ASSERT(mLoggingSerialNumber); } TransactionBase::~TransactionBase() @@ -7621,8 +7796,8 @@ TransactionBase::ReleaseBackgroundThreadObjects() NormalTransaction::NormalTransaction( Database* aDatabase, - nsTArray>& aObjectStores, - TransactionBase::Mode aMode) + TransactionBase::Mode aMode, + nsTArray>& aObjectStores) : TransactionBase(aDatabase, aMode) { AssertIsOnBackgroundThread(); @@ -9919,8 +10094,6 @@ DatabaseOfflineStorage::Invalidate() NS_IMPL_ISUPPORTS(CompressDataBlobsFunction, mozIStorageFunction) NS_IMPL_ISUPPORTS(EncodeKeysFunction, mozIStorageFunction) -uint64_t DatabaseOperationBase::sNextSerialNumber = 0; - // static void DatabaseOperationBase::GetBindingClauseForKeyRange( @@ -10329,7 +10502,9 @@ FactoryOp::FactoryOp(Factory* aFactory, already_AddRefed aContentParent, const CommonFactoryRequestParams& aCommonParams, bool aDeleting) - : mFactory(aFactory) + : DatabaseOperationBase(aFactory->GetLoggingInfo()->Id(), + aFactory->GetLoggingInfo()->NextRequestSN()) + , mFactory(aFactory) , mContentParent(Move(aContentParent)) , mCommonParams(aCommonParams) , mState(State_Initial) @@ -11076,7 +11251,7 @@ OpenDatabaseOp::DoDatabaseWork() MOZ_ASSERT(mState == State_DatabaseWorkOpen); PROFILER_LABEL("IndexedDB", - "OpenDatabaseHelper::DoDatabaseWork", + "OpenDatabaseOp::DoDatabaseWork", js::ProfileEntry::Category::STORAGE); if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonMainThread()) || @@ -11649,6 +11824,8 @@ OpenDatabaseOp::DispatchToWorkThread() AssertIsOnOwningThread(); MOZ_ASSERT(mState == State_WaitingForTransactionsToComplete); MOZ_ASSERT(mVersionChangeTransaction); + MOZ_ASSERT(mVersionChangeTransaction->GetMode() == + IDBTransaction::VERSION_CHANGE); MOZ_ASSERT(mMaybeBlockedDatabases.IsEmpty()); if (IsActorDestroyed()) { @@ -11661,15 +11838,20 @@ OpenDatabaseOp::DispatchToWorkThread() // Intentionally empty. nsTArray objectStoreNames; + const int64_t loggingSerialNumber = + mVersionChangeTransaction->LoggingSerialNumber(); + const nsID& backgroundChildLoggingId = + mVersionChangeTransaction->GetLoggingInfo()->Id(); + nsRefPtr versionChangeOp = new VersionChangeOp(this); - gTransactionThreadPool->Dispatch(mVersionChangeTransaction->TransactionId(), - mVersionChangeTransaction->DatabaseId(), - objectStoreNames, - mVersionChangeTransaction->GetMode(), - versionChangeOp, - /* aFinish */ false, - /* aFinishCallback */ nullptr); + gTransactionThreadPool->Start(mVersionChangeTransaction->TransactionId(), + mVersionChangeTransaction->DatabaseId(), + objectStoreNames, + mVersionChangeTransaction->GetMode(), + backgroundChildLoggingId, + loggingSerialNumber, + versionChangeOp); mVersionChangeTransaction->SetActive(); @@ -12109,7 +12291,7 @@ VersionChangeOp::DoDatabaseWork(TransactionBase* aTransaction) } PROFILER_LABEL("IndexedDB", - "VersionChangeOp::DoDatabaseWork", + "OpenDatabaseOp::VersionChangeOp::DoDatabaseWork", js::ProfileEntry::Category::STORAGE); mozIStorageConnection* connection = aTransaction->Connection(); @@ -12797,10 +12979,27 @@ VersionChangeOp::Run() TransactionDatabaseOperationBase::TransactionDatabaseOperationBase( TransactionBase* aTransaction) - : mTransaction(aTransaction) + : DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(), + aTransaction->GetLoggingInfo()->NextRequestSN()) + , mTransaction(aTransaction) + , mTransactionLoggingSerialNumber(aTransaction->LoggingSerialNumber()) , mTransactionIsAborted(aTransaction->IsAborted()) { MOZ_ASSERT(aTransaction); + MOZ_ASSERT(LoggingSerialNumber()); +} + +TransactionDatabaseOperationBase::TransactionDatabaseOperationBase( + TransactionBase* aTransaction, + uint64_t aLoggingSerialNumber) + : DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(), + aLoggingSerialNumber) + , mTransaction(aTransaction) + , mTransactionLoggingSerialNumber(aTransaction->LoggingSerialNumber()) + , mTransactionIsAborted(aTransaction->IsAborted()) +{ + MOZ_ASSERT(aTransaction); + MOZ_ASSERT(LoggingSerialNumber()); } TransactionDatabaseOperationBase::~TransactionDatabaseOperationBase() @@ -12842,6 +13041,10 @@ TransactionDatabaseOperationBase::RunOnTransactionThread() MOZ_ASSERT(mTransaction); MOZ_ASSERT(NS_SUCCEEDED(mResultCode)); + PROFILER_LABEL("IndexedDB", + "TransactionDatabaseOperationBase::RunOnTransactionThread", + js::ProfileEntry::Category::STORAGE); + // There are several cases where we don't actually have to to any work here. if (mTransactionIsAborted) { @@ -12868,7 +13071,22 @@ TransactionDatabaseOperationBase::RunOnTransactionThread() if (NS_WARN_IF(NS_FAILED(rv))) { mResultCode = rv; } else { + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld] Request[%llu]: " + "Beginning database work", + "IndexedDB %s: P T[%lld] R[%llu]: DB Start", + IDB_LOG_ID_STRING(mBackgroundChildLoggingId), + mTransactionLoggingSerialNumber, + mLoggingSerialNumber); + rv = DoDatabaseWork(mTransaction); + + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld] Request[%llu]: " + "Finished database work", + "IndexedDB %s: P T[%lld] R[%llu]: DB End", + IDB_LOG_ID_STRING(mBackgroundChildLoggingId), + mTransactionLoggingSerialNumber, + mLoggingSerialNumber); + if (NS_FAILED(rv)) { mResultCode = rv; } @@ -12950,6 +13168,18 @@ TransactionDatabaseOperationBase::Run() return NS_OK; } +TransactionBase:: + +CommitOp::CommitOp(TransactionBase* aTransaction, nsresult aResultCode) + : DatabaseOperationBase(aTransaction->GetLoggingInfo()->Id(), + aTransaction->GetLoggingInfo()->NextRequestSN()) + , mTransaction(aTransaction) + , mResultCode(aResultCode) +{ + MOZ_ASSERT(aTransaction); + MOZ_ASSERT(LoggingSerialNumber()); +} + nsresult TransactionBase:: CommitOp::WriteAutoIncrementCounts() @@ -13055,6 +13285,13 @@ CommitOp::Run() AssertIsOnTransactionThread(); + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld] Request[%llu]: " + "Beginning database work", + "IndexedDB %s: P T[%lld] R[%llu]: DB Start", + IDB_LOG_ID_STRING(mBackgroundChildLoggingId), + mTransaction->LoggingSerialNumber(), + mLoggingSerialNumber); + if (NS_SUCCEEDED(mResultCode) && mTransaction->mUpdateFileRefcountFunction) { mResultCode = mTransaction-> mUpdateFileRefcountFunction->WillCommit(connection); @@ -13095,6 +13332,13 @@ CommitOp::Run() mTransaction->ReleaseTransactionThreadObjects(); + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld] Request[%llu]: " + "Finished database work", + "IndexedDB %s: P T[%lld] R[%llu]: DB End", + IDB_LOG_ID_STRING(mBackgroundChildLoggingId), + mTransaction->LoggingSerialNumber(), + mLoggingSerialNumber); + return NS_OK; } @@ -13121,13 +13365,14 @@ CommitOp::TransactionFinishedAfterUnblock() AssertIsOnBackgroundThread(); MOZ_ASSERT(mTransaction); - PROFILER_LABEL("IndexedDB", - "CommitOp::TransactionFinishedAfterUnblock", - js::ProfileEntry::Category::STORAGE); - - IDB_PROFILER_MARK("IndexedDB Transaction %llu: Complete (rv = %lu)", - "IDBTransaction[%llu] MT Complete", - mTransaction->TransactionId(), mResultCode); + if (!mTransaction->IsActorDestroyed()) { + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld]: " + "Finished with result 0x%x", + "IndexedDB %s: P T[%lld]: Transaction finished (0x%x)", + IDB_LOG_ID_STRING(mTransaction->GetLoggingInfo()->Id()), + mTransaction->LoggingSerialNumber(), + mResultCode); + } mTransaction->ReleaseBackgroundThreadObjects(); @@ -16604,6 +16849,10 @@ OpenOp::DoDatabaseWork(TransactionBase* aTransaction) MOZ_ASSERT(mCursor->mKey.IsUnset()); MOZ_ASSERT(mCursor->mRangeKey.IsUnset()); + PROFILER_LABEL("IndexedDB", + "Cursor::OpenOp::DoDatabaseWork", + js::ProfileEntry::Category::STORAGE); + nsresult rv; switch (mCursor->mType) { diff --git a/dom/indexedDB/ActorsParent.h b/dom/indexedDB/ActorsParent.h index 75f1417f96d4..ad42be4ee930 100644 --- a/dom/indexedDB/ActorsParent.h +++ b/dom/indexedDB/ActorsParent.h @@ -7,6 +7,7 @@ template struct already_AddRefed; class nsCString; +struct nsID; class nsIPrincipal; class nsPIDOMWindow; @@ -23,14 +24,16 @@ class Client; namespace indexedDB { +class LoggingInfo; class PBackgroundIDBFactoryParent; class PIndexedDBPermissionRequestParent; PBackgroundIDBFactoryParent* -AllocPBackgroundIDBFactoryParent(); +AllocPBackgroundIDBFactoryParent(const LoggingInfo& aLoggingInfo); bool -RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor); +RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor, + const LoggingInfo& aLoggingInfo); bool DeallocPBackgroundIDBFactoryParent(PBackgroundIDBFactoryParent* aActor); diff --git a/dom/indexedDB/IDBCursor.cpp b/dom/indexedDB/IDBCursor.cpp index e12af8154b76..6e9842607f31 100644 --- a/dom/indexedDB/IDBCursor.cpp +++ b/dom/indexedDB/IDBCursor.cpp @@ -426,36 +426,41 @@ IDBCursor::Continue(JSContext* aCx, } } + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + mRequest->SetLoggingSerialNumber(requestSerialNumber); + + if (mType == Type_ObjectStore || mType == Type_ObjectStoreKey) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "cursor(%s).continue(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.continue()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(mSourceObjectStore), + IDB_LOG_STRINGIFY(mDirection), + IDB_LOG_STRINGIFY(key)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "index(%s).cursor(%s).continue(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.continue()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(mSourceIndex->ObjectStore()), + IDB_LOG_STRINGIFY(mSourceIndex), + IDB_LOG_STRINGIFY(mDirection), + IDB_LOG_STRINGIFY(key)); + } + mBackgroundActor->SendContinueInternal(ContinueParams(key)); mContinueCalled = true; - -#ifdef IDB_PROFILER_USE_MARKS - if (mType == Type_ObjectStore || mType == Type_ObjectStoreKey) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).cursor(%s)." - "continue(%s)", - "IDBRequest[%llu] MT IDBCursor.continue()", - Request()->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(mSourceObjectStore), - IDB_PROFILER_STRING(mDirection), - key.IsUnset() ? "" : IDB_PROFILER_STRING(key)); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).index(%s)." - "cursor(%s).continue(%s)", - "IDBRequest[%llu] MT IDBCursor.continue()", - Request()->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(mSourceIndex->ObjectStore()), - IDB_PROFILER_STRING(mSourceIndex), - IDB_PROFILER_STRING(mDirection), - key.IsUnset() ? "" : IDB_PROFILER_STRING(key)); - } -#endif } void @@ -478,36 +483,41 @@ IDBCursor::Advance(uint32_t aCount, ErrorResult &aRv) return; } + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + mRequest->SetLoggingSerialNumber(requestSerialNumber); + + if (mType == Type_ObjectStore || mType == Type_ObjectStoreKey) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "cursor(%s).advance(%ld)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.advance()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(mSourceObjectStore), + IDB_LOG_STRINGIFY(mDirection), + aCount); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "index(%s).cursor(%s).advance(%ld)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.advance()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(mSourceIndex->ObjectStore()), + IDB_LOG_STRINGIFY(mSourceIndex), + IDB_LOG_STRINGIFY(mDirection), + aCount); + } + mBackgroundActor->SendContinueInternal(AdvanceParams(aCount)); mContinueCalled = true; - -#ifdef IDB_PROFILER_USE_MARKS - { - if (mType == Type_ObjectStore || mType == Type_ObjectStoreKey) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "cursor(%s).advance(%ld)", - "IDBRequest[%llu] MT IDBCursor.advance()", - Request()->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(mSourceObjectStore), - IDB_PROFILER_STRING(mDirection), aCount); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "index(%s).cursor(%s).advance(%ld)", - "IDBRequest[%llu] MT IDBCursor.advance()", - Request()->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(mSourceIndex->ObjectStore()), - IDB_PROFILER_STRING(mSourceIndex), - IDB_PROFILER_STRING(mDirection), aCount); - } - } -#endif } already_AddRefed @@ -563,7 +573,12 @@ IDBCursor::Update(JSContext* aCx, JS::Handle aValue, return nullptr; } - request = objectStore->Put(aCx, aValue, JS::UndefinedHandleValue, aRv); + request = objectStore->AddOrPut(aCx, + aValue, + /* aKey */ JS::UndefinedHandleValue, + /* aOverwrite */ true, + /* aFromCursor */ true, + aRv); if (aRv.Failed()) { return nullptr; } @@ -575,7 +590,12 @@ IDBCursor::Update(JSContext* aCx, JS::Handle aValue, return nullptr; } - request = objectStore->Put(aCx, aValue, keyVal, aRv); + request = objectStore->AddOrPut(aCx, + aValue, + keyVal, + /* aOverwrite */ true, + /* aFromCursor */ true, + aRv); if (aRv.Failed()) { return nullptr; } @@ -583,37 +603,34 @@ IDBCursor::Update(JSContext* aCx, JS::Handle aValue, request->SetSource(this); -#ifdef IDB_PROFILER_USE_MARKS - { - uint64_t requestSerial = request->GetSerialNumber(); - if (mType == Type_ObjectStore) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "cursor(%s).update(%s)", - "IDBRequest[%llu] MT IDBCursor.update()", - requestSerial, - IDB_PROFILER_STRING(mTransaction->Database()), - IDB_PROFILER_STRING(mTransaction), - IDB_PROFILER_STRING(objectStore), - IDB_PROFILER_STRING(mDirection), - mObjectStore->HasValidKeyPath() ? "" : - IDB_PROFILER_STRING(primaryKey)); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "index(%s).cursor(%s).update(%s)", - "IDBRequest[%llu] MT IDBCursor.update()", - requestSerial, - IDB_PROFILER_STRING(mTransaction->Database()), - IDB_PROFILER_STRING(mTransaction), - IDB_PROFILER_STRING(objectStore), - IDB_PROFILER_STRING(mSourceIndex), - IDB_PROFILER_STRING(mDirection), - mObjectStore->HasValidKeyPath() ? "" : - IDB_PROFILER_STRING(primaryKey)); - } + if (mType == Type_ObjectStore) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "cursor(%s).update(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.update()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(objectStore), + IDB_LOG_STRINGIFY(mDirection), + IDB_LOG_STRINGIFY(objectStore, primaryKey)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "index(%s).cursor(%s).update(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.update()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(objectStore), + IDB_LOG_STRINGIFY(mSourceIndex), + IDB_LOG_STRINGIFY(mDirection), + IDB_LOG_STRINGIFY(objectStore, primaryKey)); } -#endif return request.forget(); } @@ -658,44 +675,42 @@ IDBCursor::Delete(JSContext* aCx, ErrorResult& aRv) return nullptr; } - nsRefPtr request = objectStore->Delete(aCx, key, aRv); + nsRefPtr request = + objectStore->DeleteInternal(aCx, key, /* aFromCursor */ true, aRv); if (aRv.Failed()) { return nullptr; } request->SetSource(this); -#ifdef IDB_PROFILER_USE_MARKS - { - uint64_t requestSerial = request->GetSerialNumber(); - if (mType == Type_ObjectStore) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "cursor(%s).delete(%s)", - "IDBRequest[%llu] MT IDBCursor.delete()", - requestSerial, - IDB_PROFILER_STRING(mTransaction->Database()), - IDB_PROFILER_STRING(mTransaction), - IDB_PROFILER_STRING(objectStore), - IDB_PROFILER_STRING(mDirection), - mObjectStore->HasValidKeyPath() ? "" : - IDB_PROFILER_STRING(primaryKey)); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "index(%s).cursor(%s).delete(%s)", - "IDBRequest[%llu] MT IDBCursor.delete()", - requestSerial, - IDB_PROFILER_STRING(mTransaction->Database()), - IDB_PROFILER_STRING(mTransaction), - IDB_PROFILER_STRING(objectStore), - IDB_PROFILER_STRING(mSourceIndex), - IDB_PROFILER_STRING(mDirection), - mObjectStore->HasValidKeyPath() ? "" : - IDB_PROFILER_STRING(primaryKey)); - } + if (mType == Type_ObjectStore) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "cursor(%s).delete(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.delete()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(objectStore), + IDB_LOG_STRINGIFY(mDirection), + IDB_LOG_STRINGIFY(objectStore, primaryKey)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "index(%s).cursor(%s).delete(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBCursor.delete()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(objectStore), + IDB_LOG_STRINGIFY(mSourceIndex), + IDB_LOG_STRINGIFY(mDirection), + IDB_LOG_STRINGIFY(objectStore, primaryKey)); } -#endif return request.forget(); } diff --git a/dom/indexedDB/IDBDatabase.cpp b/dom/indexedDB/IDBDatabase.cpp index 9c305c827c05..9cd86c7bc2a7 100644 --- a/dom/indexedDB/IDBDatabase.cpp +++ b/dom/indexedDB/IDBDatabase.cpp @@ -506,12 +506,20 @@ IDBDatabase::CreateObjectStore( transaction->CreateObjectStore(*newSpec); MOZ_ASSERT(objectStore); - IDB_PROFILER_MARK("IndexedDB Pseudo-request: " - "database(%s).transaction(%s).createObjectStore(%s)", - "MT IDBDatabase.createObjectStore()", - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aTransaction), - IDB_PROFILER_STRING(objectStore)); + // Don't do this in the macro because we always need to increment the serial + // number to keep in sync with the parent. + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).createObjectStore(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: " + "IDBDatabase.createObjectStore()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(objectStore)); return objectStore.forget(); } @@ -559,12 +567,20 @@ IDBDatabase::DeleteObjectStore(const nsAString& aName, ErrorResult& aRv) return; } - IDB_PROFILER_MARK("IndexedDB Pseudo-request: " - "database(%s).transaction(%s).deleteObjectStore(\"%s\")", - "MT IDBDatabase.deleteObjectStore()", - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(transaction), - NS_ConvertUTF16toUTF8(aName).get()); + // Don't do this in the macro because we always need to increment the serial + // number to keep in sync with the parent. + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).deleteObjectStore(\"%s\")", + "IndexedDB %s: C T[%lld] R[%llu]: " + "IDBDatabase.deleteObjectStore()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(transaction), + NS_ConvertUTF16toUTF8(aName).get()); } already_AddRefed @@ -669,6 +685,14 @@ IDBDatabase::Transaction(const Sequence& aStoreNames, BackgroundTransactionChild* actor = new BackgroundTransactionChild(transaction); + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld]: " + "database(%s).transaction(%s)", + "IndexedDB %s: C T[%lld]: IDBDatabase.transaction()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(transaction)); + MOZ_ALWAYS_TRUE( mBackgroundActor->SendPBackgroundIDBTransactionConstructor(actor, sortedStoreNames, @@ -676,11 +700,6 @@ IDBDatabase::Transaction(const Sequence& aStoreNames, transaction->SetBackgroundActor(actor); - IDB_PROFILER_MARK("IndexedDB Transaction %llu: database(%s).transaction(%s)", - "IDBTransaction[%llu] MT Started", - transaction->GetSerialNumber(), IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(transaction)); - return transaction.forget(); } @@ -722,6 +741,8 @@ IDBDatabase::CreateMutableFile(const nsAString& aName, type = aType.Value(); } + mFactory->IncrementParentLoggingRequestSerialNumber(); + aRv = CreateFileHelper::CreateAndDispatch(this, request, aName, type); if (NS_WARN_IF(aRv.Failed())) { return nullptr; diff --git a/dom/indexedDB/IDBFactory.cpp b/dom/indexedDB/IDBFactory.cpp index be9fccb8041b..2019b446f3c9 100644 --- a/dom/indexedDB/IDBFactory.cpp +++ b/dom/indexedDB/IDBFactory.cpp @@ -6,6 +6,7 @@ #include "IDBFactory.h" +#include "BackgroundChildImpl.h" #include "IDBRequest.h" #include "IndexedDatabaseManager.h" #include "mozilla/ErrorResult.h" @@ -21,7 +22,9 @@ #include "nsIIPCBackgroundChildCreateCallback.h" #include "nsILoadContext.h" #include "nsIPrincipal.h" +#include "nsIUUIDGenerator.h" #include "nsIWebNavigation.h" +#include "nsServiceManagerUtils.h" #include "ProfilerHelpers.h" #include "ReportInternalError.h" @@ -76,10 +79,14 @@ class IDBFactory::BackgroundCreateCallback MOZ_FINAL : public nsIIPCBackgroundChildCreateCallback { nsRefPtr mFactory; + LoggingInfo mLoggingInfo; public: - explicit BackgroundCreateCallback(IDBFactory* aFactory) - : mFactory(aFactory) + explicit + BackgroundCreateCallback(IDBFactory* aFactory, + const LoggingInfo& aLoggingInfo) + : mFactory(aFactory) + , mLoggingInfo(aLoggingInfo) { MOZ_ASSERT(aFactory); } @@ -306,6 +313,15 @@ IDBFactory::SetBackgroundActor(BackgroundFactoryChild* aBackgroundActor) mBackgroundActor = aBackgroundActor; } +void +IDBFactory::IncrementParentLoggingRequestSerialNumber() +{ + AssertIsOnOwningThread(); + MOZ_ASSERT(mBackgroundActor); + + mBackgroundActor->SendIncrementLoggingRequestSerialNumber(); +} + already_AddRefed IDBFactory::Open(const nsAString& aName, uint64_t aVersion, @@ -501,27 +517,44 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal, params = OpenDatabaseRequestParams(commonParams); } - if (!mBackgroundActor) { - // If another consumer has already created a background actor for this - // thread then we can start this request immediately. - if (PBackgroundChild* bgActor = BackgroundChild::GetForCurrentThread()) { - nsresult rv = BackgroundActorCreated(bgActor); - if (NS_WARN_IF(NS_FAILED(rv))) { - IDB_REPORT_INTERNAL_ERR(); - aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - return nullptr; - } - MOZ_ASSERT(mBackgroundActor); - } else if (mPendingRequests.IsEmpty()) { - // We need to start the sequence to create a background actor for this - // thread. - nsRefPtr cb = - new BackgroundCreateCallback(this); - if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) { - IDB_REPORT_INTERNAL_ERR(); - aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); - return nullptr; + if (!mBackgroundActor && mPendingRequests.IsEmpty()) { + // We need to start the sequence to create a background actor for this + // thread. + BackgroundChildImpl::ThreadLocal* threadLocal = + BackgroundChildImpl::GetThreadLocalForCurrentThread(); + + nsAutoPtr newIDBThreadLocal; + ThreadLocal* idbThreadLocal; + + if (threadLocal && threadLocal->mIndexedDBThreadLocal) { + idbThreadLocal = threadLocal->mIndexedDBThreadLocal; + } else { + nsCOMPtr uuidGen = + do_GetService("@mozilla.org/uuid-generator;1"); + MOZ_ASSERT(uuidGen); + + nsID id; + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(uuidGen->GenerateUUIDInPlace(&id))); + + newIDBThreadLocal = idbThreadLocal = new ThreadLocal(id); + } + + nsRefPtr cb = + new BackgroundCreateCallback(this, idbThreadLocal->GetLoggingInfo()); + if (NS_WARN_IF(!BackgroundChild::GetOrCreateForCurrentThread(cb))) { + IDB_REPORT_INTERNAL_ERR(); + aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + return nullptr; + } + + if (newIDBThreadLocal) { + if (!threadLocal) { + threadLocal = BackgroundChildImpl::GetThreadLocalForCurrentThread(); } + MOZ_ASSERT(threadLocal); + MOZ_ASSERT(!threadLocal->mIndexedDBThreadLocal); + + threadLocal->mIndexedDBThreadLocal = newIDBThreadLocal.forget(); } } @@ -550,6 +583,23 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal, MOZ_ASSERT(request); + if (aDeleting) { + IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " + "indexedDB.deleteDatabase(\"%s\")", + "IndexedDB %s: C R[%llu]: IDBFactory.deleteDatabase()", + IDB_LOG_ID_STRING(), + request->LoggingSerialNumber(), + NS_ConvertUTF16toUTF8(aName).get()); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Request[%llu]: " + "indexedDB.open(\"%s\", %s)", + "IndexedDB %s: C R[%llu]: IDBFactory.open()", + IDB_LOG_ID_STRING(), + request->LoggingSerialNumber(), + NS_ConvertUTF16toUTF8(aName).get(), + IDB_LOG_STRINGIFY(aVersion)); + } + // If we already have a background actor then we can start this request now. if (mBackgroundActor) { nsresult rv = InitiateRequest(request, params); @@ -562,27 +612,12 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal, mPendingRequests.AppendElement(new PendingRequestInfo(request, params)); } -#ifdef IDB_PROFILER_USE_MARKS - { - NS_ConvertUTF16toUTF8 profilerName(aName); - if (aDeleting) { - IDB_PROFILER_MARK("IndexedDB Request %llu: deleteDatabase(\"%s\")", - "MT IDBFactory.deleteDatabase()", - request->GetSerialNumber(), profilerName.get()); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: open(\"%s\", %lld)", - "MT IDBFactory.open()", - request->GetSerialNumber(), profilerName.get(), - aVersion); - } - } -#endif - return request.forget(); } nsresult -IDBFactory::BackgroundActorCreated(PBackgroundChild* aBackgroundActor) +IDBFactory::BackgroundActorCreated(PBackgroundChild* aBackgroundActor, + const LoggingInfo& aLoggingInfo) { MOZ_ASSERT(aBackgroundActor); MOZ_ASSERT(!mBackgroundActor); @@ -595,7 +630,8 @@ IDBFactory::BackgroundActorCreated(PBackgroundChild* aBackgroundActor) mBackgroundActor = static_cast( - aBackgroundActor->SendPBackgroundIDBFactoryConstructor(actor)); + aBackgroundActor->SendPBackgroundIDBFactoryConstructor(actor, + aLoggingInfo)); } if (NS_WARN_IF(!mBackgroundActor)) { @@ -735,7 +771,7 @@ IDBFactory::BackgroundCreateCallback::ActorCreated(PBackgroundChild* aActor) nsRefPtr factory; mFactory.swap(factory); - factory->BackgroundActorCreated(aActor); + factory->BackgroundActorCreated(aActor, mLoggingInfo); } void diff --git a/dom/indexedDB/IDBFactory.h b/dom/indexedDB/IDBFactory.h index b88d055195bd..d4f15ffe3f10 100644 --- a/dom/indexedDB/IDBFactory.h +++ b/dom/indexedDB/IDBFactory.h @@ -42,6 +42,7 @@ namespace indexedDB { class BackgroundFactoryChild; class FactoryRequestParams; class IDBOpenDBRequest; +class LoggingInfo; class IDBFactory MOZ_FINAL : public nsISupports @@ -112,6 +113,9 @@ public: mBackgroundActor = nullptr; } + void + IncrementParentLoggingRequestSerialNumber(); + nsPIDOMWindow* GetParentObject() const { @@ -208,7 +212,8 @@ private: ErrorResult& aRv); nsresult - BackgroundActorCreated(PBackgroundChild* aBackgroundActor); + BackgroundActorCreated(PBackgroundChild* aBackgroundActor, + const LoggingInfo& aLoggingInfo); void BackgroundActorFailed(); diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp index a8a3e74bc677..ff4af101379f 100644 --- a/dom/indexedDB/IDBIndex.cpp +++ b/dom/indexedDB/IDBIndex.cpp @@ -264,33 +264,38 @@ IDBIndex::GetInternal(bool aKeyOnly, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (aKeyOnly) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "getKey(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.getKey()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "get(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.get()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange)); + } + BackgroundRequestChild* actor = new BackgroundRequestChild(request); transaction->StartRequest(actor, params); - if (aKeyOnly) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).index(%s)." - "getKey(%s)", - "IDBRequest[%llu] MT IDBIndex.getKey()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(transaction->Database()), - IDB_PROFILER_STRING(transaction), - IDB_PROFILER_STRING(mObjectStore), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKey)); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).index(%s)." - "get(%s)", - "IDBRequest[%llu] MT IDBIndex.get()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(transaction->Database()), - IDB_PROFILER_STRING(transaction), - IDB_PROFILER_STRING(mObjectStore), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKey)); - } return request.forget(); } @@ -340,36 +345,40 @@ IDBIndex::GetAllInternal(bool aKeysOnly, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (aKeysOnly) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "getAllKeys(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.getAllKeys()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(aLimit)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "getAll(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.getAll()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(aLimit)); + } + BackgroundRequestChild* actor = new BackgroundRequestChild(request); transaction->StartRequest(actor, params); - if (aKeysOnly) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).index(%s)." - "getAllKeys(%s, %lu)", - "IDBRequest[%llu] MT IDBIndex.getAllKeys()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(transaction->Database()), - IDB_PROFILER_STRING(transaction), - IDB_PROFILER_STRING(mObjectStore), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKeyRange), - aLimit); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).index(%s)." - "getAll(%s, %lu)", - "IDBRequest[%llu] MT IDBIndex.getAll()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(transaction->Database()), - IDB_PROFILER_STRING(transaction), - IDB_PROFILER_STRING(mObjectStore), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKeyRange), - aLimit); - } - return request.forget(); } @@ -432,6 +441,37 @@ IDBIndex::OpenCursorInternal(bool aKeysOnly, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (aKeysOnly) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "openKeyCursor(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBIndex.openKeyCursor()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(direction)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "openCursor(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: " + "IDBObjectStore.openKeyCursor()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(direction)); + } + BackgroundCursorChild* actor = new BackgroundCursorChild(request, this, direction); @@ -474,21 +514,23 @@ IDBIndex::Count(JSContext* aCx, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).index(%s)." + "count(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.count()", + IDB_LOG_ID_STRING(), + transaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(transaction->Database()), + IDB_LOG_STRINGIFY(transaction), + IDB_LOG_STRINGIFY(mObjectStore), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange)); + BackgroundRequestChild* actor = new BackgroundRequestChild(request); transaction->StartRequest(actor, params); - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).index(%s)." - "count(%s)", - "IDBRequest[%llu] MT IDBObjectStore.count()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(transaction->Database()), - IDB_PROFILER_STRING(transaction), - IDB_PROFILER_STRING(mObjectStore), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKey)); - return request.forget(); } diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index 5d5410f9cfca..f8e35c101009 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -1143,10 +1143,12 @@ IDBObjectStore::AddOrPut(JSContext* aCx, JS::Handle aValue, JS::Handle aKey, bool aOverwrite, + bool aFromCursor, ErrorResult& aRv) { AssertIsOnOwningThread(); MOZ_ASSERT(aCx); + MOZ_ASSERT_IF(aFromCursor, aOverwrite); if (!mTransaction->IsOpen()) { aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR); @@ -1249,6 +1251,32 @@ IDBObjectStore::AddOrPut(JSContext* aCx, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (!aFromCursor) { + if (aOverwrite) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).put(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.put()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(key)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).add(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.add()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(key)); + } + } + BackgroundRequestChild* actor = new BackgroundRequestChild(request); mTransaction->StartRequest(actor, params); @@ -1261,28 +1289,6 @@ IDBObjectStore::AddOrPut(JSContext* aCx, MOZ_ASSERT(fileInfos.IsEmpty()); } -#ifdef IDB_PROFILER_USE_MARKS - if (aOverwrite) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).%s(%s)", - "IDBRequest[%llu] MT IDBObjectStore.put()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), - key.IsUnset() ? "" : IDB_PROFILER_STRING(key)); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).add(%s)", - "IDBRequest[%llu] MT IDBObjectStore.add()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), - key.IsUnset() ? "" : IDB_PROFILER_STRING(key)); - } -#endif - return request.forget(); } @@ -1329,36 +1335,38 @@ IDBObjectStore::GetAllInternal(bool aKeysOnly, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (aKeysOnly) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "getAllKeys(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.getAllKeys()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(aLimit)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "getAll(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.getAll()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(aLimit)); + } + BackgroundRequestChild* actor = new BackgroundRequestChild(request); mTransaction->StartRequest(actor, params); -#ifdef IDB_PROFILER_USE_MARKS - if (aKeysOnly) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "getAllKeys(%s, %lu)", - "IDBRequest[%llu] MT IDBObjectStore.getAllKeys()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKeyRange), - aLimit); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "getAll(%s, %lu)", - "IDBRequest[%llu] MT IDBObjectStore.getAll()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), - IDB_PROFILER_STRING(aKeyRange), - aLimit); - } -#endif - return request.forget(); } @@ -1383,18 +1391,20 @@ IDBObjectStore::Clear(ErrorResult& aRv) nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).clear()", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.clear()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this)); + BackgroundRequestChild* actor = new BackgroundRequestChild(request); mTransaction->StartRequest(actor, params); - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).clear()", - "IDBRequest[%llu] MT IDBObjectStore.clear()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this)); - return request.forget(); } @@ -1579,25 +1589,29 @@ IDBObjectStore::Get(JSContext* aCx, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).get(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.get()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange)); + BackgroundRequestChild* actor = new BackgroundRequestChild(request); mTransaction->StartRequest(actor, params); - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).get(%s)", - "IDBRequest[%llu] MT IDBObjectStore.get()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange)); - return request.forget(); } already_AddRefed -IDBObjectStore::Delete(JSContext* aCx, - JS::Handle aKey, - ErrorResult& aRv) +IDBObjectStore::DeleteInternal(JSContext* aCx, + JS::Handle aKey, + bool aFromCursor, + ErrorResult& aRv) { AssertIsOnOwningThread(); @@ -1630,18 +1644,23 @@ IDBObjectStore::Delete(JSContext* aCx, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (!aFromCursor) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).delete(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.delete()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange)); + } + BackgroundRequestChild* actor = new BackgroundRequestChild(request); mTransaction->StartRequest(actor, params); - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).delete(%s)", - "IDBRequest[%llu] MT IDBObjectStore.delete()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange)); - return request.forget(); } @@ -1748,13 +1767,20 @@ IDBObjectStore::CreateIndexInternal( mIndexes.AppendElement(index); - IDB_PROFILER_MARK("IndexedDB Pseudo-request: " - "database(%s).transaction(%s).objectStore(%s)." - "createIndex(%s)", - "MT IDBObjectStore.createIndex()", - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(index)); + // Don't do this in the macro because we always need to increment the serial + // number to keep in sync with the parent. + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).createIndex(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.createIndex()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(index)); return index.forget(); } @@ -1813,16 +1839,23 @@ IDBObjectStore::DeleteIndex(const nsAString& aName, ErrorResult& aRv) return; } - transaction->DeleteIndex(this, foundId); + // Don't do this in the macro because we always need to increment the serial + // number to keep in sync with the parent. + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); - IDB_PROFILER_MARK("IndexedDB Pseudo-request: " - "database(%s).transaction(%s).objectStore(%s)." - "deleteIndex(\"%s\")", - "MT IDBObjectStore.deleteIndex()", - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), - NS_ConvertUTF16toUTF8(aName).get()); + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "deleteIndex(\"%s\")", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.deleteIndex()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + requestSerialNumber, + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + NS_ConvertUTF16toUTF8(aName).get()); + + transaction->DeleteIndex(this, foundId); } already_AddRefed @@ -1855,18 +1888,21 @@ IDBObjectStore::Count(JSContext* aCx, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s).count(%s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.count()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange)); + BackgroundRequestChild* actor = new BackgroundRequestChild(request); mTransaction->StartRequest(actor, params); - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s).count(%s)", - "IDBRequest[%llu] MT IDBObjectStore.count()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange)); - return request.forget(); } @@ -1925,34 +1961,40 @@ IDBObjectStore::OpenCursorInternal(bool aKeysOnly, nsRefPtr request = GenerateRequest(this); MOZ_ASSERT(request); + if (aKeysOnly) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "openKeyCursor(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: " + "IDBObjectStore.openKeyCursor()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(direction)); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "database(%s).transaction(%s).objectStore(%s)." + "openCursor(%s, %s)", + "IndexedDB %s: C T[%lld] R[%llu]: IDBObjectStore.openCursor()", + IDB_LOG_ID_STRING(), + mTransaction->LoggingSerialNumber(), + request->LoggingSerialNumber(), + IDB_LOG_STRINGIFY(mTransaction->Database()), + IDB_LOG_STRINGIFY(mTransaction), + IDB_LOG_STRINGIFY(this), + IDB_LOG_STRINGIFY(keyRange), + IDB_LOG_STRINGIFY(direction)); + } + BackgroundCursorChild* actor = new BackgroundCursorChild(request, this, direction); mTransaction->OpenCursor(actor, params); -#ifdef IDB_PROFILER_USE_MARKS - if (aKeysOnly) { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "openKeyCursor(%s, %s)", - "IDBRequest[%llu] MT IDBObjectStore.openKeyCursor()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange), - IDB_PROFILER_STRING(direction)); - } else { - IDB_PROFILER_MARK("IndexedDB Request %llu: " - "database(%s).transaction(%s).objectStore(%s)." - "openCursor(%s, %s)", - "IDBRequest[%llu] MT IDBObjectStore.openKeyCursor()", - request->GetSerialNumber(), - IDB_PROFILER_STRING(Transaction()->Database()), - IDB_PROFILER_STRING(Transaction()), - IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange), - IDB_PROFILER_STRING(direction)); - } -#endif return request.forget(); } diff --git a/dom/indexedDB/IDBObjectStore.h b/dom/indexedDB/IDBObjectStore.h index ccb12baf0355..2e43b068f51f 100644 --- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -33,6 +33,7 @@ template class Sequence; namespace indexedDB { class FileManager; +class IDBCursor; class IDBKeyRange; class IDBRequest; class IDBTransaction; @@ -47,6 +48,9 @@ class IDBObjectStore MOZ_FINAL : public nsISupports , public nsWrapperCache { + // For AddOrPut() and DeleteInternal(). + friend class IDBCursor; + static const JSClass sDummyPropJSClass; nsRefPtr mTransaction; @@ -160,7 +164,7 @@ public: { AssertIsOnOwningThread(); - return AddOrPut(aCx, aValue, aKey, false, aRv); + return AddOrPut(aCx, aValue, aKey, false, /* aFromCursor */ false, aRv); } already_AddRefed @@ -171,11 +175,18 @@ public: { AssertIsOnOwningThread(); - return AddOrPut(aCx, aValue, aKey, true, aRv); + return AddOrPut(aCx, aValue, aKey, true, /* aFromCursor */ false, aRv); } already_AddRefed - Delete(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv); + Delete(JSContext* aCx, + JS::Handle aKey, + ErrorResult& aRv) + { + AssertIsOnOwningThread(); + + return DeleteInternal(aCx, aKey, /* aFromCursor */ false, aRv); + } already_AddRefed Get(JSContext* aCx, JS::Handle aKey, ErrorResult& aRv); @@ -286,8 +297,15 @@ private: JS::Handle aValue, JS::Handle aKey, bool aOverwrite, + bool aFromCursor, ErrorResult& aRv); + already_AddRefed + DeleteInternal(JSContext* aCx, + JS::Handle aKey, + bool aFromCursor, + ErrorResult& aRv); + already_AddRefed GetAllInternal(bool aKeysOnly, JSContext* aCx, diff --git a/dom/indexedDB/IDBRequest.cpp b/dom/indexedDB/IDBRequest.cpp index 388e8046131a..7ddd08d4b992 100644 --- a/dom/indexedDB/IDBRequest.cpp +++ b/dom/indexedDB/IDBRequest.cpp @@ -29,6 +29,9 @@ #include "nsString.h" #include "ReportInternalError.h" +// Include this last to avoid path problems on Windows. +#include "ActorsChild.h" + namespace mozilla { namespace dom { namespace indexedDB { @@ -75,19 +78,10 @@ IDBRequest::InitMembers() AssertIsOnOwningThread(); mResultVal.setUndefined(); + mLoggingSerialNumber = NextSerialNumber(); mErrorCode = NS_OK; mLineNo = 0; mHaveResultOrErrorCode = false; - -#ifdef MOZ_ENABLE_PROFILER_SPS - { - BackgroundChildImpl::ThreadLocal* threadLocal = - BackgroundChildImpl::GetThreadLocalForCurrentThread(); - MOZ_ASSERT(threadLocal); - - mSerialNumber = threadLocal->mNextRequestSerialNumber++; - } -#endif } // static @@ -140,6 +134,28 @@ IDBRequest::Create(IDBIndex* aSourceAsIndex, } // static +uint64_t +IDBRequest::NextSerialNumber() +{ + BackgroundChildImpl::ThreadLocal* threadLocal = + BackgroundChildImpl::GetThreadLocalForCurrentThread(); + MOZ_ASSERT(threadLocal); + + ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal; + MOZ_ASSERT(idbThreadLocal); + + return idbThreadLocal->NextRequestSN(); +} + +void +IDBRequest::SetLoggingSerialNumber(uint64_t aLoggingSerialNumber) +{ + AssertIsOnOwningThread(); + MOZ_ASSERT(aLoggingSerialNumber > mLoggingSerialNumber); + + mLoggingSerialNumber = aLoggingSerialNumber; +} + void IDBRequest::CaptureCaller(nsAString& aFilename, uint32_t* aLineNo) { diff --git a/dom/indexedDB/IDBRequest.h b/dom/indexedDB/IDBRequest.h index 170dc0e25624..af3e1e929fdc 100644 --- a/dom/indexedDB/IDBRequest.h +++ b/dom/indexedDB/IDBRequest.h @@ -58,9 +58,7 @@ protected: nsRefPtr mError; nsString mFilename; -#ifdef MOZ_ENABLE_PROFILER_SPS - uint64_t mSerialNumber; -#endif + uint64_t mLoggingSerialNumber; nsresult mErrorCode; uint32_t mLineNo; bool mHaveResultOrErrorCode; @@ -84,6 +82,9 @@ public: static void CaptureCaller(nsAString& aFilename, uint32_t* aLineNo); + static uint64_t + NextSerialNumber(); + // nsIDOMEventTarget virtual nsresult PreHandleEvent(EventChainPreVisitor& aVisitor) MOZ_OVERRIDE; @@ -125,13 +126,16 @@ public: return !mHaveResultOrErrorCode; } -#ifdef MOZ_ENABLE_PROFILER_SPS uint64_t - GetSerialNumber() const + LoggingSerialNumber() const { - return mSerialNumber; + AssertIsOnOwningThread(); + + return mLoggingSerialNumber; } -#endif + + void + SetLoggingSerialNumber(uint64_t aLoggingSerialNumber); nsPIDOMWindow* GetParentObject() const diff --git a/dom/indexedDB/IDBTransaction.cpp b/dom/indexedDB/IDBTransaction.cpp index a914dc1b2f86..07c99596bbdb 100644 --- a/dom/indexedDB/IDBTransaction.cpp +++ b/dom/indexedDB/IDBTransaction.cpp @@ -32,6 +32,8 @@ namespace mozilla { namespace dom { namespace indexedDB { +using namespace mozilla::ipc; + namespace { NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); @@ -44,6 +46,7 @@ IDBTransaction::IDBTransaction(IDBDatabase* aDatabase, : IDBWrapperCache(aDatabase) , mDatabase(aDatabase) , mObjectStoreNames(aObjectStoreNames) + , mLoggingSerialNumber(0) , mNextObjectStoreId(0) , mNextIndexId(0) , mAbortCode(NS_OK) @@ -63,16 +66,15 @@ IDBTransaction::IDBTransaction(IDBDatabase* aDatabase, mBackgroundActor.mNormalBackgroundActor = nullptr; -#ifdef MOZ_ENABLE_PROFILER_SPS - { - using namespace mozilla::ipc; - BackgroundChildImpl::ThreadLocal* threadLocal = - BackgroundChildImpl::GetThreadLocalForCurrentThread(); - MOZ_ASSERT(threadLocal); + BackgroundChildImpl::ThreadLocal* threadLocal = + BackgroundChildImpl::GetThreadLocalForCurrentThread(); + MOZ_ASSERT(threadLocal); - mSerialNumber = threadLocal->mNextTransactionSerialNumber++; - } -#endif + ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal; + MOZ_ASSERT(idbThreadLocal); + + const_cast(mLoggingSerialNumber) = + idbThreadLocal->NextTransactionSN(aMode); #ifdef DEBUG if (!aObjectStoreNames.IsEmpty()) { @@ -111,13 +113,15 @@ IDBTransaction::~IDBTransaction() mDatabase->UnregisterTransaction(this); if (mMode == VERSION_CHANGE) { - if (mBackgroundActor.mVersionChangeBackgroundActor) { - mBackgroundActor.mVersionChangeBackgroundActor->SendDeleteMeInternal(); + if (auto* actor = mBackgroundActor.mVersionChangeBackgroundActor) { + actor->SendDeleteMeInternal(); + MOZ_ASSERT(!mBackgroundActor.mVersionChangeBackgroundActor, "SendDeleteMeInternal should have cleared!"); } - } else if (mBackgroundActor.mNormalBackgroundActor) { - mBackgroundActor.mNormalBackgroundActor->SendDeleteMeInternal(); + } else if (auto* actor = mBackgroundActor.mNormalBackgroundActor) { + actor->SendDeleteMeInternal(); + MOZ_ASSERT(!mBackgroundActor.mNormalBackgroundActor, "SendDeleteMeInternal should have cleared!"); } @@ -212,7 +216,10 @@ IDBTransaction::GetCurrent() BackgroundChildImpl::GetThreadLocalForCurrentThread(); MOZ_ASSERT(threadLocal); - return threadLocal->mCurrentTransaction; + ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal; + MOZ_ASSERT(idbThreadLocal); + + return idbThreadLocal->GetCurrentTransaction(); } #ifdef DEBUG @@ -339,6 +346,18 @@ IDBTransaction::SendCommit() MOZ_ASSERT(NS_SUCCEEDED(mAbortCode)); MOZ_ASSERT(IsFinished()); MOZ_ASSERT(!mSentCommitOrAbort); + MOZ_ASSERT(!mPendingRequestCount); + + // Don't do this in the macro because we always need to increment the serial + // number to keep in sync with the parent. + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "All requests complete, committing transaction", + "IndexedDB %s: C T[%lld] R[%llu]: IDBTransaction commit", + IDB_LOG_ID_STRING(), + LoggingSerialNumber(), + requestSerialNumber); if (mMode == VERSION_CHANGE) { MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor); @@ -361,6 +380,18 @@ IDBTransaction::SendAbort(nsresult aResultCode) MOZ_ASSERT(IsFinished()); MOZ_ASSERT(!mSentCommitOrAbort); + // Don't do this in the macro because we always need to increment the serial + // number to keep in sync with the parent. + const uint64_t requestSerialNumber = IDBRequest::NextSerialNumber(); + + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld] Request[%llu]: " + "Aborting transaction with result 0x%x", + "IndexedDB %s: C T[%lld] R[%llu]: IDBTransaction abort (0x%x)", + IDB_LOG_ID_STRING(), + LoggingSerialNumber(), + requestSerialNumber, + aResultCode); + if (mMode == VERSION_CHANGE) { MOZ_ASSERT(mBackgroundActor.mVersionChangeBackgroundActor); mBackgroundActor.mVersionChangeBackgroundActor->SendAbort(aResultCode); @@ -517,11 +548,14 @@ IDBTransaction::AbortInternal(nsresult aAbortCode, const bool isInvalidated = mDatabase->IsInvalidated(); bool needToSendAbort = mReadyState == INITIAL && !isInvalidated; -#ifdef DEBUG if (isInvalidated) { +#ifdef DEBUG mSentCommitOrAbort = true; - } #endif + // Increment the serial number counter here to account for the aborted + // transaction and keep the parent in sync. + IDBRequest::NextSerialNumber(); + } mAbortCode = aAbortCode; mReadyState = DONE; @@ -639,10 +673,6 @@ IDBTransaction::FireCompleteOrAbortEvents(nsresult aResult) AssertIsOnOwningThread(); MOZ_ASSERT(!mFiredCompleteOrAbort); - IDB_PROFILER_MARK("IndexedDB Transaction %llu: Complete (rv = %lu)", - "IDBTransaction[%llu] MT Complete", - mTransaction->GetSerialNumber(), mAbortCode); - mReadyState = DONE; #ifdef DEBUG @@ -670,6 +700,21 @@ IDBTransaction::FireCompleteOrAbortEvents(nsresult aResult) return; } + if (NS_SUCCEEDED(mAbortCode)) { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld]: " + "Firing 'complete' event", + "IndexedDB %s: C T[%lld]: IDBTransaction 'complete' event", + IDB_LOG_ID_STRING(), + mLoggingSerialNumber); + } else { + IDB_LOG_MARK("IndexedDB %s: Child Transaction[%lld]: " + "Firing 'abort' event with error 0x%x", + "IndexedDB %s: C T[%lld]: IDBTransaction 'abort' event (0x%x)", + IDB_LOG_ID_STRING(), + mLoggingSerialNumber, + mAbortCode); + } + bool dummy; if (NS_FAILED(DispatchEvent(event, &dummy))) { NS_WARNING("DispatchEvent failed!"); diff --git a/dom/indexedDB/IDBTransaction.h b/dom/indexedDB/IDBTransaction.h index 73771c4f37c3..07c2b9acc82e 100644 --- a/dom/indexedDB/IDBTransaction.h +++ b/dom/indexedDB/IDBTransaction.h @@ -83,15 +83,12 @@ private: BackgroundVersionChangeTransactionChild* mVersionChangeBackgroundActor; } mBackgroundActor; + const int64_t mLoggingSerialNumber; // Only used for VERSION_CHANGE transactions. int64_t mNextObjectStoreId; int64_t mNextIndexId; -#ifdef MOZ_ENABLE_PROFILER_SPS - uint64_t mSerialNumber; -#endif - nsresult mAbortCode; uint32_t mPendingRequestCount; @@ -245,14 +242,13 @@ public: void Abort(nsresult aAbortCode); -#ifdef MOZ_ENABLE_PROFILER_SPS - uint32_t - GetSerialNumber() const + int64_t + LoggingSerialNumber() const { AssertIsOnOwningThread(); - return mSerialNumber; + + return mLoggingSerialNumber; } -#endif nsPIDOMWindow* GetParentObject() const; diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 7d41156cd858..f3823a9bd0f5 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -32,11 +32,13 @@ #include "mozilla/storage.h" #include "nsContentUtils.h" #include "nsThreadUtils.h" +#include "prlog.h" #include "IDBEvents.h" #include "IDBFactory.h" #include "IDBKeyRange.h" #include "IDBRequest.h" +#include "ProfilerHelpers.h" // Bindings for ResolveConstructors #include "mozilla/dom/IDBCursorBinding.h" @@ -111,7 +113,22 @@ private: namespace { -const char kTestingPref[] = "dom.indexedDB.testing"; +#define IDB_PREF_BRANCH_ROOT "dom.indexedDB." + +const char kTestingPref[] = IDB_PREF_BRANCH_ROOT "testing"; + +#define IDB_PREF_LOGGING_BRANCH_ROOT IDB_PREF_BRANCH_ROOT "logging." + +const char kPrefLoggingEnabled[] = IDB_PREF_LOGGING_BRANCH_ROOT "enabled"; +const char kPrefLoggingDetails[] = IDB_PREF_LOGGING_BRANCH_ROOT "details"; + +#if defined(DEBUG) || defined(MOZ_ENABLE_PROFILER_SPS) +const char kPrefLoggingProfiler[] = + IDB_PREF_LOGGING_BRANCH_ROOT "profiler-marks"; +#endif + +#undef IDB_PREF_LOGGING_BRANCH_ROOT +#undef IDB_PREF_BRANCH_ROOT mozilla::StaticRefPtr gDBManager; @@ -205,6 +222,13 @@ IndexedDatabaseManager::~IndexedDatabaseManager() bool IndexedDatabaseManager::sIsMainProcess = false; bool IndexedDatabaseManager::sFullSynchronousMode = false; + +PRLogModuleInfo* IndexedDatabaseManager::sLoggingModule; + +Atomic + IndexedDatabaseManager::sLoggingMode( + IndexedDatabaseManager::Logging_Disabled); + mozilla::Atomic IndexedDatabaseManager::sLowDiskSpaceMode(false); // static @@ -221,6 +245,10 @@ IndexedDatabaseManager::GetOrCreate() if (!gDBManager) { sIsMainProcess = XRE_GetProcessType() == GeckoProcessType_Default; + if (!sLoggingModule) { + sLoggingModule = PR_NewLogModule("IndexedDB"); + } + if (sIsMainProcess && Preferences::GetBool("disk_space_watcher.enabled", false)) { // See if we're starting up in low disk space conditions. nsCOMPtr watcher = @@ -300,6 +328,15 @@ IndexedDatabaseManager::Init() // hit. sFullSynchronousMode = Preferences::GetBool("dom.indexedDB.fullSynchronous"); + Preferences::RegisterCallback(LoggingModePrefChangedCallback, + kPrefLoggingDetails); +#ifdef MOZ_ENABLE_PROFILER_SPS + Preferences::RegisterCallback(LoggingModePrefChangedCallback, + kPrefLoggingProfiler); +#endif + Preferences::RegisterCallbackAndCall(LoggingModePrefChangedCallback, + kPrefLoggingEnabled); + return NS_OK; } @@ -314,6 +351,15 @@ IndexedDatabaseManager::Destroy() Preferences::UnregisterCallback(TestingPrefChangedCallback, kTestingPref); + Preferences::UnregisterCallback(LoggingModePrefChangedCallback, + kPrefLoggingDetails); +#ifdef MOZ_ENABLE_PROFILER_SPS + Preferences::UnregisterCallback(LoggingModePrefChangedCallback, + kPrefLoggingProfiler); +#endif + Preferences::UnregisterCallback(LoggingModePrefChangedCallback, + kPrefLoggingEnabled); + delete this; } @@ -491,7 +537,30 @@ IndexedDatabaseManager::InLowDiskSpaceMode() "initialized!"); return sLowDiskSpaceMode; } -#endif + +// static +IndexedDatabaseManager::LoggingMode +IndexedDatabaseManager::GetLoggingMode() +{ + MOZ_ASSERT(gDBManager, + "GetLoggingMode called before IndexedDatabaseManager has been " + "initialized!"); + + return sLoggingMode; +} + +// static +PRLogModuleInfo* +IndexedDatabaseManager::GetLoggingModule() +{ + MOZ_ASSERT(gDBManager, + "GetLoggingModule called before IndexedDatabaseManager has been " + "initialized!"); + + return sLoggingModule; +} + +#endif // DEBUG // static bool @@ -687,6 +756,44 @@ IndexedDatabaseManager::BlockAndGetFileReferences( return NS_OK; } +// static +void +IndexedDatabaseManager::LoggingModePrefChangedCallback( + const char* /* aPrefName */, + void* /* aClosure */) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!Preferences::GetBool(kPrefLoggingEnabled)) { + sLoggingMode = Logging_Disabled; + return; + } + + bool useProfiler = +#if defined(DEBUG) || defined(MOZ_ENABLE_PROFILER_SPS) + Preferences::GetBool(kPrefLoggingProfiler); +#if !defined(MOZ_ENABLE_PROFILER_SPS) + if (useProfiler) { + NS_WARNING("IndexedDB cannot create profiler marks because this build does " + "not have profiler extensions enabled!"); + useProfiler = false; + } +#endif +#else + false; +#endif + + const bool logDetails = Preferences::GetBool(kPrefLoggingDetails); + + if (useProfiler) { + sLoggingMode = logDetails ? + Logging_DetailedProfilerMarks : + Logging_ConciseProfilerMarks; + } else { + sLoggingMode = logDetails ? Logging_Detailed : Logging_Concise; + } +} + NS_IMPL_ADDREF(IndexedDatabaseManager) NS_IMPL_RELEASE_WITH_DESTROY(IndexedDatabaseManager, Destroy()) NS_IMPL_QUERY_INTERFACE(IndexedDatabaseManager, nsIObserver) diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index 71bea9f7f786..6621b74a1b66 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -17,6 +17,7 @@ #include "nsHashKeys.h" class nsPIDOMWindow; +struct PRLogModuleInfo; namespace mozilla { @@ -36,6 +37,15 @@ class IndexedDatabaseManager MOZ_FINAL : public nsIObserver typedef mozilla::dom::quota::PersistenceType PersistenceType; public: + enum LoggingMode + { + Logging_Disabled = 0, + Logging_Concise, + Logging_Detailed, + Logging_ConciseProfilerMarks, + Logging_DetailedProfilerMarks + }; + NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER @@ -76,6 +86,26 @@ public: static bool FullSynchronous(); + static LoggingMode + GetLoggingMode() +#ifdef DEBUG + ; +#else + { + return sLoggingMode; + } +#endif + + static PRLogModuleInfo* + GetLoggingModule() +#ifdef DEBUG + ; +#else + { + return sLoggingModule; + } +#endif + already_AddRefed GetFileManager(PersistenceType aPersistenceType, const nsACString& aOrigin, @@ -143,6 +173,9 @@ private: void Destroy(); + static void + LoggingModePrefChangedCallback(const char* aPrefName, void* aClosure); + // Maintains a list of all file managers per origin. This list isn't // protected by any mutex but it is only ever touched on the IO thread. nsClassHashtable mFileManagerInfos; @@ -154,6 +187,8 @@ private: static bool sIsMainProcess; static bool sFullSynchronousMode; + static PRLogModuleInfo* sLoggingModule; + static Atomic sLoggingMode; static mozilla::Atomic sLowDiskSpaceMode; }; diff --git a/dom/indexedDB/PBackgroundIDBFactory.ipdl b/dom/indexedDB/PBackgroundIDBFactory.ipdl index 1fac81f93b16..b44eccf7dc83 100644 --- a/dom/indexedDB/PBackgroundIDBFactory.ipdl +++ b/dom/indexedDB/PBackgroundIDBFactory.ipdl @@ -51,6 +51,8 @@ parent: PBackgroundIDBFactoryRequest(FactoryRequestParams params); + IncrementLoggingRequestSerialNumber(); + child: __delete__(); diff --git a/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh b/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh index 5402b256f3de..58f9f42241c2 100644 --- a/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh +++ b/dom/indexedDB/PBackgroundIDBSharedTypes.ipdlh @@ -5,6 +5,8 @@ include protocol PBlob; include protocol PBackgroundIDBDatabaseFile; +include DOMTypes; + include "mozilla/dom/indexedDB/SerializationHelpers.h"; using struct mozilla::void_t @@ -253,6 +255,14 @@ union RequestParams IndexCountParams; }; +struct LoggingInfo +{ + nsID backgroundChildLoggingId; + int64_t nextTransactionSerialNumber; + int64_t nextVersionChangeTransactionSerialNumber; + uint64_t nextRequestSerialNumber; +}; + } // namespace indexedDB } // namespace dom } // namespace mozilla diff --git a/dom/indexedDB/ProfilerHelpers.h b/dom/indexedDB/ProfilerHelpers.h index 4afab8469c65..60356d2c7135 100644 --- a/dom/indexedDB/ProfilerHelpers.h +++ b/dom/indexedDB/ProfilerHelpers.h @@ -7,40 +7,76 @@ #ifndef mozilla_dom_indexeddb_profilerhelpers_h__ #define mozilla_dom_indexeddb_profilerhelpers_h__ +// This file is not exported and is only meant to be included in IndexedDB +// source files. + +#include "BackgroundChildImpl.h" #include "GeckoProfiler.h" - -// Uncomment this if you want IndexedDB operations to be marked in the profiler. -//#define IDB_PROFILER_USE_MARKS - -// Uncomment this if you want extended details to appear in profiler marks. -//#define IDB_PROFILER_MARK_DETAILS 0 - -// Sanity check the options above. -#if defined(IDB_PROFILER_USE_MARKS) && !defined(MOZ_ENABLE_PROFILER_SPS) -#error Cannot use IDB_PROFILER_USE_MARKS without MOZ_ENABLE_PROFILER_SPS! -#endif - -#if defined(IDB_PROFILER_MARK_DETAILS) && !defined(IDB_PROFILER_USE_MARKS) -#error Cannot use IDB_PROFILER_MARK_DETAILS without IDB_PROFILER_USE_MARKS! -#endif - -#ifdef IDB_PROFILER_USE_MARKS - -#ifdef IDB_PROFILER_MARK_DETAILS - #include "IDBCursor.h" #include "IDBDatabase.h" #include "IDBIndex.h" #include "IDBKeyRange.h" #include "IDBObjectStore.h" #include "IDBTransaction.h" +#include "IndexedDatabaseManager.h" #include "Key.h" +#include "mozilla/Assertions.h" +#include "mozilla/Attributes.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "nsDebug.h" +#include "nsID.h" +#include "nsIDOMEvent.h" +#include "nsString.h" +#include "prlog.h" + +// Include this last to avoid path problems on Windows. +#include "ActorsChild.h" namespace mozilla { namespace dom { namespace indexedDB { -class ProfilerString : public nsAutoCString +class MOZ_STACK_CLASS LoggingIdString MOZ_FINAL + : public nsAutoCString +{ +public: + LoggingIdString() + { + using mozilla::ipc::BackgroundChildImpl; + + BackgroundChildImpl::ThreadLocal* threadLocal = + BackgroundChildImpl::GetThreadLocalForCurrentThread(); + MOZ_ASSERT(threadLocal); + + ThreadLocal* idbThreadLocal = threadLocal->mIndexedDBThreadLocal; + MOZ_ASSERT(idbThreadLocal); + + Init(idbThreadLocal->Id()); + } + + explicit + LoggingIdString(const nsID& aID) + { + Init(aID); + } + +private: + void + Init(const nsID& aID) + { + static_assert(NSID_LENGTH > 1, "NSID_LENGTH is set incorrectly!"); + MOZ_ASSERT(Capacity() > NSID_LENGTH); + + // NSID_LENGTH counts the null terminator, SetLength() does not. + SetLength(NSID_LENGTH - 1); + + aID.ToProvidedString( + *reinterpret_cast(BeginWriting())); + } +}; + +class MOZ_STACK_CLASS LoggingString MOZ_FINAL + : public nsAutoCString { static const char kQuote = '\"'; static const char kOpenBracket = '['; @@ -50,20 +86,38 @@ class ProfilerString : public nsAutoCString public: explicit - ProfilerString(IDBDatabase* aDatabase) + LoggingString(IDBDatabase* aDatabase) + : nsAutoCString(kQuote) { MOZ_ASSERT(aDatabase); - Append(kQuote); AppendUTF16toUTF8(aDatabase->Name(), *this); Append(kQuote); } explicit - ProfilerString(IDBTransaction* aTransaction) + LoggingString(IDBTransaction* aTransaction) + : nsAutoCString(kOpenBracket) { MOZ_ASSERT(aTransaction); + NS_NAMED_LITERAL_CSTRING(kCommaSpace, ", "); + + const nsTArray& stores = aTransaction->ObjectStoreNamesInternal(); + + for (uint32_t count = stores.Length(), index = 0; index < count; index++) { + Append(kQuote); + AppendUTF16toUTF8(stores[index], *this); + Append(kQuote); + + if (index != count - 1) { + Append(kCommaSpace); + } + } + + Append(kCloseBracket); + Append(kCommaSpace); + switch (aTransaction->GetMode()) { case IDBTransaction::READ_ONLY: AppendLiteral("\"readonly\""); @@ -80,128 +134,198 @@ public: } explicit - ProfilerString(IDBObjectStore* aObjectStore) + LoggingString(IDBObjectStore* aObjectStore) + : nsAutoCString(kQuote) { MOZ_ASSERT(aObjectStore); - Append(kQuote); AppendUTF16toUTF8(aObjectStore->Name(), *this); Append(kQuote); } explicit - ProfilerString(IDBIndex* aIndex) + LoggingString(IDBIndex* aIndex) + : nsAutoCString(kQuote) { MOZ_ASSERT(aIndex); - Append(kQuote); AppendUTF16toUTF8(aIndex->Name(), *this); Append(kQuote); } explicit - ProfilerString(IDBKeyRange* aKeyRange) + LoggingString(IDBKeyRange* aKeyRange) { if (aKeyRange) { if (aKeyRange->IsOnly()) { - Append(ProfilerString(aKeyRange->Lower())); - } - else { - Append(aKeyRange->IsLowerOpen() ? kOpenParen : kOpenBracket); - Append(ProfilerString(aKeyRange->Lower())); + Assign(LoggingString(aKeyRange->Lower())); + } else { + Assign(aKeyRange->LowerOpen() ? kOpenParen : kOpenBracket); + Append(LoggingString(aKeyRange->Lower())); AppendLiteral(", "); - Append(ProfilerString(aKeyRange->Upper())); - Append(aKeyRange->IsUpperOpen() ? kCloseParen : kCloseBracket); + Append(LoggingString(aKeyRange->Upper())); + Append(aKeyRange->UpperOpen() ? kCloseParen : kCloseBracket); } + } else { + AssignLiteral(""); } } explicit - ProfilerString(const Key& aKey) + LoggingString(const Key& aKey) { if (aKey.IsUnset()) { - AssignLiteral("null"); - } - else if (aKey.IsFloat()) { + AssignLiteral(""); + } else if (aKey.IsFloat()) { AppendPrintf("%g", aKey.ToFloat()); - } - else if (aKey.IsDate()) { + } else if (aKey.IsDate()) { AppendPrintf("", aKey.ToDateMsec()); - } - else if (aKey.IsString()) { + } else if (aKey.IsString()) { nsAutoString str; aKey.ToString(str); AppendPrintf("\"%s\"", NS_ConvertUTF16toUTF8(str).get()); - } - else { + } else { MOZ_ASSERT(aKey.IsArray()); - AppendLiteral(""); + AssignLiteral("[...]"); } } explicit - ProfilerString(const IDBCursor::Direction aDirection) + LoggingString(const IDBCursor::Direction aDirection) { switch (aDirection) { case IDBCursor::NEXT: - AppendLiteral("\"next\""); + AssignLiteral("\"next\""); break; case IDBCursor::NEXT_UNIQUE: - AppendLiteral("\"nextunique\""); + AssignLiteral("\"nextunique\""); break; case IDBCursor::PREV: - AppendLiteral("\"prev\""); + AssignLiteral("\"prev\""); break; case IDBCursor::PREV_UNIQUE: - AppendLiteral("\"prevunique\""); + AssignLiteral("\"prevunique\""); break; default: MOZ_CRASH("Unknown direction!"); }; } + + explicit + LoggingString(const Optional& aVersion) + { + if (aVersion.WasPassed()) { + AppendInt(aVersion.Value()); + } else { + AssignLiteral(""); + } + } + + explicit + LoggingString(const Optional& aLimit) + { + if (aLimit.WasPassed()) { + AppendInt(aLimit.Value()); + } else { + AssignLiteral(""); + } + } + + LoggingString(IDBObjectStore* aObjectStore, const Key& aKey) + { + MOZ_ASSERT(aObjectStore); + + if (!aObjectStore->HasValidKeyPath()) { + Append(LoggingString(aKey)); + } + } + + LoggingString(nsIDOMEvent* aEvent, const char16_t* aDefault) + : nsAutoCString(kQuote) + { + MOZ_ASSERT(aDefault); + + nsString eventType; + + if (aEvent) { + MOZ_ALWAYS_TRUE(NS_SUCCEEDED(aEvent->GetType(eventType))); + } else { + eventType = nsDependentString(aDefault); + } + + AppendUTF16toUTF8(eventType, *this); + Append(kQuote); + } }; +inline void +LoggingHelper(bool aUseProfiler, const char* aFmt, ...) +{ + MOZ_ASSERT(IndexedDatabaseManager::GetLoggingMode() != + IndexedDatabaseManager::Logging_Disabled); + MOZ_ASSERT(aFmt); + + PRLogModuleInfo* logModule = IndexedDatabaseManager::GetLoggingModule(); + MOZ_ASSERT(logModule); + + static const PRLogModuleLevel logLevel = PR_LOG_DEBUG; + + if (PR_LOG_TEST(logModule, logLevel) || + (aUseProfiler && profiler_is_active())) { + nsAutoCString message; + + { + va_list args; + va_start(args, aFmt); + + message.AppendPrintf(aFmt, args); + + va_end(args); + } + + PR_LOG(logModule, logLevel, ("%s", message.get())); + + if (aUseProfiler) { + PROFILER_MARKER(message.get()); + } + } +} + } // namespace indexedDB } // namespace dom } // namespace mozilla -#define IDB_PROFILER_MARK(_detailedFmt, _conciseFmt, ...) \ +#define IDB_LOG_MARK(_detailedFmt, _conciseFmt, ...) \ do { \ - nsAutoCString _mark; \ - _mark.AppendPrintf(_detailedFmt, ##__VA_ARGS__); \ - PROFILER_MARKER(_mark.get()); \ - } while (0) - -#define IDB_PROFILER_STRING(_arg) \ - mozilla::dom::indexedDB::ProfilerString((_arg)).get() - -#else // IDB_PROFILER_MARK_DETAILS - -#define IDB_PROFILER_MARK(_detailedFmt, _conciseFmt, ...) \ - do { \ - nsAutoCString _mark; \ - _mark.AppendPrintf(_conciseFmt, ##__VA_ARGS__); \ - PROFILER_MARKER(_mark.get()); \ - } while (0) - -#define IDB_PROFILER_STRING(_arg) "" - -#endif // IDB_PROFILER_MARK_DETAILS - -#define IDB_PROFILER_MARK_IF(_cond, _detailedFmt, _conciseFmt, ...) \ - do { \ - if (_cond) { \ - IDB_PROFILER_MARK(_detailedFmt, _conciseFmt, __VA_ARGS__); \ + using namespace mozilla::dom::indexedDB; \ + \ + const IndexedDatabaseManager::LoggingMode mode = \ + IndexedDatabaseManager::GetLoggingMode(); \ + \ + if (mode != IndexedDatabaseManager::Logging_Disabled) { \ + const char* _fmt; \ + if (mode == IndexedDatabaseManager::Logging_Concise || \ + mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks) { \ + _fmt = _conciseFmt; \ + } else { \ + MOZ_ASSERT( \ + mode == IndexedDatabaseManager::Logging_Detailed || \ + mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks); \ + _fmt = _detailedFmt; \ + } \ + \ + const bool _useProfiler = \ + mode == IndexedDatabaseManager::Logging_ConciseProfilerMarks || \ + mode == IndexedDatabaseManager::Logging_DetailedProfilerMarks; \ + \ + LoggingHelper(_useProfiler, _fmt, ##__VA_ARGS__); \ } \ } while (0) -#else // IDB_PROFILER_USE_MARKS +#define IDB_LOG_ID_STRING(...) \ + mozilla::dom::indexedDB::LoggingIdString(__VA_ARGS__).get() -#define IDB_PROFILER_MARK(...) do { } while(0) -#define IDB_PROFILER_MARK_IF(_cond, ...) do { } while(0) -#define IDB_PROFILER_MARK2(_detailedFmt, _notdetailedFmt, ...) do { } while(0) -#define IDB_PROFILER_STRING(_arg) "" - -#endif // IDB_PROFILER_USE_MARKS +#define IDB_LOG_STRINGIFY(...) \ + mozilla::dom::indexedDB::LoggingString(__VA_ARGS__).get() #endif // mozilla_dom_indexeddb_profilerhelpers_h__ diff --git a/dom/indexedDB/TransactionThreadPool.cpp b/dom/indexedDB/TransactionThreadPool.cpp index f8af510471bf..3cd668b13dad 100644 --- a/dom/indexedDB/TransactionThreadPool.cpp +++ b/dom/indexedDB/TransactionThreadPool.cpp @@ -144,7 +144,9 @@ class TransactionThreadPool::TransactionQueue MOZ_FINAL Monitor mMonitor; nsRefPtr mOwningThreadPool; - uint64_t mTransactionId; + const uint64_t mTransactionId; + const nsID mBackgroundChildLoggingId; + const int64_t mLoggingSerialNumber; const nsCString mDatabaseId; const nsTArray mObjectStoreNames; uint16_t mMode; @@ -155,10 +157,12 @@ class TransactionThreadPool::TransactionQueue MOZ_FINAL public: TransactionQueue(TransactionThreadPool* aThreadPool, - uint64_t aTransactionId, - const nsACString& aDatabaseId, - const nsTArray& aObjectStoreNames, - uint16_t aMode); + uint64_t aTransactionId, + const nsACString& aDatabaseId, + const nsTArray& aObjectStoreNames, + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber); NS_DECL_ISUPPORTS_INHERITED @@ -187,13 +191,21 @@ struct TransactionThreadPool::TransactionInfo MOZ_FINAL uint64_t aTransactionId, const nsACString& aDatabaseId, const nsTArray& aObjectStoreNames, - uint16_t aMode) + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber) : transactionId(aTransactionId), databaseId(aDatabaseId) { MOZ_COUNT_CTOR(TransactionInfo); - queue = new TransactionQueue(aThreadPool, aTransactionId, aDatabaseId, - aObjectStoreNames, aMode); + queue = + new TransactionQueue(aThreadPool, + aTransactionId, + aDatabaseId, + aObjectStoreNames, + aMode, + aBackgroundChildLoggingId, + aLoggingSerialNumber); } ~TransactionInfo() @@ -302,7 +314,6 @@ TransactionThreadPool::Shutdown() } } -// static uint64_t TransactionThreadPool::NextTransactionId() { @@ -548,20 +559,17 @@ TransactionThreadPool::GetQueueForTransaction(uint64_t aTransactionId, } TransactionThreadPool::TransactionQueue& -TransactionThreadPool::GetQueueForTransaction( +TransactionThreadPool::CreateQueueForTransaction( uint64_t aTransactionId, const nsACString& aDatabaseId, const nsTArray& aObjectStoreNames, - uint16_t aMode) + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber) { AssertIsOnOwningThread(); MOZ_ASSERT(aTransactionId <= mNextTransactionId); - - TransactionQueue* existingQueue = - GetQueueForTransaction(aTransactionId, aDatabaseId); - if (existingQueue) { - return *existingQueue; - } + MOZ_ASSERT(!GetQueueForTransaction(aTransactionId, aDatabaseId)); // See if we can run this transaction now. DatabaseTransactionInfo* dbTransactionInfo; @@ -579,11 +587,14 @@ TransactionThreadPool::GetQueueForTransaction( return *info->queue; } - TransactionInfo* transactionInfo = new TransactionInfo(this, - aTransactionId, - aDatabaseId, - aObjectStoreNames, - aMode); + TransactionInfo* transactionInfo = + new TransactionInfo(this, + aTransactionId, + aDatabaseId, + aObjectStoreNames, + aMode, + aBackgroundChildLoggingId, + aLoggingSerialNumber); dbTransactionInfo->transactions.Put(aTransactionId, transactionInfo);; @@ -633,26 +644,27 @@ TransactionThreadPool::GetQueueForTransaction( } void -TransactionThreadPool::Dispatch(uint64_t aTransactionId, - const nsACString& aDatabaseId, - const nsTArray& aObjectStoreNames, - uint16_t aMode, - nsIRunnable* aRunnable, - bool aFinish, - FinishCallback* aFinishCallback) +TransactionThreadPool::Start(uint64_t aTransactionId, + const nsACString& aDatabaseId, + const nsTArray& aObjectStoreNames, + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber, + nsIRunnable* aRunnable) { + AssertIsOnOwningThread(); MOZ_ASSERT(aTransactionId <= mNextTransactionId); + MOZ_ASSERT(aRunnable); MOZ_ASSERT(!mShutdownRequested); - TransactionQueue& queue = GetQueueForTransaction(aTransactionId, - aDatabaseId, - aObjectStoreNames, - aMode); + TransactionQueue& queue = CreateQueueForTransaction(aTransactionId, + aDatabaseId, + aObjectStoreNames, + aMode, + aBackgroundChildLoggingId, + aLoggingSerialNumber); queue.Dispatch(aRunnable); - if (aFinish) { - queue.Finish(aFinishCallback); - } } void @@ -765,14 +777,18 @@ TransactionQueue::TransactionQueue(TransactionThreadPool* aThreadPool, uint64_t aTransactionId, const nsACString& aDatabaseId, const nsTArray& aObjectStoreNames, - uint16_t aMode) -: mMonitor("TransactionQueue::mMonitor"), - mOwningThreadPool(aThreadPool), - mTransactionId(aTransactionId), - mDatabaseId(aDatabaseId), - mObjectStoreNames(aObjectStoreNames), - mMode(aMode), - mShouldFinish(false) + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber) + : mMonitor("TransactionQueue::mMonitor") + , mOwningThreadPool(aThreadPool) + , mTransactionId(aTransactionId) + , mBackgroundChildLoggingId(aBackgroundChildLoggingId) + , mLoggingSerialNumber(aLoggingSerialNumber) + , mDatabaseId(aDatabaseId) + , mObjectStoreNames(aObjectStoreNames) + , mMode(aMode) + , mShouldFinish(false) { MOZ_ASSERT(aThreadPool); aThreadPool->AssertIsOnOwningThread(); @@ -824,9 +840,11 @@ TransactionThreadPool::TransactionQueue::Run() "TransactionThreadPool::TransactionQueue""Run", js::ProfileEntry::Category::STORAGE); - IDB_PROFILER_MARK("IndexedDB Transaction %llu: Beginning database work", - "IDBTransaction[%llu] DT Start", - mTransaction->GetSerialNumber()); + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld]: " + "Beginning database work", + "IndexedDB %s: P T[%lld]: DB Start", + IDB_LOG_ID_STRING(mBackgroundChildLoggingId), + mLoggingSerialNumber); nsAutoTArray, 10> queue; nsRefPtr finishCallback; @@ -877,9 +895,11 @@ TransactionThreadPool::TransactionQueue::Run() } #endif // DEBUG - IDB_PROFILER_MARK("IndexedDB Transaction %llu: Finished database work", - "IDBTransaction[%llu] DT Done", - mTransaction->GetSerialNumber()); + IDB_LOG_MARK("IndexedDB %s: Parent Transaction[%lld]: " + "Finished database work", + "IndexedDB %s: P T[%lld]: DB End", + IDB_LOG_ID_STRING(mBackgroundChildLoggingId), + mLoggingSerialNumber); nsRefPtr finishTransactionRunnable = new FinishTransactionRunnable(mOwningThreadPool.forget(), diff --git a/dom/indexedDB/TransactionThreadPool.h b/dom/indexedDB/TransactionThreadPool.h index 61c4fa0051e8..33c3c3e2d4c1 100644 --- a/dom/indexedDB/TransactionThreadPool.h +++ b/dom/indexedDB/TransactionThreadPool.h @@ -15,6 +15,7 @@ #include "nsISupportsImpl.h" #include "nsTArray.h" +struct nsID; class nsIEventTarget; class nsIRunnable; class nsIThreadPool; @@ -55,13 +56,13 @@ public: uint64_t NextTransactionId(); - void Dispatch(uint64_t aTransactionId, - const nsACString& aDatabaseId, - const nsTArray& aObjectStoreNames, - uint16_t aMode, - nsIRunnable* aRunnable, - bool aFinish, - FinishCallback* aFinishCallback); + void Start(uint64_t aTransactionId, + const nsACString& aDatabaseId, + const nsTArray& aObjectStoreNames, + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber, + nsIRunnable* aRunnable); void Dispatch(uint64_t aTransactionId, const nsACString& aDatabaseId, @@ -114,11 +115,13 @@ private: TransactionQueue* GetQueueForTransaction(uint64_t aTransactionId, const nsACString& aDatabaseId); - TransactionQueue& GetQueueForTransaction( + TransactionQueue& CreateQueueForTransaction( uint64_t aTransactionId, const nsACString& aDatabaseId, const nsTArray& aObjectStoreNames, - uint16_t aMode); + uint16_t aMode, + const nsID& aBackgroundChildLoggingId, + int64_t aLoggingSerialNumber); bool MaybeFireCallback(DatabasesCompleteCallback* aCallback); diff --git a/ipc/glue/BackgroundChildImpl.cpp b/ipc/glue/BackgroundChildImpl.cpp index 0a991a7c1f15..5a270e50fcc8 100644 --- a/ipc/glue/BackgroundChildImpl.cpp +++ b/ipc/glue/BackgroundChildImpl.cpp @@ -4,12 +4,14 @@ #include "BackgroundChildImpl.h" +#include "ActorsChild.h" // IndexedDB #include "FileDescriptorSetChild.h" #include "mozilla/Assertions.h" #include "mozilla/dom/PBlobChild.h" #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h" #include "mozilla/dom/ipc/BlobChild.h" #include "mozilla/ipc/PBackgroundTestChild.h" +#include "nsID.h" #include "nsTraceRefcnt.h" namespace { @@ -48,11 +50,6 @@ namespace ipc { BackgroundChildImpl:: ThreadLocal::ThreadLocal() - : mCurrentTransaction(nullptr) -#ifdef MOZ_ENABLE_PROFILER_SPS - , mNextTransactionSerialNumber(1) - , mNextRequestSerialNumber(1) -#endif { // May happen on any thread! MOZ_COUNT_CTOR(mozilla::ipc::BackgroundChildImpl::ThreadLocal); @@ -136,7 +133,8 @@ BackgroundChildImpl::DeallocPBackgroundTestChild(PBackgroundTestChild* aActor) } BackgroundChildImpl::PBackgroundIDBFactoryChild* -BackgroundChildImpl::AllocPBackgroundIDBFactoryChild() +BackgroundChildImpl::AllocPBackgroundIDBFactoryChild( + const LoggingInfo& aLoggingInfo) { MOZ_CRASH("PBackgroundIDBFactoryChild actors should be manually " "constructed!"); diff --git a/ipc/glue/BackgroundChildImpl.h b/ipc/glue/BackgroundChildImpl.h index afdb52e8993e..0fedb67944a2 100644 --- a/ipc/glue/BackgroundChildImpl.h +++ b/ipc/glue/BackgroundChildImpl.h @@ -7,14 +7,13 @@ #include "mozilla/Attributes.h" #include "mozilla/ipc/PBackgroundChild.h" - -template class nsAutoPtr; +#include "nsAutoPtr.h" namespace mozilla { namespace dom { namespace indexedDB { -class IDBTransaction; +class ThreadLocal; } // namespace indexedDB } // namespace dom @@ -53,7 +52,7 @@ protected: DeallocPBackgroundTestChild(PBackgroundTestChild* aActor) MOZ_OVERRIDE; virtual PBackgroundIDBFactoryChild* - AllocPBackgroundIDBFactoryChild() MOZ_OVERRIDE; + AllocPBackgroundIDBFactoryChild(const LoggingInfo& aLoggingInfo) MOZ_OVERRIDE; virtual bool DeallocPBackgroundIDBFactoryChild(PBackgroundIDBFactoryChild* aActor) @@ -78,12 +77,7 @@ class BackgroundChildImpl::ThreadLocal MOZ_FINAL friend class nsAutoPtr; public: - mozilla::dom::indexedDB::IDBTransaction* mCurrentTransaction; - -#ifdef MOZ_ENABLE_PROFILER_SPS - uint64_t mNextTransactionSerialNumber; - uint64_t mNextRequestSerialNumber; -#endif + nsAutoPtr mIndexedDBThreadLocal; public: ThreadLocal(); diff --git a/ipc/glue/BackgroundParentImpl.cpp b/ipc/glue/BackgroundParentImpl.cpp index 1dd7cbedb56f..0d5eeb2d5a35 100644 --- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -119,7 +119,8 @@ BackgroundParentImpl::DeallocPBackgroundTestParent( } auto -BackgroundParentImpl::AllocPBackgroundIDBFactoryParent() +BackgroundParentImpl::AllocPBackgroundIDBFactoryParent( + const LoggingInfo& aLoggingInfo) -> PBackgroundIDBFactoryParent* { using mozilla::dom::indexedDB::AllocPBackgroundIDBFactoryParent; @@ -127,12 +128,13 @@ BackgroundParentImpl::AllocPBackgroundIDBFactoryParent() AssertIsInMainProcess(); AssertIsOnBackgroundThread(); - return AllocPBackgroundIDBFactoryParent(); + return AllocPBackgroundIDBFactoryParent(aLoggingInfo); } bool BackgroundParentImpl::RecvPBackgroundIDBFactoryConstructor( - PBackgroundIDBFactoryParent* aActor) + PBackgroundIDBFactoryParent* aActor, + const LoggingInfo& aLoggingInfo) { using mozilla::dom::indexedDB::RecvPBackgroundIDBFactoryConstructor; @@ -140,18 +142,20 @@ BackgroundParentImpl::RecvPBackgroundIDBFactoryConstructor( AssertIsOnBackgroundThread(); MOZ_ASSERT(aActor); - return RecvPBackgroundIDBFactoryConstructor(aActor); + return RecvPBackgroundIDBFactoryConstructor(aActor, aLoggingInfo); } bool BackgroundParentImpl::DeallocPBackgroundIDBFactoryParent( PBackgroundIDBFactoryParent* aActor) { + using mozilla::dom::indexedDB::DeallocPBackgroundIDBFactoryParent; + AssertIsInMainProcess(); AssertIsOnBackgroundThread(); MOZ_ASSERT(aActor); - return mozilla::dom::indexedDB::DeallocPBackgroundIDBFactoryParent(aActor); + return DeallocPBackgroundIDBFactoryParent(aActor); } auto diff --git a/ipc/glue/BackgroundParentImpl.h b/ipc/glue/BackgroundParentImpl.h index ba9e78bd07ec..e0a6d7240e09 100644 --- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -33,10 +33,12 @@ protected: DeallocPBackgroundTestParent(PBackgroundTestParent* aActor) MOZ_OVERRIDE; virtual PBackgroundIDBFactoryParent* - AllocPBackgroundIDBFactoryParent() MOZ_OVERRIDE; + AllocPBackgroundIDBFactoryParent(const LoggingInfo& aLoggingInfo) + MOZ_OVERRIDE; virtual bool - RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor) + RecvPBackgroundIDBFactoryConstructor(PBackgroundIDBFactoryParent* aActor, + const LoggingInfo& aLoggingInfo) MOZ_OVERRIDE; virtual bool diff --git a/ipc/glue/PBackground.ipdl b/ipc/glue/PBackground.ipdl index 89756c3410aa..4f4a155589e2 100644 --- a/ipc/glue/PBackground.ipdl +++ b/ipc/glue/PBackground.ipdl @@ -8,6 +8,7 @@ include protocol PBlob; include protocol PFileDescriptorSet; include DOMTypes; +include PBackgroundIDBSharedTypes; namespace mozilla { namespace ipc { @@ -23,7 +24,7 @@ parent: // Only called at startup during mochitests to check the basic infrastructure. PBackgroundTest(nsCString testArg); - PBackgroundIDBFactory(); + PBackgroundIDBFactory(LoggingInfo loggingInfo); both: PBlob(BlobConstructorParams params); diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index b4e2b68ca377..6ea3abfd87b1 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -130,6 +130,7 @@ SOURCES += [ ] LOCAL_INCLUDES += [ + '/dom/indexedDB', '/xpcom/build', ] diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index c800658c83ef..a0e314b69e8b 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -119,6 +119,12 @@ pref("dom.indexedDB.enabled", true); pref("dom.indexedDB.warningQuota", 50); // Whether or not indexedDB experimental features are enabled. pref("dom.indexedDB.experimental", false); +// Enable indexedDB logging. +pref("dom.indexedDB.logging.enabled", true); +// Detailed output in log messages. +pref("dom.indexedDB.logging.details", true); +// Enable profiler marks for indexedDB events. +pref("dom.indexedDB.logging.profiler-marks", false); // Whether or not Web Workers are enabled. pref("dom.workers.enabled", true); From bc4dbcd8a1835ff884eb07abc39cf91106bede06 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Wed, 19 Nov 2014 16:23:49 +0100 Subject: [PATCH 07/36] Bug 1077652 - Introduce new preloading mechanism r=dao --- browser/base/content/tabbrowser.xml | 223 +++++++++++++++++++--------- testing/mochitest/browser-test.js | 8 + 2 files changed, 164 insertions(+), 67 deletions(-) diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 1b8a8fe27f6a..db66d0fdfc34 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1513,6 +1513,134 @@ + null + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1583,55 +1711,23 @@ if (aOwner) t.owner = aOwner; - var b = document.createElementNS( - "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", - "browser"); - b.setAttribute("type", "content-targetable"); - b.setAttribute("message", "true"); - b.setAttribute("messagemanagergroup", "browsers"); - b.setAttribute("contextmenu", this.getAttribute("contentcontextmenu")); - b.setAttribute("tooltip", this.getAttribute("contenttooltip")); + let b; + let usingPreloadedContent = false; + let isPrivateWindow = PrivateBrowsingUtils.isWindowPrivate(window); - if (remote) - b.setAttribute("remote", "true"); - - if (window.gShowPageResizers && window.windowState == window.STATE_NORMAL) { - b.setAttribute("showresizer", "true"); + // If we open a new tab with the newtab URL, + // check if there is a preloaded browser ready. + if (aURI == BROWSER_NEW_TAB_URL && !isPrivateWindow) { + b = this._getPreloadedBrowser(); + usingPreloadedContent = !!b; } - if (this.hasAttribute("autocompletepopup")) - b.setAttribute("autocompletepopup", this.getAttribute("autocompletepopup")); - - if (this.hasAttribute("selectpopup")) - b.setAttribute("selectpopup", this.getAttribute("selectpopup")); - - b.setAttribute("autoscrollpopup", this._autoScrollPopup.id); - - // Create the browserStack container - var stack = document.createElementNS(NS_XUL, "stack"); - stack.className = "browserStack"; - stack.appendChild(b); - stack.setAttribute("flex", "1"); - - // Create the browserContainer - var browserContainer = document.createElementNS(NS_XUL, "vbox"); - browserContainer.className = "browserContainer"; - browserContainer.appendChild(stack); - browserContainer.setAttribute("flex", "1"); - - // Create the sidebar container - var browserSidebarContainer = document.createElementNS(NS_XUL, - "hbox"); - browserSidebarContainer.className = "browserSidebarContainer"; - browserSidebarContainer.appendChild(browserContainer); - browserSidebarContainer.setAttribute("flex", "1"); - - // Add the Message and the Browser to the box - var notificationbox = document.createElementNS(NS_XUL, - "notificationbox"); - notificationbox.setAttribute("flex", "1"); - notificationbox.appendChild(browserSidebarContainer); + if (!b) { + // No preloaded browser found, create one. + b = this._createBrowser({remote, uriIsAboutBlank}); + } + let notificationbox = this.getNotificationBox(b); var position = this.tabs.length - 1; var uniqueId = this._generateUniquePanelID(); notificationbox.id = uniqueId; @@ -1642,19 +1738,16 @@ t.lastAccessed = Date.now(); this.tabContainer._setPositionalAttributes(); - // Prevent the superfluous initial load of a blank document - // if we're going to load something other than about:blank. - if (!uriIsAboutBlank) { - b.setAttribute("nodefaultsrc", "true"); + // Inject the into the DOM if necessary. + if (!notificationbox.parentNode) { + // NB: this appendChild call causes us to run constructors for the + // browser element, which fires off a bunch of notifications. Some + // of those notifications can cause code to run that inspects our + // state, so it is important that the tab element is fully + // initialized by this point. + this.mPanelContainer.appendChild(notificationbox); } - // NB: this appendChild call causes us to run constructors for the - // browser element, which fires off a bunch of notifications. Some - // of those notifications can cause code to run that inspects our - // state, so it is important that the tab element is fully - // initialized by this point. - this.mPanelContainer.appendChild(notificationbox); - // We've waited until the tab is in the DOM to set the label. This // allows the TabLabelModified event to be properly dispatched. if (!aURI || isBlankPageURL(aURI)) { @@ -1677,16 +1770,9 @@ b.droppedLinkHandler = handleDroppedLink; - // If we just created a new tab that loads the default - // newtab url, swap in a preloaded page if possible. - // Do nothing if we're a private window. - let docShellsSwapped = false; - if (aURI == BROWSER_NEW_TAB_URL && - !PrivateBrowsingUtils.isWindowPrivate(window) && - !gMultiProcessBrowser) { - docShellsSwapped = gBrowserNewTabPreloader.newTab(t); - } else if (aURI == "about:customizing") { - docShellsSwapped = gCustomizationTabPreloader.newTab(t); + // Swap in a preloaded customize tab, if available. + if (aURI == "about:customizing") { + usingPreloadedContent = gCustomizationTabPreloader.newTab(t); } // Dispatch a new tab notification. We do this once we're @@ -1698,7 +1784,7 @@ // If we didn't swap docShells with a preloaded browser // then let's just continue loading the page normally. - if (!docShellsSwapped && !uriIsAboutBlank) { + if (!usingPreloadedContent && !uriIsAboutBlank) { // pretend the user typed this so it'll be available till // the document successfully loads if (aURI && gInitialPages.indexOf(aURI) == -1) @@ -4279,6 +4365,9 @@ // without any scrolling and when the tabbar has already // overflowed. this.mTabstrip._updateScrollButtonsDisabledState(); + + // Preload the next about:newtab if there isn't one already. + this.tabbrowser._createPreloadBrowser(); ]]> diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js index a989d156c0f0..7c5816e4d225 100644 --- a/testing/mochitest/browser-test.js +++ b/testing/mochitest/browser-test.js @@ -505,6 +505,14 @@ Tester.prototype = { BackgroundPageThumbs._destroy(); BrowserNewTabPreloader.uninit(); + + // Destroy preloaded browsers. + if (gBrowser._preloadedBrowser) { + let browser = gBrowser._preloadedBrowser; + gBrowser._preloadedBrowser = null; + gBrowser.getNotificationBox(browser).remove(); + } + CustomizationTabPreloader.uninit(); SocialFlyout.unload(); SocialShare.uninit(); From 8bec2e8b93ad2acb6fce50f94974832916ce3f92 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Wed, 19 Nov 2014 16:21:22 +0100 Subject: [PATCH 08/36] Bug 1077652 - Update browser_newtab_background_captures.js to work with the new preloader r=adw --- .../browser_newtab_background_captures.js | 39 +++++-------------- browser/base/content/test/newtab/head.js | 26 ++++++++----- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/browser/base/content/test/newtab/browser_newtab_background_captures.js b/browser/base/content/test/newtab/browser_newtab_background_captures.js index f8ea7f982fb5..5b372482ebff 100644 --- a/browser/base/content/test/newtab/browser_newtab_background_captures.js +++ b/browser/base/content/test/newtab/browser_newtab_background_captures.js @@ -11,7 +11,6 @@ const CAPTURE_PREF = "browser.pagethumbnails.capturing_disabled"; function runTests() { let imports = {}; Cu.import("resource://gre/modules/PageThumbs.jsm", imports); - Cu.import("resource:///modules/BrowserNewTabPreloader.jsm", imports); // Disable captures. let originalDisabledState = Services.prefs.getBoolPref(CAPTURE_PREF); @@ -31,32 +30,15 @@ function runTests() { yield setLinks("-1"); // We need a handle to a hidden, pre-loaded newtab so we can verify that it - // doesn't allow background captures. Add a newtab, which triggers creation - // of a hidden newtab, and then keep calling BrowserNewTabPreloader.newTab - // until it returns true, meaning that it swapped the passed-in tab's docshell - // for the hidden newtab docshell. - let tab = gWindow.gBrowser.addTab("about:blank"); - yield addNewTabPageTab(); + // doesn't allow background captures. Ensure we have a preloaded browser. + gBrowser._createPreloadBrowser(); - // When newtab is loaded very quickly (which is what happens in 99% of cases) - // there is no need to wait so no tests are run. Because each test requires - // either a pass, fail or todo we run a dummy test here. - ok(true, "Each test requires at least one pass, fail or todo so here is a pass."); + // Wait for the preloaded browser to load. + yield waitForBrowserLoad(gBrowser._preloadedBrowser); - let swapWaitCount = 0; - let swapped = imports.BrowserNewTabPreloader.newTab(tab); - while (!swapped) { - if (++swapWaitCount == 10) { - ok(false, "Timed out waiting for newtab docshell swap."); - return; - } - // Give the hidden newtab some time to finish loading. - yield wait(2000); - info("Checking newtab swap " + swapWaitCount); - swapped = imports.BrowserNewTabPreloader.newTab(tab); - } - - // The tab's docshell is now the previously hidden newtab docshell. + // We're now ready to use the preloaded browser. + BrowserOpenTab(); + let tab = gBrowser.selectedTab; let doc = tab.linkedBrowser.contentDocument; // Enable captures. @@ -67,8 +49,11 @@ function runTests() { if (data != url) return; Services.obs.removeObserver(onCreate, "page-thumbnail:create"); + ok(true, "thumbnail created after preloaded tab was shown"); + // Test finished! Services.prefs.setBoolPref(CAPTURE_PREF, originalDisabledState); + gBrowser.removeTab(tab); file.remove(false); TestRunner.next(); }, "page-thumbnail:create", false); @@ -76,7 +61,3 @@ function runTests() { info("Waiting for thumbnail capture"); yield true; } - -function wait(ms) { - setTimeout(TestRunner.next, ms); -} diff --git a/browser/base/content/test/newtab/head.js b/browser/base/content/test/newtab/head.js index d07e6b92d47c..d823085242b9 100644 --- a/browser/base/content/test/newtab/head.js +++ b/browser/base/content/test/newtab/head.js @@ -374,21 +374,27 @@ function addNewTabPageTabPromise() { } } - // The new tab page might have been preloaded in the background. - if (browser.contentDocument.readyState == "complete") { - waitForCondition(() => !browser.contentDocument.hidden).then(whenNewTabLoaded); - return deferred.promise; - } - // Wait for the new tab page to be loaded. - browser.addEventListener("load", function onLoad() { - browser.removeEventListener("load", onLoad, true); - whenNewTabLoaded(); - }, true); + waitForBrowserLoad(browser, function () { + // Wait for the document to become visible in case it was preloaded. + waitForCondition(() => !browser.contentDocument.hidden).then(whenNewTabLoaded); + }); return deferred.promise; } +function waitForBrowserLoad(browser, callback = TestRunner.next) { + if (browser.contentDocument.readyState == "complete") { + executeSoon(callback); + return; + } + + browser.addEventListener("load", function onLoad() { + browser.removeEventListener("load", onLoad, true); + executeSoon(callback); + }, true); +} + /** * Compares the current grid arrangement with the given pattern. * @param the pattern (see below) From 2f2c500f0f611ff0e4352ae0bee0334ffe245751 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Wed, 5 Nov 2014 14:36:44 +0100 Subject: [PATCH 09/36] Bug 1077652 - Revert change from bug 794041 that makes test_docload.html expect accessibles in the hidden window r=tbsaunde --- .../tests/mochitest/events/test_docload.html | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/accessible/tests/mochitest/events/test_docload.html b/accessible/tests/mochitest/events/test_docload.html index 7d3d515430b5..01abeb32d765 100644 --- a/accessible/tests/mochitest/events/test_docload.html +++ b/accessible/tests/mochitest/events/test_docload.html @@ -15,25 +15,6 @@ src="../role.js"> - - - @@ -193,12 +174,6 @@ var accTree = { role: ROLE_APP_ROOT, children: [ - { - role: ROLE_CHROME_WINDOW - }, - { - role: ROLE_CHROME_WINDOW - }, { role: ROLE_CHROME_WINDOW }, From a0d7efa3cd786bfcb9e7e19825ca359bd6a62826 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Thu, 6 Nov 2014 12:30:47 +0100 Subject: [PATCH 10/36] Bug 1077652 - Let a11y tests know about the extra preloaded document r=tbsaunde --- .../tests/mochitest/actions/test_link.html | 13 +++++++++++-- .../tests/mochitest/tree/test_dochierarchy.html | 11 ++++++++--- .../tests/mochitest/tree/test_tabbrowser.xul | 17 +++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/accessible/tests/mochitest/actions/test_link.html b/accessible/tests/mochitest/actions/test_link.html index 49fc7d911b2c..2b6904517586 100644 --- a/accessible/tests/mochitest/actions/test_link.html +++ b/accessible/tests/mochitest/actions/test_link.html @@ -22,8 +22,17 @@ var thisTabDocAcc = getTabDocAccessible(); var thisDocTabPanelAcc = thisTabDocAcc.parent.parent; var tabPanelsAcc = thisDocTabPanelAcc.parent; - var newDocTabPanelAcc = tabPanelsAcc.lastChild.firstChild; - return newDocTabPanelAcc.firstChild; + var newDocTabPanelAcc = tabPanelsAcc.firstChild; + var nextAcc = newDocTabPanelAcc; + + while (nextAcc = nextAcc.nextSibling) { + // Find the last accessible for a browser with about:mozilla loaded. + if (nextAcc.firstChild.DOMNode.currentURI.spec == "about:mozilla") { + newDocTabPanelAcc = nextAcc; + } + } + + return newDocTabPanelAcc.firstChild.firstChild; } function linkChecker(aID) diff --git a/accessible/tests/mochitest/tree/test_dochierarchy.html b/accessible/tests/mochitest/tree/test_dochierarchy.html index 0bc9686aabea..0104c6abadba 100644 --- a/accessible/tests/mochitest/tree/test_dochierarchy.html +++ b/accessible/tests/mochitest/tree/test_dochierarchy.html @@ -31,10 +31,15 @@ is(root.parentDocument, null, "Wrong parent document of root accessible"); - is(root.childDocumentCount, 1, + ok(root.childDocumentCount >= 1, "Wrong child document count of root accessible"); - is(root.getChildDocumentAt(0), tabDoc, - "Wrong child document at index 0 of root accessible"); + + var tabDocumentFound = false; + for (var i = 0; i < root.childDocumentCount && !tabDocumentFound; i++) { + tabDocumentFound = root.getChildDocumentAt(i) == tabDoc; + } + ok(tabDocumentFound, + "Tab document not found in children of the root accessible"); is(tabDoc.parentDocument, root, "Wrong parent document of tab document"); diff --git a/accessible/tests/mochitest/tree/test_tabbrowser.xul b/accessible/tests/mochitest/tree/test_tabbrowser.xul index d4755c120fc5..e957c10658f0 100644 --- a/accessible/tests/mochitest/tree/test_tabbrowser.xul +++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul @@ -169,6 +169,23 @@ ] } ] + }, + { + // notificationbox + role: ROLE_PROPERTYPAGE, + children: [ + { + // browser + role: ROLE_INTERNAL_FRAME, + children: [ + { + // #document ("about:newtab" preloaded) + role: ROLE_APPLICATION + // children: [ ... ] // Ignore document content. + } + ] + } + ] } ] }; From fa8dce40d6b93a5d6c88216675d63730cf006722 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Wed, 19 Nov 2014 16:21:07 +0100 Subject: [PATCH 11/36] Bug 1077652 - Remove old BrowserNewTabPreloader.jsm and references r=jaws --- browser/base/content/browser.js | 3 - browser/components/nsBrowserGlue.js | 4 - browser/modules/BrowserNewTabPreloader.jsm | 379 --------------------- browser/modules/moz.build | 1 - testing/mochitest/browser-test.js | 5 - 5 files changed, 392 deletions(-) delete mode 100644 browser/modules/BrowserNewTabPreloader.jsm diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 18990542ff17..a81f5542c10c 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -154,9 +154,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing", "resource://gre/modules/SafeBrowsing.jsm"); #endif -XPCOMUtils.defineLazyModuleGetter(this, "gBrowserNewTabPreloader", - "resource:///modules/BrowserNewTabPreloader.jsm", "BrowserNewTabPreloader"); - XPCOMUtils.defineLazyModuleGetter(this, "gCustomizationTabPreloader", "resource:///modules/CustomizationTabPreloader.jsm", "CustomizationTabPreloader"); diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index 047bcf22d827..0b8241317e65 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -53,9 +53,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs", XPCOMUtils.defineLazyModuleGetter(this, "NewTabUtils", "resource://gre/modules/NewTabUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader", - "resource:///modules/BrowserNewTabPreloader.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "CustomizationTabPreloader", "resource:///modules/CustomizationTabPreloader.jsm"); @@ -791,7 +788,6 @@ BrowserGlue.prototype = { Cu.reportError("Could not end startup crash tracking in quit-application-granted: " + e); } - BrowserNewTabPreloader.uninit(); CustomizationTabPreloader.uninit(); WebappManager.uninit(); #ifdef NIGHTLY_BUILD diff --git a/browser/modules/BrowserNewTabPreloader.jsm b/browser/modules/BrowserNewTabPreloader.jsm deleted file mode 100644 index 41e86883d96a..000000000000 --- a/browser/modules/BrowserNewTabPreloader.jsm +++ /dev/null @@ -1,379 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -this.EXPORTED_SYMBOLS = ["BrowserNewTabPreloader"]; - -const Cu = Components.utils; -const Cc = Components.classes; -const Ci = Components.interfaces; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Promise.jsm"); - -const HTML_NS = "http://www.w3.org/1999/xhtml"; -const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; -const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,"; -const NEWTAB_URL = "about:newtab"; - -const PREF_NEWTAB_URL = "browser.newtab.url"; -const PREF_NEWTAB_PRELOAD = "browser.newtab.preload"; - -// The interval between swapping in a preload docShell and kicking off the -// next preload in the background. -const PRELOADER_INTERVAL_MS = 600; -// The number of miliseconds we'll wait after we received a notification that -// causes us to update our list of browsers and tabbrowser sizes. This acts as -// kind of a damper when too many events are occuring in quick succession. -const PRELOADER_UPDATE_DELAY_MS = 3000; - -const TOPIC_TIMER_CALLBACK = "timer-callback"; -const TOPIC_DELAYED_STARTUP = "browser-delayed-startup-finished"; -const TOPIC_XUL_WINDOW_CLOSED = "xul-window-destroyed"; - -const BROWSER_CONTENT_SCRIPT = "chrome://browser/content/content.js"; - -function isPreloadingEnabled() { - return Services.prefs.getBoolPref(PREF_NEWTAB_PRELOAD) && - !Services.prefs.prefHasUserValue(PREF_NEWTAB_URL); -} - -function createTimer(obj, delay) { - let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - timer.init(obj, delay, Ci.nsITimer.TYPE_ONE_SHOT); - return timer; -} - -function clearTimer(timer) { - if (timer) { - timer.cancel(); - } - return null; -} - -this.BrowserNewTabPreloader = { - uninit: function Preloader_uninit() { - HostFrame.destroy(); - HiddenBrowsers.uninit(); - }, - - newTab: function Preloader_newTab(aTab) { - if (!isPreloadingEnabled()) { - return false; - } - - let win = aTab.ownerDocument.defaultView; - if (win.gBrowser) { - let utils = win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - - let {width, height} = utils.getBoundsWithoutFlushing(win.gBrowser); - let hiddenBrowser = HiddenBrowsers.get(width, height) - if (hiddenBrowser) { - return hiddenBrowser.swapWithNewTab(aTab); - } - } - - return false; - } -}; - -Object.freeze(BrowserNewTabPreloader); - -let HiddenBrowsers = { - _browsers: null, - _updateTimer: null, - - _topics: [ - TOPIC_DELAYED_STARTUP, - TOPIC_XUL_WINDOW_CLOSED - ], - - _init: function () { - this._browsers = new Map(); - this._updateBrowserSizes(); - this._topics.forEach(t => Services.obs.addObserver(this, t, false)); - }, - - uninit: function () { - if (this._browsers) { - this._topics.forEach(t => Services.obs.removeObserver(this, t, false)); - this._updateTimer = clearTimer(this._updateTimer); - - for (let [key, browser] of this._browsers) { - browser.destroy(); - } - this._browsers = null; - } - }, - - get: function (width, height) { - // Initialize if this is the first call. - if (!this._browsers) { - this._init(); - } - - let key = width + "x" + height; - if (!this._browsers.has(key)) { - // Update all browsers' sizes if we can't find a matching one. - this._updateBrowserSizes(); - } - - // We should now have a matching browser. - if (this._browsers.has(key)) { - return this._browsers.get(key); - } - - // We should never be here. Return the first browser we find. - Cu.reportError("NewTabPreloader: no matching browser found after updating"); - for (let [size, browser] of this._browsers) { - return browser; - } - - // We should really never be here. - Cu.reportError("NewTabPreloader: not even a single browser was found?"); - return null; - }, - - observe: function (subject, topic, data) { - if (topic === TOPIC_TIMER_CALLBACK) { - this._updateTimer = null; - this._updateBrowserSizes(); - } else { - this._updateTimer = clearTimer(this._updateTimer); - this._updateTimer = createTimer(this, PRELOADER_UPDATE_DELAY_MS); - } - }, - - _updateBrowserSizes: function () { - let sizes = this._collectTabBrowserSizes(); - let toRemove = []; - - // Iterate all browsers and check that they - // each can be assigned to one of the sizes. - for (let [key, browser] of this._browsers) { - if (sizes.has(key)) { - // We already have a browser for that size, great! - sizes.delete(key); - } else { - // This browser is superfluous or needs to be resized. - toRemove.push(browser); - this._browsers.delete(key); - } - } - - // Iterate all sizes that we couldn't find a browser for. - for (let [key, {width, height}] of sizes) { - let browser; - if (toRemove.length) { - // Let's just resize one of the superfluous - // browsers and put it back into the map. - browser = toRemove.shift(); - browser.resize(width, height); - } else { - // No more browsers to reuse, create a new one. - browser = new HiddenBrowser(width, height); - } - - this._browsers.set(key, browser); - } - - // Finally, remove all browsers we don't need anymore. - toRemove.forEach(b => b.destroy()); - }, - - _collectTabBrowserSizes: function () { - let sizes = new Map(); - - function tabBrowserBounds() { - let wins = Services.ww.getWindowEnumerator("navigator:browser"); - while (wins.hasMoreElements()) { - let win = wins.getNext(); - if (win.gBrowser) { - let utils = win.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - yield utils.getBoundsWithoutFlushing(win.gBrowser); - } - } - } - - // Collect the sizes of all s out there. - for (let {width, height} of tabBrowserBounds()) { - if (width > 0 && height > 0) { - let key = width + "x" + height; - if (!sizes.has(key)) { - sizes.set(key, {width: width, height: height}); - } - } - } - - return sizes; - } -}; - -function HiddenBrowser(width, height) { - this.resize(width, height); - this._createBrowser(); -} - -HiddenBrowser.prototype = { - _width: null, - _height: null, - _timer: null, - - get isPreloaded() { - return this._browser && - this._browser.contentDocument && - this._browser.contentDocument.readyState === "complete" && - this._browser.currentURI.spec === NEWTAB_URL; - }, - - swapWithNewTab: function (aTab) { - if (!this.isPreloaded || this._timer) { - return false; - } - - let win = aTab.ownerDocument.defaultView; - let tabbrowser = win.gBrowser; - - if (!tabbrowser) { - return false; - } - - // Swap docShells. - tabbrowser.swapNewTabWithBrowser(aTab, this._browser); - - // Load all delayed frame scripts attached to the "browers" message manager. - // The browser content script was already loaded, so don't load it again. - let mm = aTab.linkedBrowser.messageManager; - let scripts = win.getGroupMessageManager("browsers").getDelayedFrameScripts(); - Array.forEach(scripts, ([script, runGlobal]) => { - if (script != BROWSER_CONTENT_SCRIPT) { - mm.loadFrameScript(script, true, runGlobal); - } - }); - - // Remove the browser, it will be recreated by a timer. - this._removeBrowser(); - - // Start a timer that will kick off preloading the next newtab page. - this._timer = createTimer(this, PRELOADER_INTERVAL_MS); - - // Signal that we swapped docShells. - return true; - }, - - observe: function () { - this._timer = null; - - // Start pre-loading the new tab page. - this._createBrowser(); - }, - - resize: function (width, height) { - this._width = width; - this._height = height; - this._applySize(); - }, - - destroy: function () { - this._removeBrowser(); - this._timer = clearTimer(this._timer); - }, - - _applySize: function () { - if (this._browser) { - this._browser.style.width = this._width + "px"; - this._browser.style.height = this._height + "px"; - } - }, - - _createBrowser: function () { - HostFrame.get().then(aFrame => { - let doc = aFrame.document; - this._browser = doc.createElementNS(XUL_NS, "browser"); - this._browser.setAttribute("type", "content"); - this._browser.setAttribute("src", NEWTAB_URL); - this._applySize(); - doc.getElementById("win").appendChild(this._browser); - - // The browser might not have a docShell here if the HostFrame was - // destroyed while the promise was resolved. Simply bail out. - if (!this._browser.docShell) { - return; - } - - // Let the docShell be inactive so that document.hidden=true. - this._browser.docShell.isActive = false; - - this._browser.messageManager.loadFrameScript(BROWSER_CONTENT_SCRIPT, - true); - }); - }, - - _removeBrowser: function () { - if (this._browser) { - this._browser.remove(); - this._browser = null; - } - } -}; - -let HostFrame = { - _frame: null, - _deferred: null, - - get hiddenDOMDocument() { - return Services.appShell.hiddenDOMWindow.document; - }, - - get isReady() { - return this.hiddenDOMDocument.readyState === "complete"; - }, - - get: function () { - if (!this._deferred) { - this._deferred = Promise.defer(); - this._create(); - } - - return this._deferred.promise; - }, - - destroy: function () { - if (this._frame) { - if (!Cu.isDeadWrapper(this._frame)) { - this._frame.removeEventListener("load", this, true); - this._frame.remove(); - } - - this._frame = null; - this._deferred = null; - } - }, - - handleEvent: function () { - let contentWindow = this._frame.contentWindow; - if (contentWindow.location.href === XUL_PAGE) { - this._frame.removeEventListener("load", this, true); - this._deferred.resolve(contentWindow); - } else { - contentWindow.location = XUL_PAGE; - } - }, - - _create: function () { - if (this.isReady) { - let doc = this.hiddenDOMDocument; - this._frame = doc.createElementNS(HTML_NS, "iframe"); - this._frame.addEventListener("load", this, true); - doc.documentElement.appendChild(this._frame); - } else { - let flags = Ci.nsIThread.DISPATCH_NORMAL; - Services.tm.currentThread.dispatch(() => this._create(), flags); - } - } -}; diff --git a/browser/modules/moz.build b/browser/modules/moz.build index 0cc21c5dd24e..d708b5fc9702 100644 --- a/browser/modules/moz.build +++ b/browser/modules/moz.build @@ -11,7 +11,6 @@ XPCSHELL_TESTS_MANIFESTS += [ ] EXTRA_JS_MODULES += [ - 'BrowserNewTabPreloader.jsm', 'BrowserUITelemetry.jsm', 'CastingApps.jsm', 'Chat.jsm', diff --git a/testing/mochitest/browser-test.js b/testing/mochitest/browser-test.js index 7c5816e4d225..9d4c638cb0c2 100644 --- a/testing/mochitest/browser-test.js +++ b/testing/mochitest/browser-test.js @@ -15,9 +15,6 @@ Cu.import("resource://gre/modules/Task.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "BrowserNewTabPreloader", - "resource:///modules/BrowserNewTabPreloader.jsm"); - XPCOMUtils.defineLazyModuleGetter(this, "CustomizationTabPreloader", "resource:///modules/CustomizationTabPreloader.jsm"); @@ -504,8 +501,6 @@ Tester.prototype = { Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm", {}); BackgroundPageThumbs._destroy(); - BrowserNewTabPreloader.uninit(); - // Destroy preloaded browsers. if (gBrowser._preloadedBrowser) { let browser = gBrowser._preloadedBrowser; From aaec5f7d971b49a04352e21a3f77cdfe2aa3fbb5 Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Thu, 11 Dec 2014 21:05:54 -0800 Subject: [PATCH 12/36] Bug 1104927 - UITour: Add Loop conversation view target for email/copy link buttons. r=Unfocused,mixedpuppy --- browser/base/content/socialchat.xml | 6 ++++++ browser/components/loop/MozLoopService.jsm | 12 +++++++++--- browser/modules/UITour.jsm | 13 +++++++++++-- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/browser/base/content/socialchat.xml b/browser/base/content/socialchat.xml index 6355429fcd3c..83ac01569c1f 100644 --- a/browser/base/content/socialchat.xml +++ b/browser/base/content/socialchat.xml @@ -669,6 +669,12 @@ if (event.target != otherWin.document) return; + let detachEvent = new aChatbox.contentWindow.CustomEvent("socialFrameDetached", { + bubbles: true, + cancelable: true, + }); + aChatbox.contentDocument.dispatchEvent(detachEvent); + otherWin.removeEventListener("load", _chatLoad, true); let otherChatbox = otherWin.document.getElementById("chatter"); aChatbox.swapDocShells(otherChatbox); diff --git a/browser/components/loop/MozLoopService.jsm b/browser/components/loop/MozLoopService.jsm index a3f034be0eb4..6c30bf438358 100644 --- a/browser/components/loop/MozLoopService.jsm +++ b/browser/components/loop/MozLoopService.jsm @@ -828,9 +828,15 @@ let MozLoopServiceInternal = { let window = chatbox.contentWindow; - window.addEventListener("unload", function onUnloadChat(evt) { - UITour.notify("Loop:ChatWindowClosed"); - }); + function socialFrameChanged(eventName) { + UITour.availableTargetsCache.clear(); + UITour.notify(eventName); + } + + window.addEventListener("socialFrameHide", socialFrameChanged.bind(null, "Loop:ChatWindowHidden")); + window.addEventListener("socialFrameShow", socialFrameChanged.bind(null, "Loop:ChatWindowShown")); + window.addEventListener("socialFrameDetached", socialFrameChanged.bind(null, "Loop:ChatWindowDetached")); + window.addEventListener("unload", socialFrameChanged.bind(null, "Loop:ChatWindowClosed")); injectLoopAPI(window); diff --git a/browser/modules/UITour.jsm b/browser/modules/UITour.jsm index 7534fd4b4b87..48448e8c3370 100644 --- a/browser/modules/UITour.jsm +++ b/browser/modules/UITour.jsm @@ -142,6 +142,16 @@ this.UITour = { return loopBrowser.contentDocument.querySelector(".room-list"); }, }], + ["loop-selectedRoomButtons", { + infoPanelPosition: "leftcenter bottomright", + query: (aDocument) => { + let chatbox = aDocument.querySelector("chatbox[src^='about\:loopconversation'][selected]"); + if (!chatbox || !chatbox.contentDocument) { + return null; + } + return chatbox.contentDocument.querySelector(".call-action-group"); + }, + }], ["loop-signInUpLink", { query: (aDocument) => { let loopBrowser = aDocument.querySelector("#loop-notification-panel > #loop"); @@ -1375,8 +1385,7 @@ this.UITour = { hideLoopPanelAnnotations: function(aEvent) { UITour.hideAnnotationsForPanel(aEvent, (aTarget) => { - // TODO: Bug 1104927 - Handle the conversation targets separately. - return aTarget.targetName.startsWith("loop-"); + return aTarget.targetName.startsWith("loop-") && aTarget.targetName != "loop-selectedRoomButtons"; }); }, From 8e8d87b6b562c2754b34e684b7a6dea73dbe6fac Mon Sep 17 00:00:00 2001 From: Drew Willcoxon Date: Thu, 11 Dec 2014 21:06:55 -0800 Subject: [PATCH 13/36] Bug 1016825 - Show legacy-Sync-to-Firefox-Accounts migration notifications in the main browser window. r=markh --- browser/base/content/browser-fxaccounts.js | 82 +++++++++++++++---- browser/base/content/browser-syncui.js | 32 -------- .../test/general/browser_fxa_migrate.js | 19 ++++- .../en-US/chrome/browser/accounts.properties | 22 +++-- 4 files changed, 98 insertions(+), 57 deletions(-) diff --git a/browser/base/content/browser-fxaccounts.js b/browser/base/content/browser-fxaccounts.js index 18fc0e35e0e5..28b544fa4aba 100644 --- a/browser/base/content/browser-fxaccounts.js +++ b/browser/base/content/browser-fxaccounts.js @@ -11,6 +11,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "fxaMigrator", const PREF_SYNC_START_DOORHANGER = "services.sync.ui.showSyncStartDoorhanger"; const DOORHANGER_ACTIVATE_DELAY_MS = 5000; +const SYNC_MIGRATION_NOTIFICATION_TITLE = "fxa-migration"; let gFxAccounts = { @@ -157,7 +158,7 @@ let gFxAccounts = { setTimeout(() => this.onSyncStart(), DOORHANGER_ACTIVATE_DELAY_MS); } else { this._inCustomizationMode = event.type == "customizationstarting"; - this.updateUI(); + this.updateAppMenuItem(); } }, @@ -182,8 +183,13 @@ let gFxAccounts = { }, updateUI: function () { + this.updateAppMenuItem(); + this.updateMigrationNotification(); + }, + + updateAppMenuItem: function () { if (this._migrationInfo) { - this.showMigrationUI(); + this.updateAppMenuItemForMigration(); return; } @@ -241,32 +247,74 @@ let gFxAccounts = { }); }, - showMigrationUI: Task.async(function* () { + updateAppMenuItemForMigration: Task.async(function* () { let status = null; let label = null; switch (this._migrationInfo.state) { case fxaMigrator.STATE_USER_FXA: status = "migrate-signup"; - label = this.strings.formatStringFromName("needUser", + label = this.strings.formatStringFromName("needUserShort", [this.button.getAttribute("fxabrandname")], 1); break; case fxaMigrator.STATE_USER_FXA_VERIFIED: - if (this._migrationInfo.email) { - status = "migrate-verify"; - label = this.strings.formatStringFromName("needVerifiedUser", - [this._migrationInfo.email], - 1); - } + status = "migrate-verify"; + label = this.strings.formatStringFromName("needVerifiedUserShort", + [this._migrationInfo.email], + 1); break; } - if (label && status) { - this.button.label = label; - this.button.hidden = false; - this.button.setAttribute("fxastatus", status); - } else { - Cu.reportError("Could not update menu panel button given migration " + - "state: " + this._migrationInfo.state); + this.button.label = label; + this.button.hidden = false; + this.button.setAttribute("fxastatus", status); + }), + + updateMigrationNotification: Task.async(function* () { + if (!this._migrationInfo) { + Weave.Notifications.removeAll(SYNC_MIGRATION_NOTIFICATION_TITLE); + return; } + if (gBrowser.currentURI.spec.split("?")[0] == "about:accounts") { + // If the current tab is about:accounts, assume the user just completed a + // migration step and don't bother them with a redundant notification. + return; + } + let note = null; + switch (this._migrationInfo.state) { + case fxaMigrator.STATE_USER_FXA: { + let msg = this.strings.GetStringFromName("needUserLong"); + let upgradeLabel = + this.strings.GetStringFromName("upgradeToFxA.label"); + let upgradeAccessKey = + this.strings.GetStringFromName("upgradeToFxA.accessKey"); + note = new Weave.Notification( + undefined, msg, undefined, Weave.Notifications.PRIORITY_WARNING, [ + new Weave.NotificationButton(upgradeLabel, upgradeAccessKey, () => { + fxaMigrator.createFxAccount(window); + }), + ] + ); + break; + } + case fxaMigrator.STATE_USER_FXA_VERIFIED: { + let msg = + this.strings.formatStringFromName("needVerifiedUserLong", + [this._migrationInfo.email], 1); + let resendLabel = + this.strings.GetStringFromName("resendVerificationEmail.label"); + let resendAccessKey = + this.strings.GetStringFromName("resendVerificationEmail.accessKey"); + note = new Weave.Notification( + undefined, msg, undefined, Weave.Notifications.PRIORITY_INFO, [ + new Weave.NotificationButton(resendLabel, resendAccessKey, () => { + fxaMigrator.resendVerificationMail(); + }), + ] + ); + break; + } + } + note.title = SYNC_MIGRATION_NOTIFICATION_TITLE; + Weave.Notifications.replaceTitle(note); }), onMenuPanelCommand: function (event) { diff --git a/browser/base/content/browser-syncui.js b/browser/base/content/browser-syncui.js index 48d39d779809..e93ec1a8a9fd 100644 --- a/browser/base/content/browser-syncui.js +++ b/browser/base/content/browser-syncui.js @@ -13,8 +13,6 @@ let CloudSync = null; // gSyncUI handles updating the tools menu and displaying notifications. let gSyncUI = { - DEFAULT_EOL_URL: "https://www.mozilla.org/firefox/?utm_source=synceol", - _obs: ["weave:service:sync:start", "weave:service:quota:remaining", "weave:service:setup-complete", @@ -27,7 +25,6 @@ let gSyncUI = { "weave:ui:sync:error", "weave:ui:sync:finish", "weave:ui:clear-error", - "weave:eol", ], _unloaded: false, @@ -260,32 +257,6 @@ let gSyncUI = { return brand.get("brandShortName"); }, - onEOLNotice: function (data) { - let code = data.code; - let kind = (code == "hard-eol") ? "error" : "warning"; - let url = data.url || gSyncUI.DEFAULT_EOL_URL; - - let title = this._stringBundle.GetStringFromName(kind + ".sync.eol.label"); - let description = this._stringBundle.formatStringFromName(kind + ".sync.eol.description", - [this._getAppName()], - 1); - - let buttons = []; - buttons.push(new Weave.NotificationButton( - this._stringBundle.GetStringFromName("sync.eol.learnMore.label"), - this._stringBundle.GetStringFromName("sync.eol.learnMore.accesskey"), - function() { - window.openUILinkIn(url, "tab"); - return true; - } - )); - - let priority = (kind == "error") ? Weave.Notifications.PRIORITY_WARNING : - Weave.Notifications.PRIORITY_INFO; - let notification = new Weave.Notification(title, description, null, priority, buttons); - Weave.Notifications.replaceTitle(notification); - }, - openServerStatus: function () { let statusURL = Services.prefs.getCharPref("services.sync.statusURL"); window.openUILinkIn(statusURL, "tab"); @@ -551,9 +522,6 @@ let gSyncUI = { case "weave:ui:clear-error": this.clearError(); break; - case "weave:eol": - this.onEOLNotice(subject); - break; } }, diff --git a/browser/base/content/test/general/browser_fxa_migrate.js b/browser/base/content/test/general/browser_fxa_migrate.js index 2e28cbecc0e8..d631a4ea53db 100644 --- a/browser/base/content/test/general/browser_fxa_migrate.js +++ b/browser/base/content/test/general/browser_fxa_migrate.js @@ -2,6 +2,7 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ const STATE_CHANGED_TOPIC = "fxa-migration:state-changed"; +const NOTIFICATION_TITLE = "fxa-migration"; let imports = {}; Cu.import("resource://services-sync/FxaMigrator.jsm", imports); @@ -9,30 +10,42 @@ Cu.import("resource://services-sync/FxaMigrator.jsm", imports); add_task(function* test() { // Fake the state where we need an FxA user. let buttonPromise = promiseButtonMutation(); - Services.obs.notifyObservers(null, "fxa-migration:state-changed", + Services.obs.notifyObservers(null, STATE_CHANGED_TOPIC, fxaMigrator.STATE_USER_FXA); let buttonState = yield buttonPromise; assertButtonState(buttonState, "migrate-signup", true); + Assert.ok(Weave.Notifications.notifications.some(n => { + return n.title == NOTIFICATION_TITLE; + }), "Needs-user notification should be present"); // Fake the state where we need a verified FxA user. buttonPromise = promiseButtonMutation(); let email = Cc["@mozilla.org/supports-string;1"]. createInstance(Ci.nsISupportsString); email.data = "foo@example.com"; - Services.obs.notifyObservers(email, "fxa-migration:state-changed", + Services.obs.notifyObservers(email, STATE_CHANGED_TOPIC, fxaMigrator.STATE_USER_FXA_VERIFIED); buttonState = yield buttonPromise; assertButtonState(buttonState, "migrate-verify", true, "foo@example.com not verified"); + let note = Weave.Notifications.notifications.find(n => { + return n.title == NOTIFICATION_TITLE; + }); + Assert.ok(!!note, "Needs-verification notification should be present"); + Assert.ok(note.description.contains(email.data), + "Needs-verification notification should include email"); // Fake the state where no migration is needed. buttonPromise = promiseButtonMutation(); - Services.obs.notifyObservers(null, "fxa-migration:state-changed", null); + Services.obs.notifyObservers(null, STATE_CHANGED_TOPIC, null); buttonState = yield buttonPromise; // In this case, the front end has called fxAccounts.getSignedInUser() to // update the button label and status. But since there isn't actually a user, // the button is left with no fxastatus. assertButtonState(buttonState, "", true); + Assert.ok(!Weave.Notifications.notifications.some(n => { + return n.title == NOTIFICATION_TITLE; + }), "Migration notifications should no longer be present"); }); function assertButtonState(buttonState, expectedStatus, expectedVisible, diff --git a/browser/locales/en-US/chrome/browser/accounts.properties b/browser/locales/en-US/chrome/browser/accounts.properties index 7805167f2d34..18dff0aaa66e 100644 --- a/browser/locales/en-US/chrome/browser/accounts.properties +++ b/browser/locales/en-US/chrome/browser/accounts.properties @@ -1,7 +1,19 @@ -# LOCALIZATION NOTE (needUser) -# %S = Firefox Accounts brand name from syncBrand.dtd -needUser = %S required for sync +# 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/. -# LOCALIZATION NOTE (needVerifiedUser) +# LOCALIZATION NOTE (needUserShort) +# %S = Firefox Accounts brand name from syncBrand.dtd +needUserShort = %S required for sync +needUserLong = We've rebuilt Sync to make it easier for everyone. Please upgrade to a Firefox Account to continue syncing. + +upgradeToFxA.label = Upgrade +upgradeToFxA.accessKey = U + +# LOCALIZATION NOTE (needVerifiedUserShort, needVerifiedUserLong) # %S = Email address of user's Firefox Account -needVerifiedUser = %S not verified +needVerifiedUserShort = %S not verified +needVerifiedUserLong = Please click the verification link in the email sent to %S + +resendVerificationEmail.label = Resend +resendVerificationEmail.accessKey = R From 07ec92ff2ba267c98ca41ed04886ba8e34ccf51d Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Thu, 11 Dec 2014 21:37:16 -0800 Subject: [PATCH 14/36] Bug 1104927 - UITour: Update browser_UITour_loop.js with for Loop:ChatWindowShown. r=me --- browser/modules/test/browser_UITour_loop.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/browser/modules/test/browser_UITour_loop.js b/browser/modules/test/browser_UITour_loop.js index ac2e6b7aa9c7..25a18232a44a 100644 --- a/browser/modules/test/browser_UITour_loop.js +++ b/browser/modules/test/browser_UITour_loop.js @@ -90,9 +90,12 @@ let tests = [ gContentAPI.observe((event, params) => { is(event, "Loop:ChatWindowOpened", "Check Loop:ChatWindowOpened notification"); gContentAPI.observe((event, params) => { - is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification"); + is(event, "Loop:ChatWindowShown", "Check Loop:ChatWindowShown notification"); gContentAPI.observe((event, params) => { - ok(false, "No more notifications should have arrived"); + is(event, "Loop:ChatWindowClosed", "Check Loop:ChatWindowClosed notification"); + gContentAPI.observe((event, params) => { + ok(false, "No more notifications should have arrived"); + }); }); done(); }); From fa5d35976f775f7c19d283615c49d57b44b43f79 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Tue, 9 Dec 2014 11:48:00 -0800 Subject: [PATCH 15/36] Bug 1106584, Part 1: guard against null intent. r=vng --- .../mozstumbler/service/uploadthread/UploadAlarmReceiver.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java index b46400c2ef63..3780e47021d7 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java @@ -48,7 +48,8 @@ public class UploadAlarmReceiver extends BroadcastReceiver { @Override protected void onHandleIntent(Intent intent) { - boolean isRepeating = intent.getBooleanExtra(EXTRA_IS_REPEATING, true); + // Default to a repeating alarm, which is what Fennec Stumbler uses + boolean isRepeating = (intent == null)? true : intent.getBooleanExtra(EXTRA_IS_REPEATING, true); if (DataStorageManager.getInstance() == null) { DataStorageManager.createGlobalInstance(this, null); } From dc56c0508fea82498993732abebb977ce6a1eb77 Mon Sep 17 00:00:00 2001 From: Garvan Keeley Date: Thu, 11 Dec 2014 09:06:00 -0800 Subject: [PATCH 16/36] Bug 1106584 - Part 2: for safety, make explicit prefs with context getter. r=vng Any class that has access to a context should call Prefs.getInstance(Context) which is guaranteed to return a Prefs. With no context, classes can call Prefs.getInstanceWithoutContext() but they must null-check the return, and handle accordingly. Fortunately, the latter case happens in very few places, all of which require no special handling of this case. This change: - maintains context-less access to the Prefs - classes internal to the service can safely call getInstanceWithoutContext(), as the service (or the MainApp in the stumbler case) will have instantiated a Prefs so that getInstanceWithoutContext() will return a prefs - protects against null Prefs if we have failed to consider a particular entry point to the code will require that Prefs was instatiated with a context. --- .../mozilla/mozstumbler/service/Prefs.java | 15 +++++------ .../stumblerthread/StumblerService.java | 27 ++++++++++--------- .../stumblerthread/scanners/GPSScanner.java | 8 ++++-- .../scanners/LocationBlockList.java | 8 ++++-- .../stumblerthread/scanners/WifiScanner.java | 5 ++-- .../service/uploadthread/AsyncUploader.java | 4 --- .../uploadthread/UploadAlarmReceiver.java | 4 +-- .../service/utils/AbstractCommunicator.java | 10 ++++--- 8 files changed, 43 insertions(+), 38 deletions(-) diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/Prefs.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/Prefs.java index 3107c893100c..cd1abd91c4b7 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/Prefs.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/Prefs.java @@ -48,18 +48,15 @@ public final class Prefs { } } - /* Prefs must be created on application startup or service startup. - * TODO: turn into regular singleton if Context dependency can be removed. */ - public static void createGlobalInstance(Context c) { - if (sInstance != null) { - return; + public static Prefs getInstance(Context c) { + if (sInstance == null) { + sInstance = new Prefs(c); } - sInstance = new Prefs(c); + return sInstance; } - /* Only access after CreatePrefsInstance(Context) has been called at startup. */ - public static Prefs getInstance() { - assert(sInstance != null); + // Allows code without a context handle to grab the prefs. The caller must null check the return value. + public static Prefs getInstanceWithoutContext() { return sInstance; } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java index 0f2648c81ae0..a931daaef677 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/StumblerService.java @@ -4,6 +4,7 @@ package org.mozilla.mozstumbler.service.stumblerthread; +import android.content.Context; import android.content.Intent; import android.location.Location; import android.os.AsyncTask; @@ -16,7 +17,6 @@ import org.mozilla.mozstumbler.service.Prefs; import org.mozilla.mozstumbler.service.stumblerthread.blocklist.WifiBlockListInterface; import org.mozilla.mozstumbler.service.stumblerthread.datahandling.DataStorageManager; import org.mozilla.mozstumbler.service.stumblerthread.scanners.ScanManager; -import org.mozilla.mozstumbler.service.stumblerthread.scanners.cellscanner.CellScanner; import org.mozilla.mozstumbler.service.uploadthread.UploadAlarmReceiver; import org.mozilla.mozstumbler.service.utils.NetworkUtils; import org.mozilla.mozstumbler.service.utils.PersistentIntentService; @@ -68,8 +68,8 @@ public class StumblerService extends PersistentIntentService mScanManager.setWifiBlockList(list); } - public Prefs getPrefs() { - return Prefs.getInstance(); + public Prefs getPrefs(Context c) { + return Prefs.getInstance(c); } public void checkPrefs() { @@ -116,7 +116,8 @@ public class StumblerService extends PersistentIntentService // use (i.e. Fennec), init() can be called from this class's dedicated thread. // Safe to call more than once, ensure added code complies with that intent. protected void init() { - Prefs.createGlobalInstance(this); + // Ensure Prefs is created, so internal utility code can use getInstanceWithoutContext + Prefs.getInstance(this); NetworkUtils.createGlobalInstance(this); DataStorageManager.createGlobalInstance(this, this); @@ -150,7 +151,7 @@ public class StumblerService extends PersistentIntentService } if (!sFirefoxStumblingEnabled.get()) { - Prefs.getInstance().setFirefoxScanEnabled(false); + Prefs.getInstance(StumblerService.this).setFirefoxScanEnabled(false); } if (DataStorageManager.getInstance() != null) { @@ -182,7 +183,7 @@ public class StumblerService extends PersistentIntentService return; } - final boolean isScanEnabledInPrefs = Prefs.getInstance().getFirefoxScanEnabled(); + final boolean isScanEnabledInPrefs = Prefs.getInstance(this).getFirefoxScanEnabled(); if (!isScanEnabledInPrefs && intent.getBooleanExtra(ACTION_NOT_FROM_HOST_APP, false)) { stopSelf(); @@ -198,7 +199,7 @@ public class StumblerService extends PersistentIntentService // This is the only upload trigger in Firefox mode // Firefox triggers this ~4 seconds after startup (after Gecko is loaded), add a small delay to avoid // clustering with other operations that are triggered at this time. - final long lastAttemptedTime = Prefs.getInstance().getLastAttemptedUploadTime(); + final long lastAttemptedTime = Prefs.getInstance(this).getLastAttemptedUploadTime(); final long timeNow = System.currentTimeMillis(); if (timeNow - lastAttemptedTime < PASSIVE_UPLOAD_FREQ_GUARD_MSEC) { @@ -207,23 +208,23 @@ public class StumblerService extends PersistentIntentService Log.d(LOG_TAG, "Upload attempt too frequent."); } } else { - Prefs.getInstance().setLastAttemptedUploadTime(timeNow); + Prefs.getInstance(this).setLastAttemptedUploadTime(timeNow); UploadAlarmReceiver.scheduleAlarm(this, DELAY_IN_SEC_BEFORE_STARTING_UPLOAD_IN_PASSIVE_MODE, false /* no repeat*/); } } if (!isScanEnabledInPrefs) { - Prefs.getInstance().setFirefoxScanEnabled(true); + Prefs.getInstance(this).setFirefoxScanEnabled(true); } String apiKey = intent.getStringExtra(ACTION_EXTRA_MOZ_API_KEY); - if (apiKey != null && !apiKey.equals(Prefs.getInstance().getMozApiKey())) { - Prefs.getInstance().setMozApiKey(apiKey); + if (apiKey != null && !apiKey.equals(Prefs.getInstance(this).getMozApiKey())) { + Prefs.getInstance(this).setMozApiKey(apiKey); } String userAgent = intent.getStringExtra(ACTION_EXTRA_USER_AGENT); - if (userAgent != null && !userAgent.equals(Prefs.getInstance().getUserAgent())) { - Prefs.getInstance().setUserAgent(userAgent); + if (userAgent != null && !userAgent.equals(Prefs.getInstance(this).getUserAgent())) { + Prefs.getInstance(this).setUserAgent(userAgent); } if (!mScanManager.isScanning()) { diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java index 6d4a61131c56..071e6229450e 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/GPSScanner.java @@ -164,7 +164,11 @@ public class GPSScanner implements LocationListener { mBlockList.updateBlocks(); } - mAutoGeofencing = Prefs.getInstance().getGeofenceHere(); + Prefs prefs = Prefs.getInstanceWithoutContext(); + if (prefs == null) { + return; + } + mAutoGeofencing = prefs.getGeofenceHere(); } public boolean isGeofenced() { @@ -186,7 +190,7 @@ public class GPSScanner implements LocationListener { String provider = location.getProvider(); if (!provider.toLowerCase().contains("gps")) { - sendToLogActivity(logMsg + "Discard fused/network location."); + Log.d(LOG_TAG, "Discard fused/network location."); // only interested in GPS locations return; } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/LocationBlockList.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/LocationBlockList.java index 165852efe92a..c3cba7b45358 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/LocationBlockList.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/LocationBlockList.java @@ -28,8 +28,12 @@ public final class LocationBlockList { } public void updateBlocks() { - mBlockedLocation = Prefs.getInstance().getGeofenceLocation(); - mGeofencingEnabled = Prefs.getInstance().getGeofenceEnabled(); + Prefs prefs = Prefs.getInstanceWithoutContext(); + if (prefs == null) { + return; + } + mBlockedLocation = prefs.getGeofenceLocation(); + mGeofencingEnabled = prefs.getGeofenceEnabled(); } public boolean contains(Location location) { diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java index 9d5e8d416221..eed61d8bbf4f 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/stumblerthread/scanners/WifiScanner.java @@ -74,12 +74,13 @@ public class WifiScanner extends BroadcastReceiver { public synchronized void start(final ActiveOrPassiveStumbling stumblingMode) { - if (mStarted) { + Prefs prefs = Prefs.getInstanceWithoutContext(); + if (mStarted || prefs == null) { return; } mStarted = true; - boolean scanAlways = Prefs.getInstance().getWifiScanAlways(); + boolean scanAlways = prefs.getWifiScanAlways(); if (scanAlways || isWifiEnabled()) { activatePeriodicScan(stumblingMode); diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java index df37a0c39e0e..64e4746cddcc 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/AsyncUploader.java @@ -112,10 +112,6 @@ public class AsyncUploader extends AsyncTask { private class Submitter extends AbstractCommunicator { private static final String SUBMIT_URL = "https://location.services.mozilla.com/v1/submit"; - public Submitter() { - super(Prefs.getInstance().getUserAgent()); - } - @Override public String getUrlString() { return SUBMIT_URL; diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java index 3780e47021d7..9292cee5bb0c 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/uploadthread/UploadAlarmReceiver.java @@ -78,9 +78,9 @@ public class UploadAlarmReceiver extends BroadcastReceiver { !AsyncUploader.isUploading()) { Log.d(LOG_TAG, "Alarm upload(), call AsyncUploader"); AsyncUploader.UploadSettings settings = - new AsyncUploader.UploadSettings(Prefs.getInstance().getWifiScanAlways(), Prefs.getInstance().getUseWifiOnly()); + new AsyncUploader.UploadSettings(Prefs.getInstance(this).getWifiScanAlways(), Prefs.getInstance(this).getUseWifiOnly()); AsyncUploader uploader = new AsyncUploader(settings, null); - uploader.setNickname(Prefs.getInstance().getNickname()); + uploader.setNickname(Prefs.getInstance(this).getNickname()); uploader.execute(); // we could listen for completion and cancel, instead, cancel on next alarm when db empty } diff --git a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/AbstractCommunicator.java b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/AbstractCommunicator.java index 59ee78e979b1..70816371a39c 100644 --- a/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/AbstractCommunicator.java +++ b/mobile/android/stumbler/java/org/mozilla/mozstumbler/service/utils/AbstractCommunicator.java @@ -61,14 +61,16 @@ public abstract class AbstractCommunicator { return null; } - public AbstractCommunicator(String userAgent) { - mUserAgent = userAgent; + public AbstractCommunicator() { + Prefs prefs = Prefs.getInstanceWithoutContext(); + mUserAgent = (prefs != null)? prefs.getUserAgent() : "fennec-stumbler-unset-user-agent"; } private void openConnectionAndSetHeaders() { try { - if (sMozApiKey == null) { - sMozApiKey = Prefs.getInstance().getMozApiKey(); + Prefs prefs = Prefs.getInstanceWithoutContext(); + if (sMozApiKey == null || prefs != null) { + sMozApiKey = prefs.getMozApiKey(); } URL url = new URL(getUrlString() + "?key=" + sMozApiKey); mHttpURLConnection = (HttpURLConnection) url.openConnection(); From 62ebb2ebd708b6bbdb62c2f2c45944e51602fcd0 Mon Sep 17 00:00:00 2001 From: Nivvedan S Date: Thu, 11 Dec 2014 21:40:04 -0800 Subject: [PATCH 17/36] Bug 1109233 - Replaced Assert.isTrue(false, ...) with Assert.fail(...) for easier readability; r=mcomella --- mobile/android/base/overlays/service/OverlayActionService.java | 2 +- .../android/base/overlays/ui/SendTabDeviceListArrayAdapter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/android/base/overlays/service/OverlayActionService.java b/mobile/android/base/overlays/service/OverlayActionService.java index fea82cf3f200..1f0937dac1f8 100644 --- a/mobile/android/base/overlays/service/OverlayActionService.java +++ b/mobile/android/base/overlays/service/OverlayActionService.java @@ -135,7 +135,7 @@ public class OverlayActionService extends Service { OverlayToastHelper.showFailureToast(getApplicationContext(), shareMethod.getFailureMessage()); break; default: - Assert.isTrue(false, "Unknown share method result code: " + result); + Assert.fail("Unknown share method result code: " + result); break; } } diff --git a/mobile/android/base/overlays/ui/SendTabDeviceListArrayAdapter.java b/mobile/android/base/overlays/ui/SendTabDeviceListArrayAdapter.java index 32c6054ad88d..1f885af6767e 100644 --- a/mobile/android/base/overlays/ui/SendTabDeviceListArrayAdapter.java +++ b/mobile/android/base/overlays/ui/SendTabDeviceListArrayAdapter.java @@ -163,7 +163,7 @@ public class SendTabDeviceListArrayAdapter extends ArrayAdapter Date: Thu, 11 Dec 2014 22:47:41 +0100 Subject: [PATCH 18/36] Bug 1109112 - Avoid highlighter exceptions after reloading the page; r=miker --- toolkit/devtools/server/actors/highlighter.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/toolkit/devtools/server/actors/highlighter.js b/toolkit/devtools/server/actors/highlighter.js index bc9ea1da67e7..dc47bf74d597 100644 --- a/toolkit/devtools/server/actors/highlighter.js +++ b/toolkit/devtools/server/actors/highlighter.js @@ -684,16 +684,15 @@ AutoRefreshHighlighter.prototype = { _startRefreshLoop: function() { let win = this.currentNode.ownerDocument.defaultView; this.rafID = win.requestAnimationFrame(this._startRefreshLoop.bind(this)); + this.rafWin = win; this.update(); }, _stopRefreshLoop: function() { - if (!this.rafID) { - return; + if (this.rafID && !Cu.isDeadWrapper(this.rafWin)) { + this.rafWin.cancelAnimationFrame(this.rafID); } - let win = this.currentNode.ownerDocument.defaultView; - win.cancelAnimationFrame(this.rafID); - this.rafID = null; + this.rafID = this.rafWin = null; }, destroy: function() { From 08736c299fcecd96d11f9c03daff1ae0fbbe8ee0 Mon Sep 17 00:00:00 2001 From: Anthony Jones Date: Fri, 12 Dec 2014 17:11:51 +1300 Subject: [PATCH 19/36] Bug 1110595 - Fix MSE playback stalling; r=mattwoodrow --- dom/media/mediasource/MediaSourceReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index c4ae0cc40455..663b8e80da69 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -268,7 +268,7 @@ MediaSourceReader::OnVideoNotDecoded(NotDecodedReason aReason) // switching to the end of the buffered range. MOZ_ASSERT(aReason == END_OF_STREAM); if (mVideoReader) { - AdjustEndTime(&mLastVideoTime, mAudioReader); + AdjustEndTime(&mLastVideoTime, mVideoReader); } // See if we can find a different reader that can pick up where we left off. We use the From 05871a3a208fde3f180145a2d6147d9442c3c474 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:44:48 -0800 Subject: [PATCH 20/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - loadinfo changes (r=sicking) --- docshell/base/LoadInfo.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/docshell/base/LoadInfo.cpp b/docshell/base/LoadInfo.cpp index 068408c9f350..e2e8c2c4c637 100644 --- a/docshell/base/LoadInfo.cpp +++ b/docshell/base/LoadInfo.cpp @@ -20,16 +20,23 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsIURI* aBaseURI) - : mLoadingPrincipal(aLoadingPrincipal) + : mLoadingPrincipal(aLoadingContext ? + aLoadingContext->NodePrincipal() : aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal ? - aTriggeringPrincipal : aLoadingPrincipal) + aTriggeringPrincipal : mLoadingPrincipal.get()) , mLoadingContext(do_GetWeakReference(aLoadingContext)) , mSecurityFlags(aSecurityFlags) , mContentPolicyType(aContentPolicyType) , mBaseURI(aBaseURI) { - MOZ_ASSERT(aLoadingPrincipal); + MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); + + // if consumers pass both, aLoadingContext and aLoadingPrincipal + // then the loadingPrincipal must be the same as the node's principal + MOZ_ASSERT(!aLoadingContext || !aLoadingPrincipal || + aLoadingContext->NodePrincipal() == aLoadingPrincipal); + // if the load is sandboxed, we can not also inherit the principal if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) { mSecurityFlags ^= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL; From 5a98bf956c6260dfd6edd9988cbc99246dd080cc Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:45:16 -0800 Subject: [PATCH 21/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - netUtil changes (r=sicking,sworkman) --- netwerk/base/public/nsNetUtil.h | 286 ++++++++++++++++++++------------ 1 file changed, 184 insertions(+), 102 deletions(-) diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 9fe75cf5489d..43516b622226 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -188,24 +188,80 @@ NS_NewFileURI(nsIURI* *result, } /* - * How to create a new Channel using NS_NewChannel: - * 1) Please try to call NS_NewChannel providing a requesting *nsINode* - * 2) If no requesting nsINode is available, - * call NS_NewChannel providing a requesting *nsIPrincipal*. - * 3) Call NS_NewChannelInternal *only* if requesting Principal and - * the Node's Principal have to be different. - * >> Most likely this is not the case! << - * Needs special approval! - */ +* How to create a new Channel, using NS_NewChannel, +* NS_NewChannelWithTriggeringPrincipal, NS_OpenURI, +* NS_NewInputStreamChannel, NS_NewChannelInternal +* and it's variations: +* +* @param aURI +* nsIURI from which to make a channel +* @param aLoadingNode +* The loadingDocument of the channel. +* The element or document where the result of this request will be +* used. This is the document/element that will get access to the +* result of this request. For example for an image load, it's the +* document in which the image will be loaded. And for a CSS +* stylesheet it's the document whose rendering will be affected by +* the stylesheet. +* If possible, pass in the element which is performing the load. But +* if the load is coming from a JS API (such as XMLHttpRequest) or if +* the load might be coalesced across multiple elements (such as +* for ) then pass in the Document node instead. +* For loads that are not related to any document, such as loads coming +* from addons or internal browser features, use null here. +* @param aLoadingPrincipal +* The loadingPrincipal of the channel. +* The principal of the document where the result of this request will be used. +* This is generally the principal of the aLoadingNode. However for +* loads where aLoadingNode is null this argument still needs to be +* passed. For example for loads from a WebWorker, pass the principal +* of that worker. For loads from an addon or from internal browser +* features, pass the system principal. +* This principal should almost always be the system principal if +* aLoadingNode is null. The only exception to this is for loads +* from WebWorkers since they don't have any nodes to be passed as +* aLoadingNode. Please note, aLoadingPrincipal is *not* the +* principal of the resource being loaded. But rather the principal +* of the context where the resource will be used. +* @param aTriggeringPrincipal +* The triggeringPrincipal of the load. +* The triggeringPrincipal is the principal of the resource that caused +* this particular URL to be loaded. +* Most likely the triggeringPrincipal and the loadingPrincipal are +* identical, in which case the triggeringPrincipal can be left out. +* In some cases the loadingPrincipal and the triggeringPrincipal are +* different however, e.g. a stylesheet may import a subresource. In +* that case the principal of the stylesheet which contains the +* import command is the triggeringPrincipal, and the principal of +* the document whose rendering is affected is the loadingPrincipal. +* @param aSecurityFlags +* The securityFlags of the channel. +* Any of the securityflags defined in nsILoadInfo.idl +* @param aContentPolicyType +* The contentPolicyType of the channel. +* Any of the content types defined in nsIContentPolicy.idl +* +* Please note, if you provide a loadingNode, then the loadingPrincipal +* must match the loadingNode->NodePrincipal(). Alternatively you can +* discard the loadingPrincipal if you provide a loadingNode. +* +* What specific API function to use: +* * If possible try to call NS_NewChannel() providing a loading *nsINode* +* * If no loading *nsINode* is avaialable, call NS_NewChannel() providing +* a loading *nsIPrincipal*. +* * Call NS_NewChannelWithTriggeringPrincipal() if the loading principal +* and the Node's principal have to be different (see above). +* * Call NS_NewChannelInternal() providing aLoadInfo object in cases where +* you already have loadInfo object, e.g in case of a channel redirect. +*/ inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, + nsINode* aLoadingNode, + nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, - nsIURI* aBaseURI = nullptr, nsILoadGroup* aLoadGroup = nullptr, nsIInterfaceRequestor* aCallbacks = nullptr, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, @@ -218,7 +274,15 @@ NS_NewChannelInternal(nsIChannel** outChannel, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr channel; - rv = aIoService->NewChannelFromURI(aUri, getter_AddRefs(channel)); + rv = aIoService->NewChannelFromURI2( + aUri, + aLoadingNode ? + aLoadingNode->AsDOMNode() : nullptr, + aLoadingPrincipal, + aTriggeringPrincipal, + aSecurityFlags, + aContentPolicyType, + getter_AddRefs(channel)); NS_ENSURE_SUCCESS(rv, rv); if (aLoadGroup) { @@ -252,9 +316,9 @@ NS_NewChannelInternal(nsIChannel** outChannel, // create a new Loadinfo with the potentially updated securityFlags loadInfo = - new mozilla::LoadInfo(aRequestingPrincipal, aTriggeringPrincipal, - aRequestingNode, aSecurityFlags, - aContentPolicyType, aBaseURI); + new mozilla::LoadInfo(aLoadingPrincipal, aTriggeringPrincipal, + aLoadingNode, aSecurityFlags, + aContentPolicyType); if (!loadInfo) { return NS_ERROR_UNEXPECTED; } @@ -270,6 +334,7 @@ NS_NewChannelInternal(nsIChannel** outChannel, return NS_OK; } +// See NS_NewChannelInternal for usage and argument description inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, nsIURI* aUri, @@ -287,19 +352,22 @@ NS_NewChannelInternal(nsIChannel** outChannel, aLoadInfo->TriggeringPrincipal(), aLoadInfo->GetSecurityFlags(), aLoadInfo->GetContentPolicyType(), - aLoadInfo->BaseURI(), aLoadGroup, aCallbacks, aLoadFlags, aIoService); NS_ENSURE_SUCCESS(rv, rv); + // Please note that we still call SetLoadInfo on the channel because + // we want the same instance of the loadInfo to be set on the channel. + (*outChannel)->SetLoadInfo(aLoadInfo); return NS_OK; } +// See NS_NewChannelInternal for usage and argument description inline nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aRequestingNode, + nsINode* aLoadingNode, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -308,26 +376,26 @@ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - MOZ_ASSERT(aRequestingNode); + MOZ_ASSERT(aLoadingNode); NS_ASSERTION(aTriggeringPrincipal, "Can not create channel without a triggering Principal!"); return NS_NewChannelInternal(outChannel, aUri, - aRequestingNode, - aRequestingNode->NodePrincipal(), + aLoadingNode, + aLoadingNode->NodePrincipal(), aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, - nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, aIoService); } +// See NS_NewChannelInternal for usage and argument description inline nsresult /*NS_NewChannelWithPrincipalAndTriggeringPrincipal */ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsIURI* aUri, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -336,25 +404,25 @@ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); + NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!"); return NS_NewChannelInternal(outChannel, aUri, - nullptr, // aRequestingNode - aRequestingPrincipal, + nullptr, // aLoadingNode + aLoadingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, - nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, aIoService); } +// See NS_NewChannelInternal for usage and argument description inline nsresult /* NS_NewChannelNode */ NS_NewChannel(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aRequestingNode, + nsINode* aLoadingNode, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -362,25 +430,25 @@ NS_NewChannel(nsIChannel** outChannel, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aRequestingNode, "Can not create channel without a requesting Node!"); + NS_ASSERTION(aLoadingNode, "Can not create channel without a loading Node!"); return NS_NewChannelInternal(outChannel, aUri, - aRequestingNode, - aRequestingNode->NodePrincipal(), + aLoadingNode, + aLoadingNode->NodePrincipal(), nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, - nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, aIoService); } +// See NS_NewChannelInternal for usage and argument description inline nsresult /* NS_NewChannelPrincipal */ NS_NewChannel(nsIChannel** outChannel, nsIURI* aUri, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -390,12 +458,11 @@ NS_NewChannel(nsIChannel** outChannel, { return NS_NewChannelInternal(outChannel, aUri, - nullptr, // aRequestingNode, - aRequestingPrincipal, + nullptr, // aLoadingNode, + aLoadingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, - nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -409,8 +476,8 @@ NS_NewChannel(nsIChannel** outChannel, inline nsresult NS_OpenURIInternal(nsIInputStream** outStream, nsIURI* aUri, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, + nsINode* aLoadingNode, + nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -420,17 +487,16 @@ NS_OpenURIInternal(nsIInputStream** outStream, nsIIOService* aIoService = nullptr, // pass in nsIIOService to optimize callers nsIChannel** outChannel = nullptr) { - NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); + NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!"); nsCOMPtr channel; nsresult rv = NS_NewChannelInternal(getter_AddRefs(channel), aUri, - aRequestingNode, - aRequestingPrincipal, + aLoadingNode, + aLoadingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, - nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -451,7 +517,7 @@ NS_OpenURIInternal(nsIInputStream** outStream, inline nsresult /* NS_OpenURIprincipal */ NS_OpenURI(nsIInputStream** outStream, nsIURI* aUri, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -462,8 +528,8 @@ NS_OpenURI(nsIInputStream** outStream, { return NS_OpenURIInternal(outStream, aUri, - nullptr, // aRequestingNode - aRequestingPrincipal, + nullptr, // aLoadingNode + aLoadingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, @@ -477,7 +543,7 @@ NS_OpenURI(nsIInputStream** outStream, inline nsresult /* NS_OpenURIWithTriggeringPrincipalAndNode */ NS_OpenURIWithTriggeringPrincipal(nsIInputStream** outStream, nsIURI* aUri, - nsINode* aRequestingNode, + nsINode* aLoadingNode, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -487,12 +553,12 @@ NS_OpenURIWithTriggeringPrincipal(nsIInputStream** outStream, nsIIOService* aIoService = nullptr, nsIChannel** outChannel = nullptr) { - MOZ_ASSERT(aRequestingNode); + MOZ_ASSERT(aLoadingNode); NS_ASSERTION(aTriggeringPrincipal, "Can not open uri without a triggering Principal!"); return NS_OpenURIInternal(outStream, aUri, - aRequestingNode, - aRequestingNode->NodePrincipal(), + aLoadingNode, + aLoadingNode->NodePrincipal(), aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, @@ -529,8 +595,8 @@ inline nsresult NS_OpenURIInternal(nsIStreamListener* aListener, nsISupports* aContext, nsIURI* aUri, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, + nsINode* aLoadingNode, + nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -539,12 +605,12 @@ NS_OpenURIInternal(nsIStreamListener* aListener, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); + NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!"); nsCOMPtr loadInfo = - new mozilla::LoadInfo(aRequestingPrincipal, + new mozilla::LoadInfo(aLoadingPrincipal, aTriggeringPrincipal, - aRequestingNode, + aLoadingNode, aSecurityFlags, aContentPolicyType); if (!loadInfo) { @@ -564,7 +630,7 @@ inline nsresult NS_OpenURI(nsIStreamListener* aListener, nsISupports* aContext, nsIURI* aUri, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -575,8 +641,8 @@ NS_OpenURI(nsIStreamListener* aListener, return NS_OpenURIInternal(aListener, aContext, aUri, - nullptr, // aRequestingNode - aRequestingPrincipal, + nullptr, // aLoadingNode + aLoadingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, @@ -710,19 +776,15 @@ NS_GetRealPort(nsIURI* aURI) return NS_GetDefaultPort(scheme.get()); } -inline nsresult +inline nsresult /* NS_NewInputStreamChannelWithLoadInfo */ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, nsIURI* aUri, nsIInputStream* aStream, const nsACString& aContentType, const nsACString& aContentCharset, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, - nsIPrincipal* aTriggeringPrincipal, - nsSecurityFlags aSecurityFlags, - nsContentPolicyType aContentPolicyType, - nsIURI* aBaseURI = nullptr) + nsILoadInfo* aLoadInfo) { + MOZ_ASSERT(aLoadInfo, "can not create channel without a loadinfo"); nsresult rv; nsCOMPtr isc = do_CreateInstance(NS_INPUTSTREAMCHANNEL_CONTRACTID, &rv); @@ -745,21 +807,11 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, NS_ENSURE_SUCCESS(rv, rv); } - nsCOMPtr loadInfo = - new mozilla::LoadInfo(aRequestingPrincipal, - aTriggeringPrincipal, - aRequestingNode, - aSecurityFlags, - aContentPolicyType, - aBaseURI); - if (!loadInfo) { - return NS_ERROR_UNEXPECTED; - } - channel->SetLoadInfo(loadInfo); + channel->SetLoadInfo(aLoadInfo); // If we're sandboxed, make sure to clear any owner the channel // might already have. - if (loadInfo->GetLoadingSandboxed()) { + if (aLoadInfo->GetLoadingSandboxed()) { channel->SetOwner(nullptr); } @@ -767,11 +819,42 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, return NS_OK; } +inline nsresult +NS_NewInputStreamChannelInternal(nsIChannel** outChannel, + nsIURI* aUri, + nsIInputStream* aStream, + const nsACString& aContentType, + const nsACString& aContentCharset, + nsINode* aLoadingNode, + nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aTriggeringPrincipal, + nsSecurityFlags aSecurityFlags, + nsContentPolicyType aContentPolicyType, + nsIURI* aBaseURI = nullptr) +{ + nsCOMPtr loadInfo = + new mozilla::LoadInfo(aLoadingPrincipal, + aTriggeringPrincipal, + aLoadingNode, + aSecurityFlags, + aContentPolicyType, + aBaseURI); + if (!loadInfo) { + return NS_ERROR_UNEXPECTED; + } + return NS_NewInputStreamChannelInternal(outChannel, + aUri, + aStream, + aContentType, + aContentCharset, + loadInfo); +} + inline nsresult /* NS_NewInputStreamChannelPrincipal */ NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri, nsIInputStream* aStream, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, const nsACString& aContentType = EmptyCString(), @@ -782,8 +865,8 @@ NS_NewInputStreamChannel(nsIChannel** outChannel, aStream, aContentType, aContentCharset, - nullptr, // aRequestingNode - aRequestingPrincipal, + nullptr, // aLoadingNode + aLoadingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType); @@ -794,8 +877,8 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, nsIURI* aUri, const nsAString& aData, const nsACString& aContentType, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, + nsINode* aLoadingNode, + nsIPrincipal* aLoadingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -822,8 +905,8 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, stream, aContentType, NS_LITERAL_CSTRING("UTF-8"), - aRequestingNode, - aRequestingPrincipal, + aLoadingNode, + aLoadingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, @@ -845,7 +928,7 @@ NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri, const nsAString& aData, const nsACString& aContentType, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, bool aIsSrcdocChannel = false, @@ -855,8 +938,8 @@ NS_NewInputStreamChannel(nsIChannel** outChannel, aUri, aData, aContentType, - nullptr, // aRequestingNode - aRequestingPrincipal, + nullptr, // aLoadingNode + aLoadingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, @@ -969,8 +1052,8 @@ inline nsresult NS_NewStreamLoaderInternal(nsIStreamLoader** outStream, nsIURI* aUri, nsIStreamLoaderObserver* aObserver, - nsINode* aRequestingNode, - nsIPrincipal* aRequestingPrincipal, + nsINode* aLoadingNode, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsISupports* aContext = nullptr, @@ -982,12 +1065,11 @@ NS_NewStreamLoaderInternal(nsIStreamLoader** outStream, nsCOMPtr channel; nsresult rv = NS_NewChannelInternal(getter_AddRefs(channel), aUri, - aRequestingNode, - aRequestingPrincipal, + aLoadingNode, + aLoadingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, - nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags); @@ -1007,7 +1089,7 @@ inline nsresult /* NS_NewStreamLoaderNode */ NS_NewStreamLoader(nsIStreamLoader** outStream, nsIURI* aUri, nsIStreamLoaderObserver* aObserver, - nsINode* aRequestingNode, + nsINode* aLoadingNode, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsISupports* aContext = nullptr, @@ -1016,12 +1098,12 @@ NS_NewStreamLoader(nsIStreamLoader** outStream, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIURI* aReferrer = nullptr) { - NS_ASSERTION(aRequestingNode, "Can not create stream loader without a requesting Node!"); + NS_ASSERTION(aLoadingNode, "Can not create stream loader without a loading Node!"); return NS_NewStreamLoaderInternal(outStream, aUri, aObserver, - aRequestingNode, - aRequestingNode->NodePrincipal(), + aLoadingNode, + aLoadingNode->NodePrincipal(), aSecurityFlags, aContentPolicyType, aContext, @@ -1035,7 +1117,7 @@ inline nsresult /* NS_NewStreamLoaderPrincipal */ NS_NewStreamLoader(nsIStreamLoader** outStream, nsIURI* aUri, nsIStreamLoaderObserver* aObserver, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsISupports* aContext = nullptr, @@ -1047,8 +1129,8 @@ NS_NewStreamLoader(nsIStreamLoader** outStream, return NS_NewStreamLoaderInternal(outStream, aUri, aObserver, - nullptr, // aRequestingNode - aRequestingPrincipal, + nullptr, // aLoadingNode + aLoadingPrincipal, aSecurityFlags, aContentPolicyType, aContext, @@ -1664,14 +1746,14 @@ NS_ReadInputStreamToString(nsIInputStream *aInputStream, inline nsresult NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties** outResult, nsIURI* aUri, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsContentPolicyType aContentPolicyType, nsIIOService* aIoService = nullptr) { nsCOMPtr in; nsresult rv = NS_OpenURI(getter_AddRefs(in), aUri, - aRequestingPrincipal, + aLoadingPrincipal, nsILoadInfo::SEC_NORMAL, aContentPolicyType, nullptr, // aLoadGroup @@ -1694,7 +1776,7 @@ NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties** outResult, inline nsresult NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties** outResult, const nsACString& aSpec, - nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aLoadingPrincipal, nsContentPolicyType aContentPolicyType, const char* aCharset = nullptr, nsIURI* aBaseURI = nullptr, @@ -1710,7 +1792,7 @@ NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties** outResult, return NS_LoadPersistentPropertiesFromURI(outResult, uri, - aRequestingPrincipal, + aLoadingPrincipal, aContentPolicyType, aIoService); } From d9c268c606fa7f0d4fd61ea8db515416ed59c19c Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:45:30 -0800 Subject: [PATCH 22/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - ioservice/ changes (r=sicking,sworkman) --- netwerk/base/public/nsIIOService.idl | 54 ++++++++++++++++++- netwerk/base/public/nsIIOService2.idl | 55 ++++++++++++++++++- netwerk/base/src/nsIOService.cpp | 76 ++++++++++++++++++++++++--- 3 files changed, 175 insertions(+), 10 deletions(-) diff --git a/netwerk/base/public/nsIIOService.idl b/netwerk/base/public/nsIIOService.idl index 34a0714ef1e3..e9cdc8307220 100644 --- a/netwerk/base/public/nsIIOService.idl +++ b/netwerk/base/public/nsIIOService.idl @@ -67,8 +67,58 @@ interface nsIIOService : nsISupports /** * Creates a channel for a given URI. * - * @param aURI nsIURI from which to make a channel + * @param aURI + * nsIURI from which to make a channel + * @param aLoadingNode + * The loadingDocument of the channel. + * The element or document where the result of this request will be + * used. This is the document/element that will get access to the + * result of this request. For example for an image load, it's the + * document in which the image will be loaded. And for a CSS + * stylesheet it's the document whose rendering will be affected by + * the stylesheet. + * If possible, pass in the element which is performing the load. But + * if the load is coming from a JS API (such as XMLHttpRequest) or if + * the load might be coalesced across multiple elements (such as + * for ) then pass in the Document node instead. + * For loads that are not related to any document, such as loads coming + * from addons or internal browser features, use null here. + * @param aLoadingPrincipal + * The loadingPrincipal of the channel. + * The principal of the document where the result of this request will be used. + * This is generally the principal of the aLoadingNode. However for + * loads where aLoadingNode is null this argument still needs to be + * passed. For example for loads from a WebWorker, pass the principal + * of that worker. For loads from an addon or from internal browser + * features, pass the system principal. + * This principal should almost always be the system principal if + * aLoadingNode is null. The only exception to this is for loads + * from WebWorkers since they don't have any nodes to be passed as + * aLoadingNode. Please note, aLoadingPrincipal is *not* the + * principal of the resource being loaded. But rather the principal + * of the context where the resource will be used. + * @param aTriggeringPrincipal + * The triggeringPrincipal of the load. + * The triggeringPrincipal is the principal of the resource that caused + * this particular URL to be loaded. + * Most likely the triggeringPrincipal and the loadingPrincipal are + * identical, in which case the triggeringPrincipal can be left out. + * In some cases the loadingPrincipal and the triggeringPrincipal are + * different however, e.g. a stylesheet may import a subresource. In + * that case the principal of the stylesheet which contains the + * import command is the triggeringPrincipal, and the principal of + * the document whose rendering is affected is the loadingPrincipal. + * @param aSecurityFlags + * The securityFlags of the channel. + * Any of the securityflags defined in nsILoadInfo.idl + * @param aContentPolicyType + * The contentPolicyType of the channel. + * Any of the content types defined in nsIContentPolicy.idl * @return reference to the new nsIChannel object + * + * Please note, if you provide a loadingNode, then the loadingPrincipal + * must match the loadingNode->NodePrincipal(). Alternatively you can + * discard the loadingPrincipal if you provide a loadingNode. */ nsIChannel newChannelFromURI2(in nsIURI aURI, in nsIDOMNode aLoadingNode, @@ -86,7 +136,7 @@ interface nsIIOService : nsISupports nsIChannel newChannelFromURI(in nsIURI aURI); /** - * Equivalent to newChannelFromURI(newURI(...)) + * Equivalent to newChannelFromURI2(newURI(...)) */ nsIChannel newChannel2(in AUTF8String aSpec, in string aOriginCharset, diff --git a/netwerk/base/public/nsIIOService2.idl b/netwerk/base/public/nsIIOService2.idl index 394a5d8b0873..a17193363ddd 100644 --- a/netwerk/base/public/nsIIOService2.idl +++ b/netwerk/base/public/nsIIOService2.idl @@ -33,12 +33,63 @@ interface nsIIOService2 : nsIIOService /** * Creates a channel for a given URI. * - * @param aURI nsIURI from which to make a channel - * @param aProxyURI nsIURI to use for proxy resolution. Can be null in which + * @param aURI + * nsIURI from which to make a channel + * @param aProxyURI + * nsIURI to use for proxy resolution. Can be null in which * case aURI is used * @param aProxyFlags flags from nsIProtocolProxyService to use * when resolving proxies for this new channel + * @param aLoadingNode + * The loadingDocument of the channel. + * The element or document where the result of this request will be + * used. This is the document/element that will get access to the + * result of this request. For example for an image load, it's the + * document in which the image will be loaded. And for a CSS + * stylesheet it's the document whose rendering will be affected by + * the stylesheet. + * If possible, pass in the element which is performing the load. But + * if the load is coming from a JS API (such as XMLHttpRequest) or if + * the load might be coalesced across multiple elements (such as + * for ) then pass in the Document node instead. + * For loads that are not related to any document, such as loads coming + * from addons or internal browser features, use null here. + * @param aLoadingPrincipal + * The loadingPrincipal of the channel. + * The principal of the document where the result of this request will be used. + * This is generally the principal of the aLoadingNode. However for + * loads where aLoadingNode is null this argument still needs to be + * passed. For example for loads from a WebWorker, pass the principal + * of that worker. For loads from an addon or from internal browser + * features, pass the system principal. + * This principal should almost always be the system principal if + * aLoadingNode is null. The only exception to this is for loads + * from WebWorkers since they don't have any nodes to be passed as + * aLoadingNode. Please note, aLoadingPrincipal is *not* the + * principal of the resource being loaded. But rather the principal + * of the context where the resource will be used. + * @param aTriggeringPrincipal + * The triggeringPrincipal of the load. + * The triggeringPrincipal is the principal of the resource that caused + * this particular URL to be loaded. + * Most likely the triggeringPrincipal and the loadingPrincipal are + * identical, in which case the triggeringPrincipal can be left out. + * In some cases the loadingPrincipal and the triggeringPrincipal are + * different however, e.g. a stylesheet may import a subresource. In + * that case the principal of the stylesheet which contains the + * import command is the triggeringPrincipal, and the principal of + * the document whose rendering is affected is the loadingPrincipal. + * @param aSecurityFlags + * The securityFlags of the channel. + * Any of the securityflags defined in nsILoadInfo.idl + * @param aContentPolicyType + * The contentPolicyType of the channel. + * Any of the content types defined in nsIContentPolicy.idl * @return reference to the new nsIChannel object + * + * Please note, if you provide a loadingNode, then the loadingPrincipal + * must match the loadingNode->NodePrincipal(). Alternatively you can + * discard the loadingPrincipal if you provide a loadingNode. */ nsIChannel newChannelFromURIWithProxyFlags2(in nsIURI aURI, in nsIURI aProxyURI, diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp index 92d669742cb2..c6de4cb6beb1 100644 --- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -40,6 +40,7 @@ #include "MainThreadUtils.h" #include "nsIWidget.h" #include "nsThreadUtils.h" +#include "mozilla/LoadInfo.h" #include "mozilla/net/NeckoCommon.h" #ifdef MOZ_WIDGET_GONK @@ -634,13 +635,76 @@ nsIOService::NewChannelFromURIWithProxyFlags2(nsIURI* aURI, if (NS_FAILED(rv)) return rv; + // Ideally we are creating new channels by calling NewChannel2 (NewProxiedChannel2). + // Keep in mind that Addons can implement their own Protocolhandlers, hence + // NewChannel2() might *not* be implemented. + // We do not want to break those addons, therefore we first try to create a channel + // calling NewChannel2(); if that fails we fall back to creating a channel by calling + // NewChannel(); + + nsCOMPtr loadInfo; + // Unfortunately not all callsites (see Bug 1087720, and 1099296) have been updated + // yet to call NewChannel2() instead of NewChannel(), hence those callsites do not + // provide the necessary loadinfo arguments yet. + // Since creating a new loadInfo requires 'aLoadingPrincipal' or 'aLoadingNode' we + // can branch on those arguments as an interim solution. + // + // BUG 1087720: Once that bug lands, we should have a loadInfo for all callers of + // NewChannelFromURIWithProxyFlags2() and should remove the *if* before creating a + // a new loadinfo. + if (aLoadingNode || aLoadingPrincipal) { + nsCOMPtr loadingNode(do_QueryInterface(aLoadingNode)); + loadInfo = new mozilla::LoadInfo(aLoadingPrincipal, + aTriggeringPrincipal, + loadingNode, + aSecurityFlags, + aContentPolicyType); + if (!loadInfo) { + return NS_ERROR_UNEXPECTED; + } + } + + bool newChannel2Succeeded = true; + nsCOMPtr pph = do_QueryInterface(handler); - if (pph) - rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, result); - else - rv = handler->NewChannel(aURI, result); - if (NS_FAILED(rv)) - return rv; + if (pph) { + rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI, + loadInfo, result); + // if calling NewProxiedChannel2() fails we try to fall back to + // creating a new proxied channel by calling NewProxiedChannel(). + if (NS_FAILED(rv)) { + newChannel2Succeeded = false; + rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, + result); + } + } + else { + rv = handler->NewChannel2(aURI, loadInfo, result); + // if calling newChannel2() fails we try to fall back to + // creating a new channel by calling NewChannel(). + if (NS_FAILED(rv)) { + newChannel2Succeeded = false; + rv = handler->NewChannel(aURI, result); + } + } + NS_ENSURE_SUCCESS(rv, rv); + + if ((aLoadingNode || aLoadingPrincipal) && newChannel2Succeeded) { + // Make sure that all the individual protocolhandlers attach + // a loadInfo within it's implementation of ::newChannel2(). + // Once Bug 1087720 lands, we should remove the surrounding + // if-clause here and always assert that we indeed have a + // loadinfo on the newly created channel. + nsCOMPtr loadInfo; + (*result)->GetLoadInfo(getter_AddRefs(loadInfo)); + MOZ_ASSERT(loadInfo); + + // If we're sandboxed, make sure to clear any owner the channel + // might already have. + if (loadInfo->GetLoadingSandboxed()) { + (*result)->SetOwner(nullptr); + } + } // Some extensions override the http protocol handler and provide their own // implementation. The channels returned from that implementation doesn't From 235e03cc768fafd1d717c13fb5d90c0b76134b95 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:45:43 -0800 Subject: [PATCH 23/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - chrome/ changes (r=sicking) --- chrome/nsChromeProtocolHandler.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/chrome/nsChromeProtocolHandler.cpp b/chrome/nsChromeProtocolHandler.cpp index fa40425b0d23..f339a89cab35 100644 --- a/chrome/nsChromeProtocolHandler.cpp +++ b/chrome/nsChromeProtocolHandler.cpp @@ -100,7 +100,7 @@ nsChromeProtocolHandler::NewURI(const nsACString &aSpec, NS_IMETHODIMP nsChromeProtocolHandler::NewChannel2(nsIURI* aURI, - nsILoadInfo* aLoadinfo, + nsILoadInfo* aLoadInfo, nsIChannel** aResult) { nsresult rv; @@ -147,12 +147,22 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI, return rv; } - nsCOMPtr ioServ(do_GetIOService(&rv)); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() instead of NewChannel() + // we should have a non-null loadInfo consistently. Until then we have to branch on the + // loadInfo. + if (aLoadInfo) { + rv = NS_NewChannelInternal(getter_AddRefs(result), + resolvedURI, + aLoadInfo); + } + else { + nsCOMPtr ioServ(do_GetIOService(&rv)); + NS_ENSURE_SUCCESS(rv, rv); + rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result)); + } NS_ENSURE_SUCCESS(rv, rv); - rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result)); - if (NS_FAILED(rv)) return rv; - #ifdef DEBUG nsCOMPtr fileChan(do_QueryInterface(result)); if (fileChan) { From ce7c3e7aa804ee16427dbd42d63da53775bcbc2e Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:45:56 -0800 Subject: [PATCH 24/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - dom/ changes (r=sicking) --- dom/base/nsHostObjectProtocolHandler.cpp | 29 +++++++++++++++++------- dom/jsurl/nsJSProtocolHandler.cpp | 5 ++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/dom/base/nsHostObjectProtocolHandler.cpp b/dom/base/nsHostObjectProtocolHandler.cpp index ba20807753d7..838e54da057d 100644 --- a/dom/base/nsHostObjectProtocolHandler.cpp +++ b/dom/base/nsHostObjectProtocolHandler.cpp @@ -485,7 +485,7 @@ nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec, NS_IMETHODIMP nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri, - nsILoadInfo *aLoadinfo, + nsILoadInfo* aLoadInfo, nsIChannel** result) { *result = nullptr; @@ -519,13 +519,26 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr channel; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - uri, - stream, - info->mPrincipal, - nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, - nsIContentPolicy::TYPE_OTHER); - + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() instead of NewChannel() + // we should have a non-null loadInfo consistently. Until then we have to brach on the + // loadInfo and provide default arguments to create a NewInputStreamChannel. + if (aLoadInfo) { + rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), + uri, + stream, + EmptyCString(), // aContentType + EmptyCString(), // aContentCharset + aLoadInfo); + } + else { + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + uri, + stream, + info->mPrincipal, + nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, + nsIContentPolicy::TYPE_OTHER); + } NS_ENSURE_SUCCESS(rv, rv); nsString type; diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 12ed881d54dd..4faaa4ca5e88 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -1223,6 +1223,11 @@ nsJSProtocolHandler::NewChannel2(nsIURI* uri, NS_ADDREF(channel); rv = channel->Init(uri); + + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + if (NS_SUCCEEDED(rv)) { *result = channel; NS_ADDREF(*result); From e9734384ca9979008322a8dcba9c3be71d6eab70 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:46:09 -0800 Subject: [PATCH 25/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - extensions/ changes (r=karlt) --- extensions/gio/nsGIOProtocolHandler.cpp | 26 ++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/extensions/gio/nsGIOProtocolHandler.cpp b/extensions/gio/nsGIOProtocolHandler.cpp index c989e6dcdfaa..dd82fdf356aa 100644 --- a/extensions/gio/nsGIOProtocolHandler.cpp +++ b/extensions/gio/nsGIOProtocolHandler.cpp @@ -1059,12 +1059,23 @@ nsGIOProtocolHandler::NewChannel2(nsIURI* aURI, return rv; nsRefPtr stream = new nsGIOInputStream(spec); - if (!stream) - { - rv = NS_ERROR_OUT_OF_MEMORY; + if (!stream) { + return NS_ERROR_OUT_OF_MEMORY; } - else - { + + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() instead of NewChannel() + // we should have a non-null loadInfo consistently. Until then we have to brach on the + // loadInfo and provide default arguments to create a NewInputStreamChannel. + if (aLoadInfo) { + rv = NS_NewInputStreamChannelInternal(aResult, + aURI, + stream, + NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE), + EmptyCString(), // aContentCharset + aLoadInfo); + } + else { nsCOMPtr nullPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -1078,8 +1089,9 @@ nsGIOProtocolHandler::NewChannel2(nsIURI* aURI, nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE)); - if (NS_SUCCEEDED(rv)) - stream->SetChannel(*aResult); + } + if (NS_SUCCEEDED(rv)) { + stream->SetChannel(*aResult); } return rv; } From 3cb88a3412bc84bf31c02cb56ed382aee5cf5ee2 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:46:22 -0800 Subject: [PATCH 26/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - image/ changes (r=seth) --- image/decoders/icon/nsIconProtocolHandler.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/image/decoders/icon/nsIconProtocolHandler.cpp b/image/decoders/icon/nsIconProtocolHandler.cpp index 513e11336410..eb3ded06a18d 100644 --- a/image/decoders/icon/nsIconProtocolHandler.cpp +++ b/image/decoders/icon/nsIconProtocolHandler.cpp @@ -96,6 +96,13 @@ nsIconProtocolHandler::NewChannel2(nsIURI* url, return rv; } + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + NS_RELEASE(channel); + return rv; + } + *result = channel; return NS_OK; } From 26022ca095ff3b8b5a5a56cd390441bc5903242a Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:46:34 -0800 Subject: [PATCH 27/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - modules/ changes (r=mwu) --- modules/libjar/nsJARProtocolHandler.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/libjar/nsJARProtocolHandler.cpp b/modules/libjar/nsJARProtocolHandler.cpp index b076d85e68e1..eb789ee6efff 100644 --- a/modules/libjar/nsJARProtocolHandler.cpp +++ b/modules/libjar/nsJARProtocolHandler.cpp @@ -223,6 +223,13 @@ nsJARProtocolHandler::NewChannel2(nsIURI* uri, return rv; } + // set the loadInfo on the new channel + rv = chan->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + NS_RELEASE(chan); + return rv; + } + *result = chan; return NS_OK; } From 9266af29403ecb5dac772e5a9bda71689f96d6cd Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:46:47 -0800 Subject: [PATCH 28/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - netwerk/ changes (r=sworkman,sicking) --- .../base/public/nsIProxiedProtocolHandler.idl | 1 + netwerk/protocol/about/nsAboutBlank.cpp | 30 ++++++++++++++----- netwerk/protocol/about/nsAboutBloat.cpp | 30 ++++++++++++++----- netwerk/protocol/about/nsAboutCache.cpp | 30 ++++++++++++++----- netwerk/protocol/about/nsAboutCacheEntry.cpp | 13 +++++++- .../protocol/about/nsAboutProtocolHandler.cpp | 10 +++++++ netwerk/protocol/app/AppProtocolHandler.cpp | 12 ++++++-- netwerk/protocol/data/nsDataHandler.cpp | 7 +++++ .../device/nsDeviceProtocolHandler.cpp | 4 +++ .../protocol/file/nsFileProtocolHandler.cpp | 7 +++++ netwerk/protocol/ftp/nsFtpProtocolHandler.cpp | 10 +++++-- netwerk/protocol/http/nsHttpHandler.cpp | 10 +++++-- netwerk/protocol/res/nsResProtocolHandler.cpp | 23 ++++++++++---- netwerk/protocol/rtsp/RtspHandler.cpp | 4 +++ .../viewsource/nsViewSourceHandler.cpp | 7 +++++ .../wyciwyg/nsWyciwygProtocolHandler.cpp | 6 ++++ 16 files changed, 168 insertions(+), 36 deletions(-) diff --git a/netwerk/base/public/nsIProxiedProtocolHandler.idl b/netwerk/base/public/nsIProxiedProtocolHandler.idl index 995e576fe3df..604177c12430 100644 --- a/netwerk/base/public/nsIProxiedProtocolHandler.idl +++ b/netwerk/base/public/nsIProxiedProtocolHandler.idl @@ -27,6 +27,7 @@ interface nsIProxiedProtocolHandler : nsIProtocolHandler * effect), except in the case of websockets which wants to bootstrap * to an http:// channel but make its proxy determination based on * a ws:// uri. + * @param aLoadInfo used to evaluate who initated the resource request. */ nsIChannel newProxiedChannel2(in nsIURI uri, in nsIProxyInfo proxyInfo, in unsigned long proxyResolveFlags, diff --git a/netwerk/protocol/about/nsAboutBlank.cpp b/netwerk/protocol/about/nsAboutBlank.cpp index 9326b285cdd9..fd4d3b8ec9ce 100644 --- a/netwerk/protocol/about/nsAboutBlank.cpp +++ b/netwerk/protocol/about/nsAboutBlank.cpp @@ -23,14 +23,28 @@ nsAboutBlank::NewChannel(nsIURI* aURI, if (NS_FAILED(rv)) return rv; nsCOMPtr channel; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aURI, - in, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8")); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), + aURI, + in, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8"), + aLoadInfo); + } + else { + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aURI, + in, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8")); + } if (NS_FAILED(rv)) return rv; channel.forget(result); diff --git a/netwerk/protocol/about/nsAboutBloat.cpp b/netwerk/protocol/about/nsAboutBloat.cpp index 235858ed5cc5..8dee932d0adf 100644 --- a/netwerk/protocol/about/nsAboutBloat.cpp +++ b/netwerk/protocol/about/nsAboutBloat.cpp @@ -112,14 +112,28 @@ nsAboutBloat::NewChannel(nsIURI* aURI, } nsIChannel* channel = nullptr; - rv = NS_NewInputStreamChannel(&channel, - aURI, - inStr, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/plain"), - NS_LITERAL_CSTRING("utf-8")); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + rv = NS_NewInputStreamChannelInternal(&channel, + aURI, + inStr, + NS_LITERAL_CSTRING("text/plain"), + NS_LITERAL_CSTRING("utf-8"), + aLoadInfo); + } + else { + rv = NS_NewInputStreamChannel(&channel, + aURI, + inStr, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/plain"), + NS_LITERAL_CSTRING("utf-8")); + } if (NS_FAILED(rv)) return rv; *result = channel; diff --git a/netwerk/protocol/about/nsAboutCache.cpp b/netwerk/protocol/about/nsAboutCache.cpp index b1a12c70b421..36dcdb7c5b3e 100644 --- a/netwerk/protocol/about/nsAboutCache.cpp +++ b/netwerk/protocol/about/nsAboutCache.cpp @@ -64,14 +64,28 @@ nsAboutCache::NewChannel(nsIURI* aURI, mEntriesHeaderAdded = false; nsCOMPtr channel; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aURI, - inputStream, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8")); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), + aURI, + inputStream, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8"), + aLoadInfo); + } + else { + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aURI, + inputStream, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8")); + } if (NS_FAILED(rv)) return rv; mBuffer.AssignLiteral( diff --git a/netwerk/protocol/about/nsAboutCacheEntry.cpp b/netwerk/protocol/about/nsAboutCacheEntry.cpp index 5fdc2871e3c7..c2030e8ed00e 100644 --- a/netwerk/protocol/about/nsAboutCacheEntry.cpp +++ b/netwerk/protocol/about/nsAboutCacheEntry.cpp @@ -99,7 +99,18 @@ nsAboutCacheEntry::NewChannel(nsIURI* uri, nsCOMPtr stream; rv = GetContentStream(uri, getter_AddRefs(stream)); if (NS_FAILED(rv)) return rv; - + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + return NS_NewInputStreamChannelInternal(result, + uri, + stream, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8"), + aLoadInfo); + } return NS_NewInputStreamChannel(result, uri, stream, diff --git a/netwerk/protocol/about/nsAboutProtocolHandler.cpp b/netwerk/protocol/about/nsAboutProtocolHandler.cpp index 8a81437e3ec5..13af35bb8b72 100644 --- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp +++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp @@ -142,6 +142,16 @@ nsAboutProtocolHandler::NewChannel2(nsIURI* uri, // The standard return case: rv = aboutMod->NewChannel(uri, aLoadInfo, result); if (NS_SUCCEEDED(rv)) { + // Not all implementations of nsIAboutModule::NewChannel() + // set the LoadInfo on the newly created channel yet, as + // an interim solution we set the LoadInfo here if not + // available on the channel. Bug 1087720 + nsCOMPtr loadInfo; + (*result)->GetLoadInfo(getter_AddRefs(loadInfo)); + if (!loadInfo) { + (*result)->SetLoadInfo(aLoadInfo); + } + // If this URI is safe for untrusted content, enforce that its // principal be based on the channel's originalURI by setting the // owner to null. diff --git a/netwerk/protocol/app/AppProtocolHandler.cpp b/netwerk/protocol/app/AppProtocolHandler.cpp index 6a95c68bd657..fda2ce8112ba 100644 --- a/netwerk/protocol/app/AppProtocolHandler.cpp +++ b/netwerk/protocol/app/AppProtocolHandler.cpp @@ -423,7 +423,9 @@ AppProtocolHandler::NewChannel2(nsIURI* aUri, if (NS_FAILED(rv) || !jsInfo.isObject()) { // Return a DummyChannel. printf_stderr("!! Creating a dummy channel for %s (no appInfo)\n", host.get()); - NS_IF_ADDREF(*aResult = new DummyChannel()); + nsRefPtr dummyChannel = new DummyChannel(); + dummyChannel->SetLoadInfo(aLoadInfo); + dummyChannel.forget(aResult); return NS_OK; } @@ -432,7 +434,9 @@ AppProtocolHandler::NewChannel2(nsIURI* aUri, if (!appInfo->Init(cx, jsInfo) || appInfo->mPath.IsEmpty()) { // Return a DummyChannel. printf_stderr("!! Creating a dummy channel for %s (invalid appInfo)\n", host.get()); - NS_IF_ADDREF(*aResult = new DummyChannel()); + nsRefPtr dummyChannel = new DummyChannel(); + dummyChannel->SetLoadInfo(aLoadInfo); + dummyChannel.forget(aResult); return NS_OK; } mAppInfoCache.Put(host, appInfo); @@ -456,6 +460,10 @@ AppProtocolHandler::NewChannel2(nsIURI* aUri, rv = channel->Init(jarURI); NS_ENSURE_SUCCESS(rv, rv); + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + rv = channel->SetAppURI(aUri); NS_ENSURE_SUCCESS(rv, rv); diff --git a/netwerk/protocol/data/nsDataHandler.cpp b/netwerk/protocol/data/nsDataHandler.cpp index e5d2ed7bb32a..b242593d29bc 100644 --- a/netwerk/protocol/data/nsDataHandler.cpp +++ b/netwerk/protocol/data/nsDataHandler.cpp @@ -119,6 +119,13 @@ nsDataHandler::NewChannel2(nsIURI* uri, return rv; } + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + NS_RELEASE(channel); + return rv; + } + *result = channel; return NS_OK; } diff --git a/netwerk/protocol/device/nsDeviceProtocolHandler.cpp b/netwerk/protocol/device/nsDeviceProtocolHandler.cpp index 577692bd7c0f..51cfe9033d6d 100644 --- a/netwerk/protocol/device/nsDeviceProtocolHandler.cpp +++ b/netwerk/protocol/device/nsDeviceProtocolHandler.cpp @@ -62,6 +62,10 @@ nsDeviceProtocolHandler::NewChannel2(nsIURI* aURI, nsresult rv = channel->Init(aURI); NS_ENSURE_SUCCESS(rv, rv); + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + return CallQueryInterface(channel, aResult); } diff --git a/netwerk/protocol/file/nsFileProtocolHandler.cpp b/netwerk/protocol/file/nsFileProtocolHandler.cpp index 2c417a6a4e5f..c8b9ac0e0fa8 100644 --- a/netwerk/protocol/file/nsFileProtocolHandler.cpp +++ b/netwerk/protocol/file/nsFileProtocolHandler.cpp @@ -192,6 +192,13 @@ nsFileProtocolHandler::NewChannel2(nsIURI* uri, return rv; } + // set the loadInfo on the new channel + rv = chan->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + NS_RELEASE(chan); + return rv; + } + *result = chan; return NS_OK; } diff --git a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp index bd1f94ee8451..f540650d2cf4 100644 --- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp +++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp @@ -207,7 +207,7 @@ nsFtpProtocolHandler::NewChannel2(nsIURI* url, nsILoadInfo* aLoadInfo, nsIChannel** result) { - return NewProxiedChannel(url, nullptr, 0, nullptr, result); + return NewProxiedChannel2(url, nullptr, 0, nullptr, aLoadInfo, result); } NS_IMETHODIMP @@ -234,7 +234,13 @@ nsFtpProtocolHandler::NewProxiedChannel2(nsIURI* uri, nsIProxyInfo* proxyInfo, if (NS_FAILED(rv)) { return rv; } - + + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + return rv; + } + channel.forget(result); return rv; } diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 1ef14cdf1bc7..af343ca84617 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -1725,7 +1725,7 @@ nsHttpHandler::NewChannel2(nsIURI* uri, } } - return NewProxiedChannel(uri, nullptr, 0, nullptr, result); + return NewProxiedChannel2(uri, nullptr, 0, nullptr, aLoadInfo, result); } NS_IMETHODIMP @@ -1793,6 +1793,12 @@ nsHttpHandler::NewProxiedChannel2(nsIURI *uri, if (NS_FAILED(rv)) return rv; + // set the loadInfo on the new channel + rv = httpChannel->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + return rv; + } + httpChannel.forget(result); return NS_OK; } @@ -2107,7 +2113,7 @@ nsHttpsHandler::NewChannel2(nsIURI* aURI, MOZ_ASSERT(gHttpHandler); if (!gHttpHandler) return NS_ERROR_UNEXPECTED; - return gHttpHandler->NewChannel(aURI, _retval); + return gHttpHandler->NewChannel2(aURI, aLoadInfo, _retval); } NS_IMETHODIMP diff --git a/netwerk/protocol/res/nsResProtocolHandler.cpp b/netwerk/protocol/res/nsResProtocolHandler.cpp index 1f6cf39dbd44..8111deea320d 100644 --- a/netwerk/protocol/res/nsResProtocolHandler.cpp +++ b/netwerk/protocol/res/nsResProtocolHandler.cpp @@ -284,14 +284,27 @@ nsResProtocolHandler::NewChannel2(nsIURI* uri, nsIChannel** result) { NS_ENSURE_ARG_POINTER(uri); - nsresult rv; nsAutoCString spec; + nsresult rv = ResolveURI(uri, spec); + NS_ENSURE_SUCCESS(rv, rv); - rv = ResolveURI(uri, spec); - if (NS_FAILED(rv)) return rv; + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() instead of NewChannel() + // we should have a non-null loadInfo consistently. Until then we have to branch on the + // loadInfo. + nsCOMPtr newURI; + rv = NS_NewURI(getter_AddRefs(newURI), spec); + NS_ENSURE_SUCCESS(rv, rv); - rv = mIOService->NewChannel(spec, nullptr, nullptr, result); - if (NS_FAILED(rv)) return rv; + if (aLoadInfo) { + rv = NS_NewChannelInternal(result, + newURI, + aLoadInfo); + } + else { + rv = mIOService->NewChannelFromURI(newURI, result); + } + NS_ENSURE_SUCCESS(rv, rv); nsLoadFlags loadFlags = 0; (*result)->GetLoadFlags(&loadFlags); diff --git a/netwerk/protocol/rtsp/RtspHandler.cpp b/netwerk/protocol/rtsp/RtspHandler.cpp index 885cb64d4bf1..f633f1ce85d3 100644 --- a/netwerk/protocol/rtsp/RtspHandler.cpp +++ b/netwerk/protocol/rtsp/RtspHandler.cpp @@ -86,6 +86,10 @@ RtspHandler::NewChannel2(nsIURI* aURI, rv = rtspChannel->Init(); NS_ENSURE_SUCCESS(rv, rv); + // set the loadInfo on the new channel + rv = rtspChannel->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + rtspChannel.forget(aResult); return NS_OK; } diff --git a/netwerk/protocol/viewsource/nsViewSourceHandler.cpp b/netwerk/protocol/viewsource/nsViewSourceHandler.cpp index 979aea3510cb..261ee2465e51 100644 --- a/netwerk/protocol/viewsource/nsViewSourceHandler.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceHandler.cpp @@ -106,6 +106,13 @@ nsViewSourceHandler::NewChannel2(nsIURI* uri, return rv; } + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + NS_RELEASE(channel); + return rv; + } + *result = static_cast(channel); return NS_OK; } diff --git a/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp b/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp index 30cfd2127d22..3e9b66af47c3 100644 --- a/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp +++ b/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp @@ -131,6 +131,12 @@ nsWyciwygProtocolHandler::NewChannel2(nsIURI* url, if (NS_FAILED(rv)) return rv; + // set the loadInfo on the new channel + rv = channel->SetLoadInfo(aLoadInfo); + if (NS_FAILED(rv)) { + return rv; + } + channel.forget(result); return NS_OK; } From b27cc28ecc231f183fc005d1f151449db08592fb Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:46:59 -0800 Subject: [PATCH 29/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - toolkit/ changes (r=gcp) --- .../places/nsAnnoProtocolHandler.cpp | 30 ++++++++++++++----- .../components/places/nsAnnoProtocolHandler.h | 3 ++ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/toolkit/components/places/nsAnnoProtocolHandler.cpp b/toolkit/components/places/nsAnnoProtocolHandler.cpp index cb6e84b5fb13..40c5e6d86095 100644 --- a/toolkit/components/places/nsAnnoProtocolHandler.cpp +++ b/toolkit/components/places/nsAnnoProtocolHandler.cpp @@ -279,7 +279,7 @@ nsAnnoProtocolHandler::NewChannel2(nsIURI* aURI, if (!annoName.EqualsLiteral(FAVICON_ANNOTATION_NAME)) return NS_ERROR_INVALID_ARG; - return NewFaviconChannel(aURI, annoURI, _retval); + return NewFaviconChannel(aURI, annoURI, aLoadInfo, _retval); } NS_IMETHODIMP @@ -328,7 +328,7 @@ nsAnnoProtocolHandler::ParseAnnoURI(nsIURI* aURI, nsresult nsAnnoProtocolHandler::NewFaviconChannel(nsIURI *aURI, nsIURI *aAnnotationURI, - nsIChannel **_channel) + nsILoadInfo* aLoadInfo, nsIChannel **_channel) { // Create our pipe. This will give us our input stream and output stream // that will be written to when we get data from the database. @@ -343,12 +343,26 @@ nsAnnoProtocolHandler::NewFaviconChannel(nsIURI *aURI, nsIURI *aAnnotationURI, // Create our channel. We'll call SetContentType with the right type when // we know what it actually is. nsCOMPtr channel; - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aURI, - inputStream, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() instead of NewChannel() + // we should have a non-null loadInfo consistently. Until then we have to brach on the + // loadInfo and provide default arguments to create a NewInputStreamChannel. + if (aLoadInfo) { + rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), + aURI, + inputStream, + EmptyCString(), // aContentType + EmptyCString(), // aContentCharset + aLoadInfo); + } + else { + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aURI, + inputStream, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER); + } NS_ENSURE_SUCCESS(rv, GetDefaultIcon(_channel)); // Now we go ahead and get our data asynchronously for the favicon. diff --git a/toolkit/components/places/nsAnnoProtocolHandler.h b/toolkit/components/places/nsAnnoProtocolHandler.h index 2a956c5e39ac..df22851dc6f8 100644 --- a/toolkit/components/places/nsAnnoProtocolHandler.h +++ b/toolkit/components/places/nsAnnoProtocolHandler.h @@ -41,10 +41,13 @@ protected: * @param aAnnotationURI * The URI that holds the data needed to get the favicon from the * database. + * @param aLoadInfo + * The loadinfo that requested the resource load. * @returns (via _channel) the channel that will obtain the favicon data. */ nsresult NewFaviconChannel(nsIURI *aURI, nsIURI *aAnnotationURI, + nsILoadInfo *aLoadInfo, nsIChannel **_channel); }; From e82614dd738da81ab455961823dec50acdcbbfee Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:47:11 -0800 Subject: [PATCH 30/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - uriloader/ changes (r=smaug,sicking) --- uriloader/exthandler/nsExternalProtocolHandler.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/uriloader/exthandler/nsExternalProtocolHandler.cpp b/uriloader/exthandler/nsExternalProtocolHandler.cpp index c095a66d392a..94663e8b7b90 100644 --- a/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -57,6 +57,7 @@ private: nsCOMPtr mCallbacks; nsCOMPtr mLoadGroup; + nsCOMPtr mLoadInfo; }; NS_IMPL_ADDREF(nsExtProtocolChannel) @@ -264,14 +265,16 @@ NS_IMETHODIMP nsExtProtocolChannel::SetOwner(nsISupports * aPrincipal) return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsExtProtocolChannel::GetLoadInfo(nsILoadInfo * *aLoadInfo) +NS_IMETHODIMP nsExtProtocolChannel::GetLoadInfo(nsILoadInfo **aLoadInfo) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_IF_ADDREF(*aLoadInfo = mLoadInfo); + return NS_OK; } -NS_IMETHODIMP nsExtProtocolChannel::SetLoadInfo(nsILoadInfo * aLoadInfo) +NS_IMETHODIMP nsExtProtocolChannel::SetLoadInfo(nsILoadInfo *aLoadInfo) { - return NS_ERROR_NOT_IMPLEMENTED; + mLoadInfo = aLoadInfo; + return NS_OK; } //////////////////////////////////////////////////////////////////////////////// @@ -413,6 +416,9 @@ nsExternalProtocolHandler::NewChannel2(nsIURI* aURI, ((nsExtProtocolChannel*) channel.get())->SetURI(aURI); channel->SetOriginalURI(aURI); + // set the loadInfo on the new channel + ((nsExtProtocolChannel*) channel.get())->SetLoadInfo(aLoadInfo); + if (_retval) { *_retval = channel; From c553bfa980e9e5654617f570ed5a55822b2aa82e Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:47:23 -0800 Subject: [PATCH 31/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - widget/ changes (r=blassey) --- widget/android/nsAndroidProtocolHandler.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/widget/android/nsAndroidProtocolHandler.cpp b/widget/android/nsAndroidProtocolHandler.cpp index 5b0011609cf9..2650a64529db 100644 --- a/widget/android/nsAndroidProtocolHandler.cpp +++ b/widget/android/nsAndroidProtocolHandler.cpp @@ -170,6 +170,11 @@ nsAndroidProtocolHandler::NewChannel2(nsIURI* aURI, nsCOMPtr channel = AndroidChannel::CreateChannel(aURI); if (!channel) return NS_ERROR_FAILURE; + + // set the loadInfo on the new channel + nsresult rv = channel->SetLoadInfo(aLoadInfo); + NS_ENSURE_SUCCESS(rv, rv); + NS_ADDREF(*aResult = channel); return NS_OK; } From 424abaa72697db2ad6ba5d710e7a1308ef4266b2 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:47:34 -0800 Subject: [PATCH 32/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - browser/ changes (r=sicking) --- browser/components/about/AboutRedirector.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp index 5f4bbb67ae52..8cf5f2f516d3 100644 --- a/browser/components/about/AboutRedirector.cpp +++ b/browser/components/about/AboutRedirector.cpp @@ -153,8 +153,22 @@ AboutRedirector::NewChannel(nsIURI* aURI, for (int i = 0; i < kRedirTotal; i++) { if (!strcmp(path.get(), kRedirMap[i].id)) { nsCOMPtr tempChannel; - rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), - nullptr, nullptr, getter_AddRefs(tempChannel)); + nsCOMPtr tempURI; + rv = NS_NewURI(getter_AddRefs(tempURI), + nsDependentCString(kRedirMap[i].url)); + NS_ENSURE_SUCCESS(rv, rv); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), + tempURI, + aLoadInfo); + } + else { + rv = ioService->NewChannelFromURI(tempURI, getter_AddRefs(tempChannel)); + } NS_ENSURE_SUCCESS(rv, rv); tempChannel->SetOriginalURI(aURI); From ed7e78fc3f734bc50f33d34eb593e6d53ff2ff45 Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:47:44 -0800 Subject: [PATCH 33/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - docshell/ changes (r=smaug) --- docshell/base/nsAboutRedirector.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index 547e545c28dd..30f59e9ad91c 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -85,24 +85,35 @@ nsAboutRedirector::NewChannel(nsIURI* aURI, NS_ENSURE_ARG_POINTER(aURI); NS_ASSERTION(result, "must not be null"); - nsresult rv; - nsAutoCString path; - rv = NS_GetAboutModuleName(aURI, path); - if (NS_FAILED(rv)) - return rv; + nsresult rv = NS_GetAboutModuleName(aURI, path); + NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr ioService = do_GetIOService(&rv); - if (NS_FAILED(rv)) - return rv; + NS_ENSURE_SUCCESS(rv, rv); + for (int i=0; i tempChannel; - rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), - nullptr, nullptr, getter_AddRefs(tempChannel)); + nsCOMPtr tempURI; + rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url); + NS_ENSURE_SUCCESS(rv, rv); + // Bug 1087720 (and Bug 1099296): + // Once all callsites have been updated to call NewChannel2() + // instead of NewChannel() we should have a non-null loadInfo + // consistently. Until then we have to branch on the loadInfo. + if (aLoadInfo) { + rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), + tempURI, + aLoadInfo); + } + else { + rv = ioService->NewChannelFromURI(tempURI, + getter_AddRefs(tempChannel)); + } if (NS_FAILED(rv)) return rv; From 31b61e551f9df29e8a1cf7390289b7bd989f1f0d Mon Sep 17 00:00:00 2001 From: Christoph Kerschbaumer Date: Thu, 11 Dec 2014 20:47:55 -0800 Subject: [PATCH 34/36] Bug 1087442 - Attach LoadInfo inside each individual ProtocolHandler - securitymanager changes (r=sicking) --- caps/nsScriptSecurityManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index a6bb5a9ae82a..68c3d25b1e82 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -976,7 +976,7 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, if (uriPrinc) { nsCOMPtr principal; uriPrinc->GetPrincipal(getter_AddRefs(principal)); - if (!principal || principal == mSystemPrincipal) { + if (!principal) { return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result); } From b3dce254a53d4e4d0e648b08ffc73e22dd6daa39 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Thu, 11 Dec 2014 21:13:10 -0800 Subject: [PATCH 35/36] Fix displayport bounds not being computed from the correct origin. (bug 1109949, r=tn) --- gfx/layers/FrameMetrics.h | 11 ++++------- gfx/layers/apz/util/APZCCallbackHelper.cpp | 6 ++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index 3cc5fc0bfcaa..5c9c6e878029 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -234,8 +234,8 @@ public: // The following metrics are all in widget space/device pixels. // - // This is the area within the widget that we're compositing to. It is relative - // to the layer tree origin. + // This is the area within the widget that we're compositing to. It is in the + // same coordinate space as the reference frame for the scrolled frame. // // This is useful because, on mobile, the viewport and composition dimensions // are not always the same. In this case, we calculate the displayport using @@ -256,11 +256,8 @@ public: // space, so each is explained separately. // - // The area of a frame's contents that has been painted, relative to the - // viewport. It is in the same coordinate space as |mViewport|. For example, - // if it is at 0,0, then it's at the same place at the viewport, which is at - // the top-left in the layer, and at the same place as the scroll offset of - // the document. + // The area of a frame's contents that has been painted, relative to + // mCompositionBounds. // // Note that this is structured in such a way that it doesn't depend on the // method layout uses to scroll content. diff --git a/gfx/layers/apz/util/APZCCallbackHelper.cpp b/gfx/layers/apz/util/APZCCallbackHelper.cpp index 478852cf9fe4..8dfede7c20a4 100644 --- a/gfx/layers/apz/util/APZCCallbackHelper.cpp +++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp @@ -164,8 +164,7 @@ APZCCallbackHelper::UpdateRootFrame(nsIDOMWindowUtils* aUtils, margins.bottom, element, 0); CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels(); - nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(), - baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(), + nsRect base(0, 0, baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(), baseCSS.height * nsPresContext::AppUnitsPerCSSPixel()); nsLayoutUtils::SetDisplayPortBaseIfNotSet(content, base); @@ -208,8 +207,7 @@ APZCCallbackHelper::UpdateSubFrame(nsIContent* aContent, margins.bottom, element, 0); CSSRect baseCSS = aMetrics.CalculateCompositedRectInCssPixels(); - nsRect base(baseCSS.x * nsPresContext::AppUnitsPerCSSPixel(), - baseCSS.y * nsPresContext::AppUnitsPerCSSPixel(), + nsRect base(0, 0, baseCSS.width * nsPresContext::AppUnitsPerCSSPixel(), baseCSS.height * nsPresContext::AppUnitsPerCSSPixel()); nsLayoutUtils::SetDisplayPortBaseIfNotSet(aContent, base); From f7aea19aaea1bb4f555ab9da39b0b26fe73b4872 Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Thu, 11 Dec 2014 21:58:21 -0800 Subject: [PATCH 36/36] Backed out 15 changesets (bug 1087442) Backed out changeset 3f4166fb5e37 (bug 1087442) Backed out changeset 0c9c9123a0a9 (bug 1087442) Backed out changeset 1d85d298042d (bug 1087442) Backed out changeset 51f3ce397d68 (bug 1087442) Backed out changeset f3b81a623692 (bug 1087442) Backed out changeset 472e8fa74596 (bug 1087442) Backed out changeset 12f97df7b79c (bug 1087442) Backed out changeset 253cde88d3c5 (bug 1087442) Backed out changeset b44f9ebd56cb (bug 1087442) Backed out changeset 48e412887726 (bug 1087442) Backed out changeset a2c76343f7a9 (bug 1087442) Backed out changeset 0b5b07cfef0e (bug 1087442) Backed out changeset 2931c35342a4 (bug 1087442) Backed out changeset 681ce9dcad64 (bug 1087442) Backed out changeset 47c505856954 (bug 1087442) --- browser/components/about/AboutRedirector.cpp | 18 +- caps/nsScriptSecurityManager.cpp | 2 +- chrome/nsChromeProtocolHandler.cpp | 20 +- docshell/base/LoadInfo.cpp | 13 +- docshell/base/nsAboutRedirector.cpp | 29 +- dom/base/nsHostObjectProtocolHandler.cpp | 29 +- dom/jsurl/nsJSProtocolHandler.cpp | 5 - extensions/gio/nsGIOProtocolHandler.cpp | 26 +- image/decoders/icon/nsIconProtocolHandler.cpp | 7 - modules/libjar/nsJARProtocolHandler.cpp | 7 - netwerk/base/public/nsIIOService.idl | 54 +--- netwerk/base/public/nsIIOService2.idl | 55 +--- .../base/public/nsIProxiedProtocolHandler.idl | 1 - netwerk/base/public/nsNetUtil.h | 286 +++++++----------- netwerk/base/src/nsIOService.cpp | 76 +---- netwerk/protocol/about/nsAboutBlank.cpp | 30 +- netwerk/protocol/about/nsAboutBloat.cpp | 30 +- netwerk/protocol/about/nsAboutCache.cpp | 30 +- netwerk/protocol/about/nsAboutCacheEntry.cpp | 13 +- .../protocol/about/nsAboutProtocolHandler.cpp | 10 - netwerk/protocol/app/AppProtocolHandler.cpp | 12 +- netwerk/protocol/data/nsDataHandler.cpp | 7 - .../device/nsDeviceProtocolHandler.cpp | 4 - .../protocol/file/nsFileProtocolHandler.cpp | 7 - netwerk/protocol/ftp/nsFtpProtocolHandler.cpp | 10 +- netwerk/protocol/http/nsHttpHandler.cpp | 10 +- netwerk/protocol/res/nsResProtocolHandler.cpp | 23 +- netwerk/protocol/rtsp/RtspHandler.cpp | 4 - .../viewsource/nsViewSourceHandler.cpp | 7 - .../wyciwyg/nsWyciwygProtocolHandler.cpp | 6 - .../places/nsAnnoProtocolHandler.cpp | 30 +- .../components/places/nsAnnoProtocolHandler.h | 3 - .../exthandler/nsExternalProtocolHandler.cpp | 14 +- widget/android/nsAndroidProtocolHandler.cpp | 5 - 34 files changed, 195 insertions(+), 688 deletions(-) diff --git a/browser/components/about/AboutRedirector.cpp b/browser/components/about/AboutRedirector.cpp index 8cf5f2f516d3..5f4bbb67ae52 100644 --- a/browser/components/about/AboutRedirector.cpp +++ b/browser/components/about/AboutRedirector.cpp @@ -153,22 +153,8 @@ AboutRedirector::NewChannel(nsIURI* aURI, for (int i = 0; i < kRedirTotal; i++) { if (!strcmp(path.get(), kRedirMap[i].id)) { nsCOMPtr tempChannel; - nsCOMPtr tempURI; - rv = NS_NewURI(getter_AddRefs(tempURI), - nsDependentCString(kRedirMap[i].url)); - NS_ENSURE_SUCCESS(rv, rv); - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), - tempURI, - aLoadInfo); - } - else { - rv = ioService->NewChannelFromURI(tempURI, getter_AddRefs(tempChannel)); - } + rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), + nullptr, nullptr, getter_AddRefs(tempChannel)); NS_ENSURE_SUCCESS(rv, rv); tempChannel->SetOriginalURI(aURI); diff --git a/caps/nsScriptSecurityManager.cpp b/caps/nsScriptSecurityManager.cpp index 68c3d25b1e82..a6bb5a9ae82a 100644 --- a/caps/nsScriptSecurityManager.cpp +++ b/caps/nsScriptSecurityManager.cpp @@ -976,7 +976,7 @@ nsScriptSecurityManager::CreateCodebasePrincipal(nsIURI* aURI, uint32_t aAppId, if (uriPrinc) { nsCOMPtr principal; uriPrinc->GetPrincipal(getter_AddRefs(principal)); - if (!principal) { + if (!principal || principal == mSystemPrincipal) { return CallCreateInstance(NS_NULLPRINCIPAL_CONTRACTID, result); } diff --git a/chrome/nsChromeProtocolHandler.cpp b/chrome/nsChromeProtocolHandler.cpp index f339a89cab35..fa40425b0d23 100644 --- a/chrome/nsChromeProtocolHandler.cpp +++ b/chrome/nsChromeProtocolHandler.cpp @@ -100,7 +100,7 @@ nsChromeProtocolHandler::NewURI(const nsACString &aSpec, NS_IMETHODIMP nsChromeProtocolHandler::NewChannel2(nsIURI* aURI, - nsILoadInfo* aLoadInfo, + nsILoadInfo* aLoadinfo, nsIChannel** aResult) { nsresult rv; @@ -147,22 +147,12 @@ nsChromeProtocolHandler::NewChannel2(nsIURI* aURI, return rv; } - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() instead of NewChannel() - // we should have a non-null loadInfo consistently. Until then we have to branch on the - // loadInfo. - if (aLoadInfo) { - rv = NS_NewChannelInternal(getter_AddRefs(result), - resolvedURI, - aLoadInfo); - } - else { - nsCOMPtr ioServ(do_GetIOService(&rv)); - NS_ENSURE_SUCCESS(rv, rv); - rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result)); - } + nsCOMPtr ioServ(do_GetIOService(&rv)); NS_ENSURE_SUCCESS(rv, rv); + rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result)); + if (NS_FAILED(rv)) return rv; + #ifdef DEBUG nsCOMPtr fileChan(do_QueryInterface(result)); if (fileChan) { diff --git a/docshell/base/LoadInfo.cpp b/docshell/base/LoadInfo.cpp index e2e8c2c4c637..068408c9f350 100644 --- a/docshell/base/LoadInfo.cpp +++ b/docshell/base/LoadInfo.cpp @@ -20,23 +20,16 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsIURI* aBaseURI) - : mLoadingPrincipal(aLoadingContext ? - aLoadingContext->NodePrincipal() : aLoadingPrincipal) + : mLoadingPrincipal(aLoadingPrincipal) , mTriggeringPrincipal(aTriggeringPrincipal ? - aTriggeringPrincipal : mLoadingPrincipal.get()) + aTriggeringPrincipal : aLoadingPrincipal) , mLoadingContext(do_GetWeakReference(aLoadingContext)) , mSecurityFlags(aSecurityFlags) , mContentPolicyType(aContentPolicyType) , mBaseURI(aBaseURI) { - MOZ_ASSERT(mLoadingPrincipal); + MOZ_ASSERT(aLoadingPrincipal); MOZ_ASSERT(mTriggeringPrincipal); - - // if consumers pass both, aLoadingContext and aLoadingPrincipal - // then the loadingPrincipal must be the same as the node's principal - MOZ_ASSERT(!aLoadingContext || !aLoadingPrincipal || - aLoadingContext->NodePrincipal() == aLoadingPrincipal); - // if the load is sandboxed, we can not also inherit the principal if (mSecurityFlags & nsILoadInfo::SEC_SANDBOXED) { mSecurityFlags ^= nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL; diff --git a/docshell/base/nsAboutRedirector.cpp b/docshell/base/nsAboutRedirector.cpp index 30f59e9ad91c..547e545c28dd 100644 --- a/docshell/base/nsAboutRedirector.cpp +++ b/docshell/base/nsAboutRedirector.cpp @@ -85,35 +85,24 @@ nsAboutRedirector::NewChannel(nsIURI* aURI, NS_ENSURE_ARG_POINTER(aURI); NS_ASSERTION(result, "must not be null"); + nsresult rv; + nsAutoCString path; - nsresult rv = NS_GetAboutModuleName(aURI, path); - NS_ENSURE_SUCCESS(rv, rv); + rv = NS_GetAboutModuleName(aURI, path); + if (NS_FAILED(rv)) + return rv; nsCOMPtr ioService = do_GetIOService(&rv); - NS_ENSURE_SUCCESS(rv, rv); - + if (NS_FAILED(rv)) + return rv; for (int i=0; i tempChannel; - nsCOMPtr tempURI; - rv = NS_NewURI(getter_AddRefs(tempURI), kRedirMap[i].url); - NS_ENSURE_SUCCESS(rv, rv); - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - rv = NS_NewChannelInternal(getter_AddRefs(tempChannel), - tempURI, - aLoadInfo); - } - else { - rv = ioService->NewChannelFromURI(tempURI, - getter_AddRefs(tempChannel)); - } + rv = ioService->NewChannel(nsDependentCString(kRedirMap[i].url), + nullptr, nullptr, getter_AddRefs(tempChannel)); if (NS_FAILED(rv)) return rv; diff --git a/dom/base/nsHostObjectProtocolHandler.cpp b/dom/base/nsHostObjectProtocolHandler.cpp index 838e54da057d..ba20807753d7 100644 --- a/dom/base/nsHostObjectProtocolHandler.cpp +++ b/dom/base/nsHostObjectProtocolHandler.cpp @@ -485,7 +485,7 @@ nsHostObjectProtocolHandler::NewURI(const nsACString& aSpec, NS_IMETHODIMP nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri, - nsILoadInfo* aLoadInfo, + nsILoadInfo *aLoadinfo, nsIChannel** result) { *result = nullptr; @@ -519,26 +519,13 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr channel; - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() instead of NewChannel() - // we should have a non-null loadInfo consistently. Until then we have to brach on the - // loadInfo and provide default arguments to create a NewInputStreamChannel. - if (aLoadInfo) { - rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), - uri, - stream, - EmptyCString(), // aContentType - EmptyCString(), // aContentCharset - aLoadInfo); - } - else { - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - uri, - stream, - info->mPrincipal, - nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, - nsIContentPolicy::TYPE_OTHER); - } + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + uri, + stream, + info->mPrincipal, + nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL, + nsIContentPolicy::TYPE_OTHER); + NS_ENSURE_SUCCESS(rv, rv); nsString type; diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index 4faaa4ca5e88..12ed881d54dd 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -1223,11 +1223,6 @@ nsJSProtocolHandler::NewChannel2(nsIURI* uri, NS_ADDREF(channel); rv = channel->Init(uri); - - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - NS_ENSURE_SUCCESS(rv, rv); - if (NS_SUCCEEDED(rv)) { *result = channel; NS_ADDREF(*result); diff --git a/extensions/gio/nsGIOProtocolHandler.cpp b/extensions/gio/nsGIOProtocolHandler.cpp index dd82fdf356aa..c989e6dcdfaa 100644 --- a/extensions/gio/nsGIOProtocolHandler.cpp +++ b/extensions/gio/nsGIOProtocolHandler.cpp @@ -1059,23 +1059,12 @@ nsGIOProtocolHandler::NewChannel2(nsIURI* aURI, return rv; nsRefPtr stream = new nsGIOInputStream(spec); - if (!stream) { - return NS_ERROR_OUT_OF_MEMORY; + if (!stream) + { + rv = NS_ERROR_OUT_OF_MEMORY; } - - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() instead of NewChannel() - // we should have a non-null loadInfo consistently. Until then we have to brach on the - // loadInfo and provide default arguments to create a NewInputStreamChannel. - if (aLoadInfo) { - rv = NS_NewInputStreamChannelInternal(aResult, - aURI, - stream, - NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE), - EmptyCString(), // aContentCharset - aLoadInfo); - } - else { + else + { nsCOMPtr nullPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -1089,9 +1078,8 @@ nsGIOProtocolHandler::NewChannel2(nsIURI* aURI, nsILoadInfo::SEC_NORMAL, nsIContentPolicy::TYPE_OTHER, NS_LITERAL_CSTRING(UNKNOWN_CONTENT_TYPE)); - } - if (NS_SUCCEEDED(rv)) { - stream->SetChannel(*aResult); + if (NS_SUCCEEDED(rv)) + stream->SetChannel(*aResult); } return rv; } diff --git a/image/decoders/icon/nsIconProtocolHandler.cpp b/image/decoders/icon/nsIconProtocolHandler.cpp index eb3ded06a18d..513e11336410 100644 --- a/image/decoders/icon/nsIconProtocolHandler.cpp +++ b/image/decoders/icon/nsIconProtocolHandler.cpp @@ -96,13 +96,6 @@ nsIconProtocolHandler::NewChannel2(nsIURI* url, return rv; } - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - NS_RELEASE(channel); - return rv; - } - *result = channel; return NS_OK; } diff --git a/modules/libjar/nsJARProtocolHandler.cpp b/modules/libjar/nsJARProtocolHandler.cpp index eb789ee6efff..b076d85e68e1 100644 --- a/modules/libjar/nsJARProtocolHandler.cpp +++ b/modules/libjar/nsJARProtocolHandler.cpp @@ -223,13 +223,6 @@ nsJARProtocolHandler::NewChannel2(nsIURI* uri, return rv; } - // set the loadInfo on the new channel - rv = chan->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - NS_RELEASE(chan); - return rv; - } - *result = chan; return NS_OK; } diff --git a/netwerk/base/public/nsIIOService.idl b/netwerk/base/public/nsIIOService.idl index e9cdc8307220..34a0714ef1e3 100644 --- a/netwerk/base/public/nsIIOService.idl +++ b/netwerk/base/public/nsIIOService.idl @@ -67,58 +67,8 @@ interface nsIIOService : nsISupports /** * Creates a channel for a given URI. * - * @param aURI - * nsIURI from which to make a channel - * @param aLoadingNode - * The loadingDocument of the channel. - * The element or document where the result of this request will be - * used. This is the document/element that will get access to the - * result of this request. For example for an image load, it's the - * document in which the image will be loaded. And for a CSS - * stylesheet it's the document whose rendering will be affected by - * the stylesheet. - * If possible, pass in the element which is performing the load. But - * if the load is coming from a JS API (such as XMLHttpRequest) or if - * the load might be coalesced across multiple elements (such as - * for ) then pass in the Document node instead. - * For loads that are not related to any document, such as loads coming - * from addons or internal browser features, use null here. - * @param aLoadingPrincipal - * The loadingPrincipal of the channel. - * The principal of the document where the result of this request will be used. - * This is generally the principal of the aLoadingNode. However for - * loads where aLoadingNode is null this argument still needs to be - * passed. For example for loads from a WebWorker, pass the principal - * of that worker. For loads from an addon or from internal browser - * features, pass the system principal. - * This principal should almost always be the system principal if - * aLoadingNode is null. The only exception to this is for loads - * from WebWorkers since they don't have any nodes to be passed as - * aLoadingNode. Please note, aLoadingPrincipal is *not* the - * principal of the resource being loaded. But rather the principal - * of the context where the resource will be used. - * @param aTriggeringPrincipal - * The triggeringPrincipal of the load. - * The triggeringPrincipal is the principal of the resource that caused - * this particular URL to be loaded. - * Most likely the triggeringPrincipal and the loadingPrincipal are - * identical, in which case the triggeringPrincipal can be left out. - * In some cases the loadingPrincipal and the triggeringPrincipal are - * different however, e.g. a stylesheet may import a subresource. In - * that case the principal of the stylesheet which contains the - * import command is the triggeringPrincipal, and the principal of - * the document whose rendering is affected is the loadingPrincipal. - * @param aSecurityFlags - * The securityFlags of the channel. - * Any of the securityflags defined in nsILoadInfo.idl - * @param aContentPolicyType - * The contentPolicyType of the channel. - * Any of the content types defined in nsIContentPolicy.idl + * @param aURI nsIURI from which to make a channel * @return reference to the new nsIChannel object - * - * Please note, if you provide a loadingNode, then the loadingPrincipal - * must match the loadingNode->NodePrincipal(). Alternatively you can - * discard the loadingPrincipal if you provide a loadingNode. */ nsIChannel newChannelFromURI2(in nsIURI aURI, in nsIDOMNode aLoadingNode, @@ -136,7 +86,7 @@ interface nsIIOService : nsISupports nsIChannel newChannelFromURI(in nsIURI aURI); /** - * Equivalent to newChannelFromURI2(newURI(...)) + * Equivalent to newChannelFromURI(newURI(...)) */ nsIChannel newChannel2(in AUTF8String aSpec, in string aOriginCharset, diff --git a/netwerk/base/public/nsIIOService2.idl b/netwerk/base/public/nsIIOService2.idl index a17193363ddd..394a5d8b0873 100644 --- a/netwerk/base/public/nsIIOService2.idl +++ b/netwerk/base/public/nsIIOService2.idl @@ -33,63 +33,12 @@ interface nsIIOService2 : nsIIOService /** * Creates a channel for a given URI. * - * @param aURI - * nsIURI from which to make a channel - * @param aProxyURI - * nsIURI to use for proxy resolution. Can be null in which + * @param aURI nsIURI from which to make a channel + * @param aProxyURI nsIURI to use for proxy resolution. Can be null in which * case aURI is used * @param aProxyFlags flags from nsIProtocolProxyService to use * when resolving proxies for this new channel - * @param aLoadingNode - * The loadingDocument of the channel. - * The element or document where the result of this request will be - * used. This is the document/element that will get access to the - * result of this request. For example for an image load, it's the - * document in which the image will be loaded. And for a CSS - * stylesheet it's the document whose rendering will be affected by - * the stylesheet. - * If possible, pass in the element which is performing the load. But - * if the load is coming from a JS API (such as XMLHttpRequest) or if - * the load might be coalesced across multiple elements (such as - * for ) then pass in the Document node instead. - * For loads that are not related to any document, such as loads coming - * from addons or internal browser features, use null here. - * @param aLoadingPrincipal - * The loadingPrincipal of the channel. - * The principal of the document where the result of this request will be used. - * This is generally the principal of the aLoadingNode. However for - * loads where aLoadingNode is null this argument still needs to be - * passed. For example for loads from a WebWorker, pass the principal - * of that worker. For loads from an addon or from internal browser - * features, pass the system principal. - * This principal should almost always be the system principal if - * aLoadingNode is null. The only exception to this is for loads - * from WebWorkers since they don't have any nodes to be passed as - * aLoadingNode. Please note, aLoadingPrincipal is *not* the - * principal of the resource being loaded. But rather the principal - * of the context where the resource will be used. - * @param aTriggeringPrincipal - * The triggeringPrincipal of the load. - * The triggeringPrincipal is the principal of the resource that caused - * this particular URL to be loaded. - * Most likely the triggeringPrincipal and the loadingPrincipal are - * identical, in which case the triggeringPrincipal can be left out. - * In some cases the loadingPrincipal and the triggeringPrincipal are - * different however, e.g. a stylesheet may import a subresource. In - * that case the principal of the stylesheet which contains the - * import command is the triggeringPrincipal, and the principal of - * the document whose rendering is affected is the loadingPrincipal. - * @param aSecurityFlags - * The securityFlags of the channel. - * Any of the securityflags defined in nsILoadInfo.idl - * @param aContentPolicyType - * The contentPolicyType of the channel. - * Any of the content types defined in nsIContentPolicy.idl * @return reference to the new nsIChannel object - * - * Please note, if you provide a loadingNode, then the loadingPrincipal - * must match the loadingNode->NodePrincipal(). Alternatively you can - * discard the loadingPrincipal if you provide a loadingNode. */ nsIChannel newChannelFromURIWithProxyFlags2(in nsIURI aURI, in nsIURI aProxyURI, diff --git a/netwerk/base/public/nsIProxiedProtocolHandler.idl b/netwerk/base/public/nsIProxiedProtocolHandler.idl index 604177c12430..995e576fe3df 100644 --- a/netwerk/base/public/nsIProxiedProtocolHandler.idl +++ b/netwerk/base/public/nsIProxiedProtocolHandler.idl @@ -27,7 +27,6 @@ interface nsIProxiedProtocolHandler : nsIProtocolHandler * effect), except in the case of websockets which wants to bootstrap * to an http:// channel but make its proxy determination based on * a ws:// uri. - * @param aLoadInfo used to evaluate who initated the resource request. */ nsIChannel newProxiedChannel2(in nsIURI uri, in nsIProxyInfo proxyInfo, in unsigned long proxyResolveFlags, diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index 43516b622226..9fe75cf5489d 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -188,80 +188,24 @@ NS_NewFileURI(nsIURI* *result, } /* -* How to create a new Channel, using NS_NewChannel, -* NS_NewChannelWithTriggeringPrincipal, NS_OpenURI, -* NS_NewInputStreamChannel, NS_NewChannelInternal -* and it's variations: -* -* @param aURI -* nsIURI from which to make a channel -* @param aLoadingNode -* The loadingDocument of the channel. -* The element or document where the result of this request will be -* used. This is the document/element that will get access to the -* result of this request. For example for an image load, it's the -* document in which the image will be loaded. And for a CSS -* stylesheet it's the document whose rendering will be affected by -* the stylesheet. -* If possible, pass in the element which is performing the load. But -* if the load is coming from a JS API (such as XMLHttpRequest) or if -* the load might be coalesced across multiple elements (such as -* for ) then pass in the Document node instead. -* For loads that are not related to any document, such as loads coming -* from addons or internal browser features, use null here. -* @param aLoadingPrincipal -* The loadingPrincipal of the channel. -* The principal of the document where the result of this request will be used. -* This is generally the principal of the aLoadingNode. However for -* loads where aLoadingNode is null this argument still needs to be -* passed. For example for loads from a WebWorker, pass the principal -* of that worker. For loads from an addon or from internal browser -* features, pass the system principal. -* This principal should almost always be the system principal if -* aLoadingNode is null. The only exception to this is for loads -* from WebWorkers since they don't have any nodes to be passed as -* aLoadingNode. Please note, aLoadingPrincipal is *not* the -* principal of the resource being loaded. But rather the principal -* of the context where the resource will be used. -* @param aTriggeringPrincipal -* The triggeringPrincipal of the load. -* The triggeringPrincipal is the principal of the resource that caused -* this particular URL to be loaded. -* Most likely the triggeringPrincipal and the loadingPrincipal are -* identical, in which case the triggeringPrincipal can be left out. -* In some cases the loadingPrincipal and the triggeringPrincipal are -* different however, e.g. a stylesheet may import a subresource. In -* that case the principal of the stylesheet which contains the -* import command is the triggeringPrincipal, and the principal of -* the document whose rendering is affected is the loadingPrincipal. -* @param aSecurityFlags -* The securityFlags of the channel. -* Any of the securityflags defined in nsILoadInfo.idl -* @param aContentPolicyType -* The contentPolicyType of the channel. -* Any of the content types defined in nsIContentPolicy.idl -* -* Please note, if you provide a loadingNode, then the loadingPrincipal -* must match the loadingNode->NodePrincipal(). Alternatively you can -* discard the loadingPrincipal if you provide a loadingNode. -* -* What specific API function to use: -* * If possible try to call NS_NewChannel() providing a loading *nsINode* -* * If no loading *nsINode* is avaialable, call NS_NewChannel() providing -* a loading *nsIPrincipal*. -* * Call NS_NewChannelWithTriggeringPrincipal() if the loading principal -* and the Node's principal have to be different (see above). -* * Call NS_NewChannelInternal() providing aLoadInfo object in cases where -* you already have loadInfo object, e.g in case of a channel redirect. -*/ + * How to create a new Channel using NS_NewChannel: + * 1) Please try to call NS_NewChannel providing a requesting *nsINode* + * 2) If no requesting nsINode is available, + * call NS_NewChannel providing a requesting *nsIPrincipal*. + * 3) Call NS_NewChannelInternal *only* if requesting Principal and + * the Node's Principal have to be different. + * >> Most likely this is not the case! << + * Needs special approval! + */ inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aLoadingNode, - nsIPrincipal* aLoadingPrincipal, + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, + nsIURI* aBaseURI = nullptr, nsILoadGroup* aLoadGroup = nullptr, nsIInterfaceRequestor* aCallbacks = nullptr, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, @@ -274,15 +218,7 @@ NS_NewChannelInternal(nsIChannel** outChannel, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr channel; - rv = aIoService->NewChannelFromURI2( - aUri, - aLoadingNode ? - aLoadingNode->AsDOMNode() : nullptr, - aLoadingPrincipal, - aTriggeringPrincipal, - aSecurityFlags, - aContentPolicyType, - getter_AddRefs(channel)); + rv = aIoService->NewChannelFromURI(aUri, getter_AddRefs(channel)); NS_ENSURE_SUCCESS(rv, rv); if (aLoadGroup) { @@ -316,9 +252,9 @@ NS_NewChannelInternal(nsIChannel** outChannel, // create a new Loadinfo with the potentially updated securityFlags loadInfo = - new mozilla::LoadInfo(aLoadingPrincipal, aTriggeringPrincipal, - aLoadingNode, aSecurityFlags, - aContentPolicyType); + new mozilla::LoadInfo(aRequestingPrincipal, aTriggeringPrincipal, + aRequestingNode, aSecurityFlags, + aContentPolicyType, aBaseURI); if (!loadInfo) { return NS_ERROR_UNEXPECTED; } @@ -334,7 +270,6 @@ NS_NewChannelInternal(nsIChannel** outChannel, return NS_OK; } -// See NS_NewChannelInternal for usage and argument description inline nsresult NS_NewChannelInternal(nsIChannel** outChannel, nsIURI* aUri, @@ -352,22 +287,19 @@ NS_NewChannelInternal(nsIChannel** outChannel, aLoadInfo->TriggeringPrincipal(), aLoadInfo->GetSecurityFlags(), aLoadInfo->GetContentPolicyType(), + aLoadInfo->BaseURI(), aLoadGroup, aCallbacks, aLoadFlags, aIoService); NS_ENSURE_SUCCESS(rv, rv); - // Please note that we still call SetLoadInfo on the channel because - // we want the same instance of the loadInfo to be set on the channel. - (*outChannel)->SetLoadInfo(aLoadInfo); return NS_OK; } -// See NS_NewChannelInternal for usage and argument description inline nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aLoadingNode, + nsINode* aRequestingNode, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -376,26 +308,26 @@ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - MOZ_ASSERT(aLoadingNode); + MOZ_ASSERT(aRequestingNode); NS_ASSERTION(aTriggeringPrincipal, "Can not create channel without a triggering Principal!"); return NS_NewChannelInternal(outChannel, aUri, - aLoadingNode, - aLoadingNode->NodePrincipal(), + aRequestingNode, + aRequestingNode->NodePrincipal(), aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, aIoService); } -// See NS_NewChannelInternal for usage and argument description inline nsresult /*NS_NewChannelWithPrincipalAndTriggeringPrincipal */ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsIURI* aUri, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -404,25 +336,25 @@ NS_NewChannelWithTriggeringPrincipal(nsIChannel** outChannel, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!"); + NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); return NS_NewChannelInternal(outChannel, aUri, - nullptr, // aLoadingNode - aLoadingPrincipal, + nullptr, // aRequestingNode + aRequestingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, aIoService); } -// See NS_NewChannelInternal for usage and argument description inline nsresult /* NS_NewChannelNode */ NS_NewChannel(nsIChannel** outChannel, nsIURI* aUri, - nsINode* aLoadingNode, + nsINode* aRequestingNode, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -430,25 +362,25 @@ NS_NewChannel(nsIChannel** outChannel, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aLoadingNode, "Can not create channel without a loading Node!"); + NS_ASSERTION(aRequestingNode, "Can not create channel without a requesting Node!"); return NS_NewChannelInternal(outChannel, aUri, - aLoadingNode, - aLoadingNode->NodePrincipal(), + aRequestingNode, + aRequestingNode->NodePrincipal(), nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, aIoService); } -// See NS_NewChannelInternal for usage and argument description inline nsresult /* NS_NewChannelPrincipal */ NS_NewChannel(nsIChannel** outChannel, nsIURI* aUri, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -458,11 +390,12 @@ NS_NewChannel(nsIChannel** outChannel, { return NS_NewChannelInternal(outChannel, aUri, - nullptr, // aLoadingNode, - aLoadingPrincipal, + nullptr, // aRequestingNode, + aRequestingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -476,8 +409,8 @@ NS_NewChannel(nsIChannel** outChannel, inline nsresult NS_OpenURIInternal(nsIInputStream** outStream, nsIURI* aUri, - nsINode* aLoadingNode, - nsIPrincipal* aLoadingPrincipal, + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -487,16 +420,17 @@ NS_OpenURIInternal(nsIInputStream** outStream, nsIIOService* aIoService = nullptr, // pass in nsIIOService to optimize callers nsIChannel** outChannel = nullptr) { - NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!"); + NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); nsCOMPtr channel; nsresult rv = NS_NewChannelInternal(getter_AddRefs(channel), aUri, - aLoadingNode, - aLoadingPrincipal, + aRequestingNode, + aRequestingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags, @@ -517,7 +451,7 @@ NS_OpenURIInternal(nsIInputStream** outStream, inline nsresult /* NS_OpenURIprincipal */ NS_OpenURI(nsIInputStream** outStream, nsIURI* aUri, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -528,8 +462,8 @@ NS_OpenURI(nsIInputStream** outStream, { return NS_OpenURIInternal(outStream, aUri, - nullptr, // aLoadingNode - aLoadingPrincipal, + nullptr, // aRequestingNode + aRequestingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, @@ -543,7 +477,7 @@ NS_OpenURI(nsIInputStream** outStream, inline nsresult /* NS_OpenURIWithTriggeringPrincipalAndNode */ NS_OpenURIWithTriggeringPrincipal(nsIInputStream** outStream, nsIURI* aUri, - nsINode* aLoadingNode, + nsINode* aRequestingNode, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -553,12 +487,12 @@ NS_OpenURIWithTriggeringPrincipal(nsIInputStream** outStream, nsIIOService* aIoService = nullptr, nsIChannel** outChannel = nullptr) { - MOZ_ASSERT(aLoadingNode); + MOZ_ASSERT(aRequestingNode); NS_ASSERTION(aTriggeringPrincipal, "Can not open uri without a triggering Principal!"); return NS_OpenURIInternal(outStream, aUri, - aLoadingNode, - aLoadingNode->NodePrincipal(), + aRequestingNode, + aRequestingNode->NodePrincipal(), aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, @@ -595,8 +529,8 @@ inline nsresult NS_OpenURIInternal(nsIStreamListener* aListener, nsISupports* aContext, nsIURI* aUri, - nsINode* aLoadingNode, - nsIPrincipal* aLoadingPrincipal, + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -605,12 +539,12 @@ NS_OpenURIInternal(nsIStreamListener* aListener, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIIOService* aIoService = nullptr) { - NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!"); + NS_ASSERTION(aRequestingPrincipal, "Can not create channel without a requesting Principal!"); nsCOMPtr loadInfo = - new mozilla::LoadInfo(aLoadingPrincipal, + new mozilla::LoadInfo(aRequestingPrincipal, aTriggeringPrincipal, - aLoadingNode, + aRequestingNode, aSecurityFlags, aContentPolicyType); if (!loadInfo) { @@ -630,7 +564,7 @@ inline nsresult NS_OpenURI(nsIStreamListener* aListener, nsISupports* aContext, nsIURI* aUri, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsILoadGroup* aLoadGroup = nullptr, @@ -641,8 +575,8 @@ NS_OpenURI(nsIStreamListener* aListener, return NS_OpenURIInternal(aListener, aContext, aUri, - nullptr, // aLoadingNode - aLoadingPrincipal, + nullptr, // aRequestingNode + aRequestingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, @@ -776,15 +710,19 @@ NS_GetRealPort(nsIURI* aURI) return NS_GetDefaultPort(scheme.get()); } -inline nsresult /* NS_NewInputStreamChannelWithLoadInfo */ +inline nsresult NS_NewInputStreamChannelInternal(nsIChannel** outChannel, nsIURI* aUri, nsIInputStream* aStream, const nsACString& aContentType, const nsACString& aContentCharset, - nsILoadInfo* aLoadInfo) + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, + nsIPrincipal* aTriggeringPrincipal, + nsSecurityFlags aSecurityFlags, + nsContentPolicyType aContentPolicyType, + nsIURI* aBaseURI = nullptr) { - MOZ_ASSERT(aLoadInfo, "can not create channel without a loadinfo"); nsresult rv; nsCOMPtr isc = do_CreateInstance(NS_INPUTSTREAMCHANNEL_CONTRACTID, &rv); @@ -807,11 +745,21 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, NS_ENSURE_SUCCESS(rv, rv); } - channel->SetLoadInfo(aLoadInfo); + nsCOMPtr loadInfo = + new mozilla::LoadInfo(aRequestingPrincipal, + aTriggeringPrincipal, + aRequestingNode, + aSecurityFlags, + aContentPolicyType, + aBaseURI); + if (!loadInfo) { + return NS_ERROR_UNEXPECTED; + } + channel->SetLoadInfo(loadInfo); // If we're sandboxed, make sure to clear any owner the channel // might already have. - if (aLoadInfo->GetLoadingSandboxed()) { + if (loadInfo->GetLoadingSandboxed()) { channel->SetOwner(nullptr); } @@ -819,42 +767,11 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, return NS_OK; } -inline nsresult -NS_NewInputStreamChannelInternal(nsIChannel** outChannel, - nsIURI* aUri, - nsIInputStream* aStream, - const nsACString& aContentType, - const nsACString& aContentCharset, - nsINode* aLoadingNode, - nsIPrincipal* aLoadingPrincipal, - nsIPrincipal* aTriggeringPrincipal, - nsSecurityFlags aSecurityFlags, - nsContentPolicyType aContentPolicyType, - nsIURI* aBaseURI = nullptr) -{ - nsCOMPtr loadInfo = - new mozilla::LoadInfo(aLoadingPrincipal, - aTriggeringPrincipal, - aLoadingNode, - aSecurityFlags, - aContentPolicyType, - aBaseURI); - if (!loadInfo) { - return NS_ERROR_UNEXPECTED; - } - return NS_NewInputStreamChannelInternal(outChannel, - aUri, - aStream, - aContentType, - aContentCharset, - loadInfo); -} - inline nsresult /* NS_NewInputStreamChannelPrincipal */ NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri, nsIInputStream* aStream, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, const nsACString& aContentType = EmptyCString(), @@ -865,8 +782,8 @@ NS_NewInputStreamChannel(nsIChannel** outChannel, aStream, aContentType, aContentCharset, - nullptr, // aLoadingNode - aLoadingPrincipal, + nullptr, // aRequestingNode + aRequestingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType); @@ -877,8 +794,8 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, nsIURI* aUri, const nsAString& aData, const nsACString& aContentType, - nsINode* aLoadingNode, - nsIPrincipal* aLoadingPrincipal, + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, nsIPrincipal* aTriggeringPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, @@ -905,8 +822,8 @@ NS_NewInputStreamChannelInternal(nsIChannel** outChannel, stream, aContentType, NS_LITERAL_CSTRING("UTF-8"), - aLoadingNode, - aLoadingPrincipal, + aRequestingNode, + aRequestingPrincipal, aTriggeringPrincipal, aSecurityFlags, aContentPolicyType, @@ -928,7 +845,7 @@ NS_NewInputStreamChannel(nsIChannel** outChannel, nsIURI* aUri, const nsAString& aData, const nsACString& aContentType, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, bool aIsSrcdocChannel = false, @@ -938,8 +855,8 @@ NS_NewInputStreamChannel(nsIChannel** outChannel, aUri, aData, aContentType, - nullptr, // aLoadingNode - aLoadingPrincipal, + nullptr, // aRequestingNode + aRequestingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, @@ -1052,8 +969,8 @@ inline nsresult NS_NewStreamLoaderInternal(nsIStreamLoader** outStream, nsIURI* aUri, nsIStreamLoaderObserver* aObserver, - nsINode* aLoadingNode, - nsIPrincipal* aLoadingPrincipal, + nsINode* aRequestingNode, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsISupports* aContext = nullptr, @@ -1065,11 +982,12 @@ NS_NewStreamLoaderInternal(nsIStreamLoader** outStream, nsCOMPtr channel; nsresult rv = NS_NewChannelInternal(getter_AddRefs(channel), aUri, - aLoadingNode, - aLoadingPrincipal, + aRequestingNode, + aRequestingPrincipal, nullptr, // aTriggeringPrincipal aSecurityFlags, aContentPolicyType, + nullptr, // aBaseURI aLoadGroup, aCallbacks, aLoadFlags); @@ -1089,7 +1007,7 @@ inline nsresult /* NS_NewStreamLoaderNode */ NS_NewStreamLoader(nsIStreamLoader** outStream, nsIURI* aUri, nsIStreamLoaderObserver* aObserver, - nsINode* aLoadingNode, + nsINode* aRequestingNode, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsISupports* aContext = nullptr, @@ -1098,12 +1016,12 @@ NS_NewStreamLoader(nsIStreamLoader** outStream, nsLoadFlags aLoadFlags = nsIRequest::LOAD_NORMAL, nsIURI* aReferrer = nullptr) { - NS_ASSERTION(aLoadingNode, "Can not create stream loader without a loading Node!"); + NS_ASSERTION(aRequestingNode, "Can not create stream loader without a requesting Node!"); return NS_NewStreamLoaderInternal(outStream, aUri, aObserver, - aLoadingNode, - aLoadingNode->NodePrincipal(), + aRequestingNode, + aRequestingNode->NodePrincipal(), aSecurityFlags, aContentPolicyType, aContext, @@ -1117,7 +1035,7 @@ inline nsresult /* NS_NewStreamLoaderPrincipal */ NS_NewStreamLoader(nsIStreamLoader** outStream, nsIURI* aUri, nsIStreamLoaderObserver* aObserver, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsSecurityFlags aSecurityFlags, nsContentPolicyType aContentPolicyType, nsISupports* aContext = nullptr, @@ -1129,8 +1047,8 @@ NS_NewStreamLoader(nsIStreamLoader** outStream, return NS_NewStreamLoaderInternal(outStream, aUri, aObserver, - nullptr, // aLoadingNode - aLoadingPrincipal, + nullptr, // aRequestingNode + aRequestingPrincipal, aSecurityFlags, aContentPolicyType, aContext, @@ -1746,14 +1664,14 @@ NS_ReadInputStreamToString(nsIInputStream *aInputStream, inline nsresult NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties** outResult, nsIURI* aUri, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsContentPolicyType aContentPolicyType, nsIIOService* aIoService = nullptr) { nsCOMPtr in; nsresult rv = NS_OpenURI(getter_AddRefs(in), aUri, - aLoadingPrincipal, + aRequestingPrincipal, nsILoadInfo::SEC_NORMAL, aContentPolicyType, nullptr, // aLoadGroup @@ -1776,7 +1694,7 @@ NS_LoadPersistentPropertiesFromURI(nsIPersistentProperties** outResult, inline nsresult NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties** outResult, const nsACString& aSpec, - nsIPrincipal* aLoadingPrincipal, + nsIPrincipal* aRequestingPrincipal, nsContentPolicyType aContentPolicyType, const char* aCharset = nullptr, nsIURI* aBaseURI = nullptr, @@ -1792,7 +1710,7 @@ NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties** outResult, return NS_LoadPersistentPropertiesFromURI(outResult, uri, - aLoadingPrincipal, + aRequestingPrincipal, aContentPolicyType, aIoService); } diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp index c6de4cb6beb1..92d669742cb2 100644 --- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -40,7 +40,6 @@ #include "MainThreadUtils.h" #include "nsIWidget.h" #include "nsThreadUtils.h" -#include "mozilla/LoadInfo.h" #include "mozilla/net/NeckoCommon.h" #ifdef MOZ_WIDGET_GONK @@ -635,76 +634,13 @@ nsIOService::NewChannelFromURIWithProxyFlags2(nsIURI* aURI, if (NS_FAILED(rv)) return rv; - // Ideally we are creating new channels by calling NewChannel2 (NewProxiedChannel2). - // Keep in mind that Addons can implement their own Protocolhandlers, hence - // NewChannel2() might *not* be implemented. - // We do not want to break those addons, therefore we first try to create a channel - // calling NewChannel2(); if that fails we fall back to creating a channel by calling - // NewChannel(); - - nsCOMPtr loadInfo; - // Unfortunately not all callsites (see Bug 1087720, and 1099296) have been updated - // yet to call NewChannel2() instead of NewChannel(), hence those callsites do not - // provide the necessary loadinfo arguments yet. - // Since creating a new loadInfo requires 'aLoadingPrincipal' or 'aLoadingNode' we - // can branch on those arguments as an interim solution. - // - // BUG 1087720: Once that bug lands, we should have a loadInfo for all callers of - // NewChannelFromURIWithProxyFlags2() and should remove the *if* before creating a - // a new loadinfo. - if (aLoadingNode || aLoadingPrincipal) { - nsCOMPtr loadingNode(do_QueryInterface(aLoadingNode)); - loadInfo = new mozilla::LoadInfo(aLoadingPrincipal, - aTriggeringPrincipal, - loadingNode, - aSecurityFlags, - aContentPolicyType); - if (!loadInfo) { - return NS_ERROR_UNEXPECTED; - } - } - - bool newChannel2Succeeded = true; - nsCOMPtr pph = do_QueryInterface(handler); - if (pph) { - rv = pph->NewProxiedChannel2(aURI, nullptr, aProxyFlags, aProxyURI, - loadInfo, result); - // if calling NewProxiedChannel2() fails we try to fall back to - // creating a new proxied channel by calling NewProxiedChannel(). - if (NS_FAILED(rv)) { - newChannel2Succeeded = false; - rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, - result); - } - } - else { - rv = handler->NewChannel2(aURI, loadInfo, result); - // if calling newChannel2() fails we try to fall back to - // creating a new channel by calling NewChannel(). - if (NS_FAILED(rv)) { - newChannel2Succeeded = false; - rv = handler->NewChannel(aURI, result); - } - } - NS_ENSURE_SUCCESS(rv, rv); - - if ((aLoadingNode || aLoadingPrincipal) && newChannel2Succeeded) { - // Make sure that all the individual protocolhandlers attach - // a loadInfo within it's implementation of ::newChannel2(). - // Once Bug 1087720 lands, we should remove the surrounding - // if-clause here and always assert that we indeed have a - // loadinfo on the newly created channel. - nsCOMPtr loadInfo; - (*result)->GetLoadInfo(getter_AddRefs(loadInfo)); - MOZ_ASSERT(loadInfo); - - // If we're sandboxed, make sure to clear any owner the channel - // might already have. - if (loadInfo->GetLoadingSandboxed()) { - (*result)->SetOwner(nullptr); - } - } + if (pph) + rv = pph->NewProxiedChannel(aURI, nullptr, aProxyFlags, aProxyURI, result); + else + rv = handler->NewChannel(aURI, result); + if (NS_FAILED(rv)) + return rv; // Some extensions override the http protocol handler and provide their own // implementation. The channels returned from that implementation doesn't diff --git a/netwerk/protocol/about/nsAboutBlank.cpp b/netwerk/protocol/about/nsAboutBlank.cpp index fd4d3b8ec9ce..9326b285cdd9 100644 --- a/netwerk/protocol/about/nsAboutBlank.cpp +++ b/netwerk/protocol/about/nsAboutBlank.cpp @@ -23,28 +23,14 @@ nsAboutBlank::NewChannel(nsIURI* aURI, if (NS_FAILED(rv)) return rv; nsCOMPtr channel; - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), - aURI, - in, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8"), - aLoadInfo); - } - else { - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aURI, - in, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8")); - } + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aURI, + in, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8")); if (NS_FAILED(rv)) return rv; channel.forget(result); diff --git a/netwerk/protocol/about/nsAboutBloat.cpp b/netwerk/protocol/about/nsAboutBloat.cpp index 8dee932d0adf..235858ed5cc5 100644 --- a/netwerk/protocol/about/nsAboutBloat.cpp +++ b/netwerk/protocol/about/nsAboutBloat.cpp @@ -112,28 +112,14 @@ nsAboutBloat::NewChannel(nsIURI* aURI, } nsIChannel* channel = nullptr; - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - rv = NS_NewInputStreamChannelInternal(&channel, - aURI, - inStr, - NS_LITERAL_CSTRING("text/plain"), - NS_LITERAL_CSTRING("utf-8"), - aLoadInfo); - } - else { - rv = NS_NewInputStreamChannel(&channel, - aURI, - inStr, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/plain"), - NS_LITERAL_CSTRING("utf-8")); - } + rv = NS_NewInputStreamChannel(&channel, + aURI, + inStr, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/plain"), + NS_LITERAL_CSTRING("utf-8")); if (NS_FAILED(rv)) return rv; *result = channel; diff --git a/netwerk/protocol/about/nsAboutCache.cpp b/netwerk/protocol/about/nsAboutCache.cpp index 36dcdb7c5b3e..b1a12c70b421 100644 --- a/netwerk/protocol/about/nsAboutCache.cpp +++ b/netwerk/protocol/about/nsAboutCache.cpp @@ -64,28 +64,14 @@ nsAboutCache::NewChannel(nsIURI* aURI, mEntriesHeaderAdded = false; nsCOMPtr channel; - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), - aURI, - inputStream, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8"), - aLoadInfo); - } - else { - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aURI, - inputStream, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8")); - } + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aURI, + inputStream, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER, + NS_LITERAL_CSTRING("text/html"), + NS_LITERAL_CSTRING("utf-8")); if (NS_FAILED(rv)) return rv; mBuffer.AssignLiteral( diff --git a/netwerk/protocol/about/nsAboutCacheEntry.cpp b/netwerk/protocol/about/nsAboutCacheEntry.cpp index c2030e8ed00e..5fdc2871e3c7 100644 --- a/netwerk/protocol/about/nsAboutCacheEntry.cpp +++ b/netwerk/protocol/about/nsAboutCacheEntry.cpp @@ -99,18 +99,7 @@ nsAboutCacheEntry::NewChannel(nsIURI* uri, nsCOMPtr stream; rv = GetContentStream(uri, getter_AddRefs(stream)); if (NS_FAILED(rv)) return rv; - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() - // instead of NewChannel() we should have a non-null loadInfo - // consistently. Until then we have to branch on the loadInfo. - if (aLoadInfo) { - return NS_NewInputStreamChannelInternal(result, - uri, - stream, - NS_LITERAL_CSTRING("text/html"), - NS_LITERAL_CSTRING("utf-8"), - aLoadInfo); - } + return NS_NewInputStreamChannel(result, uri, stream, diff --git a/netwerk/protocol/about/nsAboutProtocolHandler.cpp b/netwerk/protocol/about/nsAboutProtocolHandler.cpp index 13af35bb8b72..8a81437e3ec5 100644 --- a/netwerk/protocol/about/nsAboutProtocolHandler.cpp +++ b/netwerk/protocol/about/nsAboutProtocolHandler.cpp @@ -142,16 +142,6 @@ nsAboutProtocolHandler::NewChannel2(nsIURI* uri, // The standard return case: rv = aboutMod->NewChannel(uri, aLoadInfo, result); if (NS_SUCCEEDED(rv)) { - // Not all implementations of nsIAboutModule::NewChannel() - // set the LoadInfo on the newly created channel yet, as - // an interim solution we set the LoadInfo here if not - // available on the channel. Bug 1087720 - nsCOMPtr loadInfo; - (*result)->GetLoadInfo(getter_AddRefs(loadInfo)); - if (!loadInfo) { - (*result)->SetLoadInfo(aLoadInfo); - } - // If this URI is safe for untrusted content, enforce that its // principal be based on the channel's originalURI by setting the // owner to null. diff --git a/netwerk/protocol/app/AppProtocolHandler.cpp b/netwerk/protocol/app/AppProtocolHandler.cpp index fda2ce8112ba..6a95c68bd657 100644 --- a/netwerk/protocol/app/AppProtocolHandler.cpp +++ b/netwerk/protocol/app/AppProtocolHandler.cpp @@ -423,9 +423,7 @@ AppProtocolHandler::NewChannel2(nsIURI* aUri, if (NS_FAILED(rv) || !jsInfo.isObject()) { // Return a DummyChannel. printf_stderr("!! Creating a dummy channel for %s (no appInfo)\n", host.get()); - nsRefPtr dummyChannel = new DummyChannel(); - dummyChannel->SetLoadInfo(aLoadInfo); - dummyChannel.forget(aResult); + NS_IF_ADDREF(*aResult = new DummyChannel()); return NS_OK; } @@ -434,9 +432,7 @@ AppProtocolHandler::NewChannel2(nsIURI* aUri, if (!appInfo->Init(cx, jsInfo) || appInfo->mPath.IsEmpty()) { // Return a DummyChannel. printf_stderr("!! Creating a dummy channel for %s (invalid appInfo)\n", host.get()); - nsRefPtr dummyChannel = new DummyChannel(); - dummyChannel->SetLoadInfo(aLoadInfo); - dummyChannel.forget(aResult); + NS_IF_ADDREF(*aResult = new DummyChannel()); return NS_OK; } mAppInfoCache.Put(host, appInfo); @@ -460,10 +456,6 @@ AppProtocolHandler::NewChannel2(nsIURI* aUri, rv = channel->Init(jarURI); NS_ENSURE_SUCCESS(rv, rv); - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - NS_ENSURE_SUCCESS(rv, rv); - rv = channel->SetAppURI(aUri); NS_ENSURE_SUCCESS(rv, rv); diff --git a/netwerk/protocol/data/nsDataHandler.cpp b/netwerk/protocol/data/nsDataHandler.cpp index b242593d29bc..e5d2ed7bb32a 100644 --- a/netwerk/protocol/data/nsDataHandler.cpp +++ b/netwerk/protocol/data/nsDataHandler.cpp @@ -119,13 +119,6 @@ nsDataHandler::NewChannel2(nsIURI* uri, return rv; } - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - NS_RELEASE(channel); - return rv; - } - *result = channel; return NS_OK; } diff --git a/netwerk/protocol/device/nsDeviceProtocolHandler.cpp b/netwerk/protocol/device/nsDeviceProtocolHandler.cpp index 51cfe9033d6d..577692bd7c0f 100644 --- a/netwerk/protocol/device/nsDeviceProtocolHandler.cpp +++ b/netwerk/protocol/device/nsDeviceProtocolHandler.cpp @@ -62,10 +62,6 @@ nsDeviceProtocolHandler::NewChannel2(nsIURI* aURI, nsresult rv = channel->Init(aURI); NS_ENSURE_SUCCESS(rv, rv); - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - NS_ENSURE_SUCCESS(rv, rv); - return CallQueryInterface(channel, aResult); } diff --git a/netwerk/protocol/file/nsFileProtocolHandler.cpp b/netwerk/protocol/file/nsFileProtocolHandler.cpp index c8b9ac0e0fa8..2c417a6a4e5f 100644 --- a/netwerk/protocol/file/nsFileProtocolHandler.cpp +++ b/netwerk/protocol/file/nsFileProtocolHandler.cpp @@ -192,13 +192,6 @@ nsFileProtocolHandler::NewChannel2(nsIURI* uri, return rv; } - // set the loadInfo on the new channel - rv = chan->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - NS_RELEASE(chan); - return rv; - } - *result = chan; return NS_OK; } diff --git a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp index f540650d2cf4..bd1f94ee8451 100644 --- a/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp +++ b/netwerk/protocol/ftp/nsFtpProtocolHandler.cpp @@ -207,7 +207,7 @@ nsFtpProtocolHandler::NewChannel2(nsIURI* url, nsILoadInfo* aLoadInfo, nsIChannel** result) { - return NewProxiedChannel2(url, nullptr, 0, nullptr, aLoadInfo, result); + return NewProxiedChannel(url, nullptr, 0, nullptr, result); } NS_IMETHODIMP @@ -234,13 +234,7 @@ nsFtpProtocolHandler::NewProxiedChannel2(nsIURI* uri, nsIProxyInfo* proxyInfo, if (NS_FAILED(rv)) { return rv; } - - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - return rv; - } - + channel.forget(result); return rv; } diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index af343ca84617..1ef14cdf1bc7 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -1725,7 +1725,7 @@ nsHttpHandler::NewChannel2(nsIURI* uri, } } - return NewProxiedChannel2(uri, nullptr, 0, nullptr, aLoadInfo, result); + return NewProxiedChannel(uri, nullptr, 0, nullptr, result); } NS_IMETHODIMP @@ -1793,12 +1793,6 @@ nsHttpHandler::NewProxiedChannel2(nsIURI *uri, if (NS_FAILED(rv)) return rv; - // set the loadInfo on the new channel - rv = httpChannel->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - return rv; - } - httpChannel.forget(result); return NS_OK; } @@ -2113,7 +2107,7 @@ nsHttpsHandler::NewChannel2(nsIURI* aURI, MOZ_ASSERT(gHttpHandler); if (!gHttpHandler) return NS_ERROR_UNEXPECTED; - return gHttpHandler->NewChannel2(aURI, aLoadInfo, _retval); + return gHttpHandler->NewChannel(aURI, _retval); } NS_IMETHODIMP diff --git a/netwerk/protocol/res/nsResProtocolHandler.cpp b/netwerk/protocol/res/nsResProtocolHandler.cpp index 8111deea320d..1f6cf39dbd44 100644 --- a/netwerk/protocol/res/nsResProtocolHandler.cpp +++ b/netwerk/protocol/res/nsResProtocolHandler.cpp @@ -284,27 +284,14 @@ nsResProtocolHandler::NewChannel2(nsIURI* uri, nsIChannel** result) { NS_ENSURE_ARG_POINTER(uri); + nsresult rv; nsAutoCString spec; - nsresult rv = ResolveURI(uri, spec); - NS_ENSURE_SUCCESS(rv, rv); - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() instead of NewChannel() - // we should have a non-null loadInfo consistently. Until then we have to branch on the - // loadInfo. - nsCOMPtr newURI; - rv = NS_NewURI(getter_AddRefs(newURI), spec); - NS_ENSURE_SUCCESS(rv, rv); + rv = ResolveURI(uri, spec); + if (NS_FAILED(rv)) return rv; - if (aLoadInfo) { - rv = NS_NewChannelInternal(result, - newURI, - aLoadInfo); - } - else { - rv = mIOService->NewChannelFromURI(newURI, result); - } - NS_ENSURE_SUCCESS(rv, rv); + rv = mIOService->NewChannel(spec, nullptr, nullptr, result); + if (NS_FAILED(rv)) return rv; nsLoadFlags loadFlags = 0; (*result)->GetLoadFlags(&loadFlags); diff --git a/netwerk/protocol/rtsp/RtspHandler.cpp b/netwerk/protocol/rtsp/RtspHandler.cpp index f633f1ce85d3..885cb64d4bf1 100644 --- a/netwerk/protocol/rtsp/RtspHandler.cpp +++ b/netwerk/protocol/rtsp/RtspHandler.cpp @@ -86,10 +86,6 @@ RtspHandler::NewChannel2(nsIURI* aURI, rv = rtspChannel->Init(); NS_ENSURE_SUCCESS(rv, rv); - // set the loadInfo on the new channel - rv = rtspChannel->SetLoadInfo(aLoadInfo); - NS_ENSURE_SUCCESS(rv, rv); - rtspChannel.forget(aResult); return NS_OK; } diff --git a/netwerk/protocol/viewsource/nsViewSourceHandler.cpp b/netwerk/protocol/viewsource/nsViewSourceHandler.cpp index 261ee2465e51..979aea3510cb 100644 --- a/netwerk/protocol/viewsource/nsViewSourceHandler.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceHandler.cpp @@ -106,13 +106,6 @@ nsViewSourceHandler::NewChannel2(nsIURI* uri, return rv; } - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - NS_RELEASE(channel); - return rv; - } - *result = static_cast(channel); return NS_OK; } diff --git a/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp b/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp index 3e9b66af47c3..30cfd2127d22 100644 --- a/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp +++ b/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp @@ -131,12 +131,6 @@ nsWyciwygProtocolHandler::NewChannel2(nsIURI* url, if (NS_FAILED(rv)) return rv; - // set the loadInfo on the new channel - rv = channel->SetLoadInfo(aLoadInfo); - if (NS_FAILED(rv)) { - return rv; - } - channel.forget(result); return NS_OK; } diff --git a/toolkit/components/places/nsAnnoProtocolHandler.cpp b/toolkit/components/places/nsAnnoProtocolHandler.cpp index 40c5e6d86095..cb6e84b5fb13 100644 --- a/toolkit/components/places/nsAnnoProtocolHandler.cpp +++ b/toolkit/components/places/nsAnnoProtocolHandler.cpp @@ -279,7 +279,7 @@ nsAnnoProtocolHandler::NewChannel2(nsIURI* aURI, if (!annoName.EqualsLiteral(FAVICON_ANNOTATION_NAME)) return NS_ERROR_INVALID_ARG; - return NewFaviconChannel(aURI, annoURI, aLoadInfo, _retval); + return NewFaviconChannel(aURI, annoURI, _retval); } NS_IMETHODIMP @@ -328,7 +328,7 @@ nsAnnoProtocolHandler::ParseAnnoURI(nsIURI* aURI, nsresult nsAnnoProtocolHandler::NewFaviconChannel(nsIURI *aURI, nsIURI *aAnnotationURI, - nsILoadInfo* aLoadInfo, nsIChannel **_channel) + nsIChannel **_channel) { // Create our pipe. This will give us our input stream and output stream // that will be written to when we get data from the database. @@ -343,26 +343,12 @@ nsAnnoProtocolHandler::NewFaviconChannel(nsIURI *aURI, nsIURI *aAnnotationURI, // Create our channel. We'll call SetContentType with the right type when // we know what it actually is. nsCOMPtr channel; - // Bug 1087720 (and Bug 1099296): - // Once all callsites have been updated to call NewChannel2() instead of NewChannel() - // we should have a non-null loadInfo consistently. Until then we have to brach on the - // loadInfo and provide default arguments to create a NewInputStreamChannel. - if (aLoadInfo) { - rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel), - aURI, - inputStream, - EmptyCString(), // aContentType - EmptyCString(), // aContentCharset - aLoadInfo); - } - else { - rv = NS_NewInputStreamChannel(getter_AddRefs(channel), - aURI, - inputStream, - nsContentUtils::GetSystemPrincipal(), - nsILoadInfo::SEC_NORMAL, - nsIContentPolicy::TYPE_OTHER); - } + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), + aURI, + inputStream, + nsContentUtils::GetSystemPrincipal(), + nsILoadInfo::SEC_NORMAL, + nsIContentPolicy::TYPE_OTHER); NS_ENSURE_SUCCESS(rv, GetDefaultIcon(_channel)); // Now we go ahead and get our data asynchronously for the favicon. diff --git a/toolkit/components/places/nsAnnoProtocolHandler.h b/toolkit/components/places/nsAnnoProtocolHandler.h index df22851dc6f8..2a956c5e39ac 100644 --- a/toolkit/components/places/nsAnnoProtocolHandler.h +++ b/toolkit/components/places/nsAnnoProtocolHandler.h @@ -41,13 +41,10 @@ protected: * @param aAnnotationURI * The URI that holds the data needed to get the favicon from the * database. - * @param aLoadInfo - * The loadinfo that requested the resource load. * @returns (via _channel) the channel that will obtain the favicon data. */ nsresult NewFaviconChannel(nsIURI *aURI, nsIURI *aAnnotationURI, - nsILoadInfo *aLoadInfo, nsIChannel **_channel); }; diff --git a/uriloader/exthandler/nsExternalProtocolHandler.cpp b/uriloader/exthandler/nsExternalProtocolHandler.cpp index 94663e8b7b90..c095a66d392a 100644 --- a/uriloader/exthandler/nsExternalProtocolHandler.cpp +++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp @@ -57,7 +57,6 @@ private: nsCOMPtr mCallbacks; nsCOMPtr mLoadGroup; - nsCOMPtr mLoadInfo; }; NS_IMPL_ADDREF(nsExtProtocolChannel) @@ -265,16 +264,14 @@ NS_IMETHODIMP nsExtProtocolChannel::SetOwner(nsISupports * aPrincipal) return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsExtProtocolChannel::GetLoadInfo(nsILoadInfo **aLoadInfo) +NS_IMETHODIMP nsExtProtocolChannel::GetLoadInfo(nsILoadInfo * *aLoadInfo) { - NS_IF_ADDREF(*aLoadInfo = mLoadInfo); - return NS_OK; + return NS_ERROR_NOT_IMPLEMENTED; } -NS_IMETHODIMP nsExtProtocolChannel::SetLoadInfo(nsILoadInfo *aLoadInfo) +NS_IMETHODIMP nsExtProtocolChannel::SetLoadInfo(nsILoadInfo * aLoadInfo) { - mLoadInfo = aLoadInfo; - return NS_OK; + return NS_ERROR_NOT_IMPLEMENTED; } //////////////////////////////////////////////////////////////////////////////// @@ -416,9 +413,6 @@ nsExternalProtocolHandler::NewChannel2(nsIURI* aURI, ((nsExtProtocolChannel*) channel.get())->SetURI(aURI); channel->SetOriginalURI(aURI); - // set the loadInfo on the new channel - ((nsExtProtocolChannel*) channel.get())->SetLoadInfo(aLoadInfo); - if (_retval) { *_retval = channel; diff --git a/widget/android/nsAndroidProtocolHandler.cpp b/widget/android/nsAndroidProtocolHandler.cpp index 2650a64529db..5b0011609cf9 100644 --- a/widget/android/nsAndroidProtocolHandler.cpp +++ b/widget/android/nsAndroidProtocolHandler.cpp @@ -170,11 +170,6 @@ nsAndroidProtocolHandler::NewChannel2(nsIURI* aURI, nsCOMPtr channel = AndroidChannel::CreateChannel(aURI); if (!channel) return NS_ERROR_FAILURE; - - // set the loadInfo on the new channel - nsresult rv = channel->SetLoadInfo(aLoadInfo); - NS_ENSURE_SUCCESS(rv, rv); - NS_ADDREF(*aResult = channel); return NS_OK; }