uriloader/base/nsDocLoader.h

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 */
michael@0 8
michael@0 9 #ifndef nsDocLoader_h__
michael@0 10 #define nsDocLoader_h__
michael@0 11
michael@0 12 #include "nsIDocumentLoader.h"
michael@0 13 #include "nsIWebProgress.h"
michael@0 14 #include "nsIWebProgressListener.h"
michael@0 15 #include "nsIRequestObserver.h"
michael@0 16 #include "nsWeakReference.h"
michael@0 17 #include "nsILoadGroup.h"
michael@0 18 #include "nsCOMArray.h"
michael@0 19 #include "nsTObserverArray.h"
michael@0 20 #include "nsVoidArray.h"
michael@0 21 #include "nsString.h"
michael@0 22 #include "nsIChannel.h"
michael@0 23 #include "nsIProgressEventSink.h"
michael@0 24 #include "nsIInterfaceRequestor.h"
michael@0 25 #include "nsIInterfaceRequestorUtils.h"
michael@0 26 #include "nsIChannelEventSink.h"
michael@0 27 #include "nsISecurityEventSink.h"
michael@0 28 #include "nsISupportsPriority.h"
michael@0 29 #include "nsCOMPtr.h"
michael@0 30 #include "pldhash.h"
michael@0 31 #include "nsAutoPtr.h"
michael@0 32
michael@0 33 #include "mozilla/LinkedList.h"
michael@0 34
michael@0 35 struct nsListenerInfo;
michael@0 36
michael@0 37 /****************************************************************************
michael@0 38 * nsDocLoader implementation...
michael@0 39 ****************************************************************************/
michael@0 40
michael@0 41 #define NS_THIS_DOCLOADER_IMPL_CID \
michael@0 42 { /* b4ec8387-98aa-4c08-93b6-6d23069c06f2 */ \
michael@0 43 0xb4ec8387, \
michael@0 44 0x98aa, \
michael@0 45 0x4c08, \
michael@0 46 {0x93, 0xb6, 0x6d, 0x23, 0x06, 0x9c, 0x06, 0xf2} \
michael@0 47 }
michael@0 48
michael@0 49 class nsDocLoader : public nsIDocumentLoader,
michael@0 50 public nsIRequestObserver,
michael@0 51 public nsSupportsWeakReference,
michael@0 52 public nsIProgressEventSink,
michael@0 53 public nsIWebProgress,
michael@0 54 public nsIInterfaceRequestor,
michael@0 55 public nsIChannelEventSink,
michael@0 56 public nsISecurityEventSink,
michael@0 57 public nsISupportsPriority
michael@0 58 {
michael@0 59 public:
michael@0 60 NS_DECLARE_STATIC_IID_ACCESSOR(NS_THIS_DOCLOADER_IMPL_CID)
michael@0 61
michael@0 62 nsDocLoader();
michael@0 63
michael@0 64 virtual nsresult Init();
michael@0 65
michael@0 66 static already_AddRefed<nsDocLoader> GetAsDocLoader(nsISupports* aSupports);
michael@0 67 // Needed to deal with ambiguous inheritance from nsISupports...
michael@0 68 static nsISupports* GetAsSupports(nsDocLoader* aDocLoader) {
michael@0 69 return static_cast<nsIDocumentLoader*>(aDocLoader);
michael@0 70 }
michael@0 71
michael@0 72 // Add aDocLoader as a child to the docloader service.
michael@0 73 static nsresult AddDocLoaderAsChildOfRoot(nsDocLoader* aDocLoader);
michael@0 74
michael@0 75 NS_DECL_ISUPPORTS
michael@0 76 NS_DECL_NSIDOCUMENTLOADER
michael@0 77
michael@0 78 // nsIProgressEventSink
michael@0 79 NS_DECL_NSIPROGRESSEVENTSINK
michael@0 80
michael@0 81 NS_DECL_NSISECURITYEVENTSINK
michael@0 82
michael@0 83 // nsIRequestObserver methods: (for observing the load group)
michael@0 84 NS_DECL_NSIREQUESTOBSERVER
michael@0 85 NS_DECL_NSIWEBPROGRESS
michael@0 86
michael@0 87 NS_DECL_NSIINTERFACEREQUESTOR
michael@0 88 NS_DECL_NSICHANNELEVENTSINK
michael@0 89 NS_DECL_NSISUPPORTSPRIORITY
michael@0 90
michael@0 91 // Implementation specific methods...
michael@0 92
michael@0 93 // Remove aChild from our childlist. This nulls out the child's mParent
michael@0 94 // pointer.
michael@0 95 nsresult RemoveChildLoader(nsDocLoader *aChild);
michael@0 96 // Add aChild to our child list. This will set aChild's mParent pointer to
michael@0 97 // |this|.
michael@0 98 nsresult AddChildLoader(nsDocLoader* aChild);
michael@0 99 nsDocLoader* GetParent() const { return mParent; }
michael@0 100
michael@0 101 protected:
michael@0 102 virtual ~nsDocLoader();
michael@0 103
michael@0 104 virtual nsresult SetDocLoaderParent(nsDocLoader * aLoader);
michael@0 105
michael@0 106 bool IsBusy();
michael@0 107
michael@0 108 void Destroy();
michael@0 109 virtual void DestroyChildren();
michael@0 110
michael@0 111 nsIDocumentLoader* ChildAt(int32_t i) {
michael@0 112 return mChildList.SafeElementAt(i, nullptr);
michael@0 113 }
michael@0 114
michael@0 115 void FireOnProgressChange(nsDocLoader* aLoadInitiator,
michael@0 116 nsIRequest *request,
michael@0 117 int64_t aProgress,
michael@0 118 int64_t aProgressMax,
michael@0 119 int64_t aProgressDelta,
michael@0 120 int64_t aTotalProgress,
michael@0 121 int64_t aMaxTotalProgress);
michael@0 122
michael@0 123 // This should be at least 2 long since we'll generally always
michael@0 124 // have the current page and the global docloader on the ancestor
michael@0 125 // list. But to deal with frames it's better to make it a bit
michael@0 126 // longer, and it's always a stack temporary so there's no real
michael@0 127 // reason not to.
michael@0 128 typedef nsAutoTArray<nsRefPtr<nsDocLoader>, 8> WebProgressList;
michael@0 129 void GatherAncestorWebProgresses(WebProgressList& aList);
michael@0 130
michael@0 131 void FireOnStateChange(nsIWebProgress *aProgress,
michael@0 132 nsIRequest* request,
michael@0 133 int32_t aStateFlags,
michael@0 134 nsresult aStatus);
michael@0 135
michael@0 136 // The guts of FireOnStateChange, but does not call itself on our ancestors.
michael@0 137 // The arguments that are const are const so that we can detect cases when
michael@0 138 // DoFireOnStateChange wants to propagate changes to the next web progress
michael@0 139 // at compile time. The ones that are not, are references so that such
michael@0 140 // changes can be propagated.
michael@0 141 void DoFireOnStateChange(nsIWebProgress * const aProgress,
michael@0 142 nsIRequest* const request,
michael@0 143 int32_t &aStateFlags,
michael@0 144 const nsresult aStatus);
michael@0 145
michael@0 146 void FireOnStatusChange(nsIWebProgress *aWebProgress,
michael@0 147 nsIRequest *aRequest,
michael@0 148 nsresult aStatus,
michael@0 149 const char16_t* aMessage);
michael@0 150
michael@0 151 void FireOnLocationChange(nsIWebProgress* aWebProgress,
michael@0 152 nsIRequest* aRequest,
michael@0 153 nsIURI *aUri,
michael@0 154 uint32_t aFlags);
michael@0 155
michael@0 156 bool RefreshAttempted(nsIWebProgress* aWebProgress,
michael@0 157 nsIURI *aURI,
michael@0 158 int32_t aDelay,
michael@0 159 bool aSameURI);
michael@0 160
michael@0 161 // this function is overridden by the docshell, it is provided so that we
michael@0 162 // can pass more information about redirect state (the normal OnStateChange
michael@0 163 // doesn't get the new channel).
michael@0 164 // @param aRedirectFlags The flags being sent to OnStateChange that
michael@0 165 // indicate the type of redirect.
michael@0 166 // @param aStateFlags The channel flags normally sent to OnStateChange.
michael@0 167 virtual void OnRedirectStateChange(nsIChannel* aOldChannel,
michael@0 168 nsIChannel* aNewChannel,
michael@0 169 uint32_t aRedirectFlags,
michael@0 170 uint32_t aStateFlags) {}
michael@0 171
michael@0 172 void doStartDocumentLoad();
michael@0 173 void doStartURLLoad(nsIRequest *request);
michael@0 174 void doStopURLLoad(nsIRequest *request, nsresult aStatus);
michael@0 175 void doStopDocumentLoad(nsIRequest *request, nsresult aStatus);
michael@0 176
michael@0 177 // Inform a parent docloader that aChild is about to call its onload
michael@0 178 // handler.
michael@0 179 bool ChildEnteringOnload(nsIDocumentLoader* aChild) {
michael@0 180 // It's ok if we're already in the list -- we'll just be in there twice
michael@0 181 // and then the RemoveObject calls from ChildDoneWithOnload will remove
michael@0 182 // us.
michael@0 183 return mChildrenInOnload.AppendObject(aChild);
michael@0 184 }
michael@0 185
michael@0 186 // Inform a parent docloader that aChild is done calling its onload
michael@0 187 // handler.
michael@0 188 void ChildDoneWithOnload(nsIDocumentLoader* aChild) {
michael@0 189 mChildrenInOnload.RemoveObject(aChild);
michael@0 190 DocLoaderIsEmpty(true);
michael@0 191 }
michael@0 192
michael@0 193 protected:
michael@0 194 struct nsStatusInfo : public mozilla::LinkedListElement<nsStatusInfo>
michael@0 195 {
michael@0 196 nsString mStatusMessage;
michael@0 197 nsresult mStatusCode;
michael@0 198 // Weak mRequest is ok; we'll be told if it decides to go away.
michael@0 199 nsIRequest * const mRequest;
michael@0 200
michael@0 201 nsStatusInfo(nsIRequest* aRequest) :
michael@0 202 mRequest(aRequest)
michael@0 203 {
michael@0 204 MOZ_COUNT_CTOR(nsStatusInfo);
michael@0 205 }
michael@0 206 ~nsStatusInfo()
michael@0 207 {
michael@0 208 MOZ_COUNT_DTOR(nsStatusInfo);
michael@0 209 }
michael@0 210 };
michael@0 211
michael@0 212 struct nsRequestInfo : public PLDHashEntryHdr
michael@0 213 {
michael@0 214 nsRequestInfo(const void* key)
michael@0 215 : mKey(key), mCurrentProgress(0), mMaxProgress(0), mUploading(false)
michael@0 216 , mLastStatus(nullptr)
michael@0 217 {
michael@0 218 MOZ_COUNT_CTOR(nsRequestInfo);
michael@0 219 }
michael@0 220
michael@0 221 ~nsRequestInfo()
michael@0 222 {
michael@0 223 MOZ_COUNT_DTOR(nsRequestInfo);
michael@0 224 }
michael@0 225
michael@0 226 nsIRequest* Request() {
michael@0 227 return static_cast<nsIRequest*>(const_cast<void*>(mKey));
michael@0 228 }
michael@0 229
michael@0 230 const void* mKey; // Must be first for the pldhash stubs to work
michael@0 231 int64_t mCurrentProgress;
michael@0 232 int64_t mMaxProgress;
michael@0 233 bool mUploading;
michael@0 234
michael@0 235 nsAutoPtr<nsStatusInfo> mLastStatus;
michael@0 236 };
michael@0 237
michael@0 238 static bool RequestInfoHashInitEntry(PLDHashTable* table, PLDHashEntryHdr* entry,
michael@0 239 const void* key);
michael@0 240 static void RequestInfoHashClearEntry(PLDHashTable* table, PLDHashEntryHdr* entry);
michael@0 241
michael@0 242 // IMPORTANT: The ownership implicit in the following member
michael@0 243 // variables has been explicitly checked and set using nsCOMPtr
michael@0 244 // for owning pointers and raw COM interface pointers for weak
michael@0 245 // (ie, non owning) references. If you add any members to this
michael@0 246 // class, please make the ownership explicit (pinkerton, scc).
michael@0 247
michael@0 248 nsCOMPtr<nsIRequest> mDocumentRequest; // [OWNER] ???compare with document
michael@0 249
michael@0 250 nsDocLoader* mParent; // [WEAK]
michael@0 251
michael@0 252 nsVoidArray mListenerInfoList;
michael@0 253
michael@0 254 nsCOMPtr<nsILoadGroup> mLoadGroup;
michael@0 255 // We hold weak refs to all our kids
michael@0 256 nsTObserverArray<nsDocLoader*> mChildList;
michael@0 257
michael@0 258 // The following member variables are related to the new nsIWebProgress
michael@0 259 // feedback interfaces that travis cooked up.
michael@0 260 int32_t mProgressStateFlags;
michael@0 261
michael@0 262 int64_t mCurrentSelfProgress;
michael@0 263 int64_t mMaxSelfProgress;
michael@0 264
michael@0 265 int64_t mCurrentTotalProgress;
michael@0 266 int64_t mMaxTotalProgress;
michael@0 267
michael@0 268 PLDHashTable mRequestInfoHash;
michael@0 269 int64_t mCompletedTotalProgress;
michael@0 270
michael@0 271 mozilla::LinkedList<nsStatusInfo> mStatusInfoList;
michael@0 272
michael@0 273 /*
michael@0 274 * This flag indicates that the loader is loading a document. It is set
michael@0 275 * from the call to LoadDocument(...) until the OnConnectionsComplete(...)
michael@0 276 * notification is fired...
michael@0 277 */
michael@0 278 bool mIsLoadingDocument;
michael@0 279
michael@0 280 /* Flag to indicate that we're in the process of restoring a document. */
michael@0 281 bool mIsRestoringDocument;
michael@0 282
michael@0 283 /* Flag to indicate that we're in the process of flushing layout
michael@0 284 under DocLoaderIsEmpty() and should not do another flush. */
michael@0 285 bool mDontFlushLayout;
michael@0 286
michael@0 287 /* Flag to indicate whether we should consider ourselves as currently
michael@0 288 flushing layout for the purposes of IsBusy. For example, if Stop has
michael@0 289 been called then IsBusy should return false even if we are still
michael@0 290 flushing. */
michael@0 291 bool mIsFlushingLayout;
michael@0 292
michael@0 293 private:
michael@0 294 // A list of kids that are in the middle of their onload calls and will let
michael@0 295 // us know once they're done. We don't want to fire onload for "normal"
michael@0 296 // DocLoaderIsEmpty calls (those coming from requests finishing in our
michael@0 297 // loadgroup) unless this is empty.
michael@0 298 nsCOMArray<nsIDocumentLoader> mChildrenInOnload;
michael@0 299
michael@0 300 // DocLoaderIsEmpty should be called whenever the docloader may be empty.
michael@0 301 // This method is idempotent and does nothing if the docloader is not in
michael@0 302 // fact empty. This method _does_ make sure that layout is flushed if our
michael@0 303 // loadgroup has no active requests before checking for "real" emptiness if
michael@0 304 // aFlushLayout is true.
michael@0 305 void DocLoaderIsEmpty(bool aFlushLayout);
michael@0 306
michael@0 307 nsListenerInfo *GetListenerInfo(nsIWebProgressListener* aListener);
michael@0 308
michael@0 309 int64_t GetMaxTotalProgress();
michael@0 310
michael@0 311 nsresult AddRequestInfo(nsIRequest* aRequest);
michael@0 312 void RemoveRequestInfo(nsIRequest* aRequest);
michael@0 313 nsRequestInfo *GetRequestInfo(nsIRequest* aRequest);
michael@0 314 void ClearRequestInfoHash();
michael@0 315 int64_t CalculateMaxProgress();
michael@0 316 static PLDHashOperator CalcMaxProgressCallback(PLDHashTable* table,
michael@0 317 PLDHashEntryHdr* hdr,
michael@0 318 uint32_t number, void* arg);
michael@0 319 /// void DumpChannelInfo(void);
michael@0 320
michael@0 321 // used to clear our internal progress state between loads...
michael@0 322 void ClearInternalProgress();
michael@0 323 };
michael@0 324
michael@0 325 NS_DEFINE_STATIC_IID_ACCESSOR(nsDocLoader, NS_THIS_DOCLOADER_IMPL_CID)
michael@0 326
michael@0 327 #endif /* nsDocLoader_h__ */

mercurial