imgRequestProxy.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. *
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #ifndef mozilla_image_imgRequestProxy_h
  7. #define mozilla_image_imgRequestProxy_h
  8. #include "imgIRequest.h"
  9. #include "nsISecurityInfoProvider.h"
  10. #include "nsILoadGroup.h"
  11. #include "nsISupportsPriority.h"
  12. #include "nsITimedChannel.h"
  13. #include "nsCOMPtr.h"
  14. #include "nsThreadUtils.h"
  15. #include "mozilla/TimeStamp.h"
  16. #include "mozilla/UniquePtr.h"
  17. #include "mozilla/gfx/Rect.h"
  18. #include "imgRequest.h"
  19. #include "IProgressObserver.h"
  20. #define NS_IMGREQUESTPROXY_CID \
  21. { /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */ \
  22. 0x20557898, \
  23. 0x1dd2, \
  24. 0x11b2, \
  25. {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
  26. }
  27. class imgINotificationObserver;
  28. class imgStatusNotifyRunnable;
  29. class ProxyBehaviour;
  30. namespace mozilla {
  31. namespace image {
  32. class Image;
  33. class ImageURL;
  34. class ProgressTracker;
  35. } // namespace image
  36. } // namespace mozilla
  37. class imgRequestProxy : public imgIRequest,
  38. public mozilla::image::IProgressObserver,
  39. public nsISupportsPriority,
  40. public nsISecurityInfoProvider,
  41. public nsITimedChannel
  42. {
  43. protected:
  44. virtual ~imgRequestProxy();
  45. public:
  46. typedef mozilla::image::Image Image;
  47. typedef mozilla::image::ImageURL ImageURL;
  48. typedef mozilla::image::ProgressTracker ProgressTracker;
  49. MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
  50. NS_DECL_ISUPPORTS
  51. NS_DECL_IMGIREQUEST
  52. NS_DECL_NSIREQUEST
  53. NS_DECL_NSISUPPORTSPRIORITY
  54. NS_DECL_NSISECURITYINFOPROVIDER
  55. // nsITimedChannel declared below
  56. imgRequestProxy();
  57. // Callers to Init or ChangeOwner are required to call NotifyListener after
  58. // (although not immediately after) doing so.
  59. nsresult Init(imgRequest* aOwner,
  60. nsILoadGroup* aLoadGroup,
  61. ImageURL* aURI,
  62. imgINotificationObserver* aObserver);
  63. nsresult ChangeOwner(imgRequest* aNewOwner); // this will change mOwner.
  64. // Do not call this if the
  65. // previous owner has already
  66. // sent notifications out!
  67. void AddToLoadGroup();
  68. void RemoveFromLoadGroup(bool releaseLoadGroup);
  69. inline bool HasObserver() const {
  70. return mListener != nullptr;
  71. }
  72. // Asynchronously notify this proxy's listener of the current state of the
  73. // image, and, if we have an imgRequest mOwner, any status changes that
  74. // happen between the time this function is called and the time the
  75. // notification is scheduled.
  76. void NotifyListener();
  77. // Synchronously notify this proxy's listener of the current state of the
  78. // image. Only use this function if you are currently servicing an
  79. // asynchronously-called function.
  80. void SyncNotifyListener();
  81. // imgINotificationObserver methods:
  82. virtual void Notify(int32_t aType,
  83. const mozilla::gfx::IntRect* aRect = nullptr) override;
  84. virtual void OnLoadComplete(bool aLastPart) override;
  85. // imgIOnloadBlocker methods:
  86. virtual void BlockOnload() override;
  87. virtual void UnblockOnload() override;
  88. // Other, internal-only methods:
  89. virtual void SetHasImage() override;
  90. // Whether we want notifications from ProgressTracker to be deferred until
  91. // an event it has scheduled has been fired.
  92. virtual bool NotificationsDeferred() const override
  93. {
  94. return mDeferNotifications;
  95. }
  96. virtual void SetNotificationsDeferred(bool aDeferNotifications) override
  97. {
  98. mDeferNotifications = aDeferNotifications;
  99. }
  100. // Removes all animation consumers that were created with
  101. // IncrementAnimationConsumers. This is necessary since we need
  102. // to do it before the proxy itself is destroyed. See
  103. // imgRequest::RemoveProxy
  104. void ClearAnimationConsumers();
  105. virtual nsresult Clone(imgINotificationObserver* aObserver,
  106. imgRequestProxy** aClone);
  107. nsresult GetStaticRequest(imgRequestProxy** aReturn);
  108. nsresult GetURI(ImageURL** aURI);
  109. protected:
  110. friend class mozilla::image::ProgressTracker;
  111. friend class imgStatusNotifyRunnable;
  112. class imgCancelRunnable;
  113. friend class imgCancelRunnable;
  114. class imgCancelRunnable : public mozilla::Runnable
  115. {
  116. public:
  117. imgCancelRunnable(imgRequestProxy* owner, nsresult status)
  118. : mOwner(owner), mStatus(status)
  119. { }
  120. NS_IMETHOD Run() override {
  121. mOwner->DoCancel(mStatus);
  122. return NS_OK;
  123. }
  124. private:
  125. RefPtr<imgRequestProxy> mOwner;
  126. nsresult mStatus;
  127. };
  128. /* Finish up canceling ourselves */
  129. void DoCancel(nsresult status);
  130. /* Do the proper refcount management to null out mListener */
  131. void NullOutListener();
  132. void DoRemoveFromLoadGroup() {
  133. RemoveFromLoadGroup(true);
  134. }
  135. // Return the ProgressTracker associated with mOwner and/or mImage. It may
  136. // live either on mOwner or mImage, depending on whether
  137. // (a) we have an mOwner at all
  138. // (b) whether mOwner has instantiated its image yet
  139. already_AddRefed<ProgressTracker> GetProgressTracker() const;
  140. nsITimedChannel* TimedChannel()
  141. {
  142. if (!GetOwner()) {
  143. return nullptr;
  144. }
  145. return GetOwner()->GetTimedChannel();
  146. }
  147. already_AddRefed<Image> GetImage() const;
  148. bool HasImage() const;
  149. imgRequest* GetOwner() const;
  150. nsresult PerformClone(imgINotificationObserver* aObserver,
  151. imgRequestProxy* (aAllocFn)(imgRequestProxy*),
  152. imgRequestProxy** aClone);
  153. public:
  154. NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
  155. protected:
  156. mozilla::UniquePtr<ProxyBehaviour> mBehaviour;
  157. private:
  158. friend class imgCacheValidator;
  159. friend imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis);
  160. // The URI of our request.
  161. RefPtr<ImageURL> mURI;
  162. // mListener is only promised to be a weak ref (see imgILoader.idl),
  163. // but we actually keep a strong ref to it until we've seen our
  164. // first OnStopRequest.
  165. imgINotificationObserver* MOZ_UNSAFE_REF("Observers must call Cancel() or "
  166. "CancelAndForgetObserver() before "
  167. "they are destroyed") mListener;
  168. nsCOMPtr<nsILoadGroup> mLoadGroup;
  169. nsLoadFlags mLoadFlags;
  170. uint32_t mLockCount;
  171. uint32_t mAnimationConsumers;
  172. bool mCanceled;
  173. bool mIsInLoadGroup;
  174. bool mListenerIsStrongRef;
  175. bool mDecodeRequested;
  176. // Whether we want to defer our notifications by the non-virtual Observer
  177. // interfaces as image loads proceed.
  178. bool mDeferNotifications;
  179. };
  180. // Used for static image proxies for which no requests are available, so
  181. // certain behaviours must be overridden to compensate.
  182. class imgRequestProxyStatic : public imgRequestProxy
  183. {
  184. public:
  185. imgRequestProxyStatic(Image* aImage, nsIPrincipal* aPrincipal);
  186. NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) override;
  187. using imgRequestProxy::Clone;
  188. virtual nsresult Clone(imgINotificationObserver* aObserver,
  189. imgRequestProxy** aClone) override;
  190. protected:
  191. friend imgRequestProxy* NewStaticProxy(imgRequestProxy*);
  192. // Our principal. We have to cache it, rather than accessing the underlying
  193. // request on-demand, because static proxies don't have an underlying request.
  194. nsCOMPtr<nsIPrincipal> mPrincipal;
  195. };
  196. #endif // mozilla_image_imgRequestProxy_h