Backed out changeset 177eae915693 (bug 1206581) for bustage
[gecko.git] / image / imgRequestProxy.h
blobdd61fbb80868956156099a7fc6c3778059689481
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/. */
7 #ifndef mozilla_image_imgRequestProxy_h
8 #define mozilla_image_imgRequestProxy_h
10 #include "imgIRequest.h"
11 #include "nsISecurityInfoProvider.h"
13 #include "nsILoadGroup.h"
14 #include "nsISupportsPriority.h"
15 #include "nsITimedChannel.h"
16 #include "nsCOMPtr.h"
17 #include "nsThreadUtils.h"
18 #include "mozilla/TimeStamp.h"
19 #include "mozilla/UniquePtr.h"
20 #include "mozilla/gfx/Rect.h"
22 #include "imgRequest.h"
23 #include "IProgressObserver.h"
25 #define NS_IMGREQUESTPROXY_CID \
26 { /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */ \
27 0x20557898, \
28 0x1dd2, \
29 0x11b2, \
30 {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
33 class imgINotificationObserver;
34 class imgStatusNotifyRunnable;
35 class ProxyBehaviour;
37 namespace mozilla {
38 namespace image {
39 class Image;
40 class ImageURL;
41 class ProgressTracker;
42 } // namespace image
43 } // namespace mozilla
45 class imgRequestProxy : public imgIRequest,
46 public mozilla::image::IProgressObserver,
47 public nsISupportsPriority,
48 public nsISecurityInfoProvider,
49 public nsITimedChannel
51 protected:
52 virtual ~imgRequestProxy();
54 public:
55 typedef mozilla::image::Image Image;
56 typedef mozilla::image::ImageURL ImageURL;
57 typedef mozilla::image::ProgressTracker ProgressTracker;
59 MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
60 NS_DECL_ISUPPORTS
61 NS_DECL_IMGIREQUEST
62 NS_DECL_NSIREQUEST
63 NS_DECL_NSISUPPORTSPRIORITY
64 NS_DECL_NSISECURITYINFOPROVIDER
65 // nsITimedChannel declared below
67 imgRequestProxy();
69 // Callers to Init or ChangeOwner are required to call NotifyListener after
70 // (although not immediately after) doing so.
71 nsresult Init(imgRequest* aOwner,
72 nsILoadGroup* aLoadGroup,
73 ImageURL* aURI,
74 imgINotificationObserver* aObserver);
76 nsresult ChangeOwner(imgRequest* aNewOwner); // this will change mOwner.
77 // Do not call this if the
78 // previous owner has already
79 // sent notifications out!
81 void AddToLoadGroup();
82 void RemoveFromLoadGroup(bool releaseLoadGroup);
84 inline bool HasObserver() const {
85 return mListener != nullptr;
88 // Asynchronously notify this proxy's listener of the current state of the
89 // image, and, if we have an imgRequest mOwner, any status changes that
90 // happen between the time this function is called and the time the
91 // notification is scheduled.
92 void NotifyListener();
94 // Synchronously notify this proxy's listener of the current state of the
95 // image. Only use this function if you are currently servicing an
96 // asynchronously-called function.
97 void SyncNotifyListener();
99 // imgINotificationObserver methods:
100 virtual void Notify(int32_t aType,
101 const mozilla::gfx::IntRect* aRect = nullptr) override;
102 virtual void OnLoadComplete(bool aLastPart) override;
104 // imgIOnloadBlocker methods:
105 virtual void BlockOnload() override;
106 virtual void UnblockOnload() override;
108 // Other, internal-only methods:
109 virtual void SetHasImage() override;
111 // Whether we want notifications from ProgressTracker to be deferred until
112 // an event it has scheduled has been fired.
113 virtual bool NotificationsDeferred() const override
115 return mDeferNotifications;
117 virtual void SetNotificationsDeferred(bool aDeferNotifications) override
119 mDeferNotifications = aDeferNotifications;
122 // Removes all animation consumers that were created with
123 // IncrementAnimationConsumers. This is necessary since we need
124 // to do it before the proxy itself is destroyed. See
125 // imgRequest::RemoveProxy
126 void ClearAnimationConsumers();
128 virtual nsresult Clone(imgINotificationObserver* aObserver,
129 imgRequestProxy** aClone);
130 nsresult GetStaticRequest(imgRequestProxy** aReturn);
132 nsresult GetURI(ImageURL** aURI);
134 protected:
135 friend class mozilla::image::ProgressTracker;
136 friend class imgStatusNotifyRunnable;
138 class imgCancelRunnable;
139 friend class imgCancelRunnable;
141 class imgCancelRunnable : public nsRunnable
143 public:
144 imgCancelRunnable(imgRequestProxy* owner, nsresult status)
145 : mOwner(owner), mStatus(status)
148 NS_IMETHOD Run() override {
149 mOwner->DoCancel(mStatus);
150 return NS_OK;
153 private:
154 RefPtr<imgRequestProxy> mOwner;
155 nsresult mStatus;
158 /* Finish up canceling ourselves */
159 void DoCancel(nsresult status);
161 /* Do the proper refcount management to null out mListener */
162 void NullOutListener();
164 void DoRemoveFromLoadGroup() {
165 RemoveFromLoadGroup(true);
168 // Return the ProgressTracker associated with mOwner and/or mImage. It may
169 // live either on mOwner or mImage, depending on whether
170 // (a) we have an mOwner at all
171 // (b) whether mOwner has instantiated its image yet
172 already_AddRefed<ProgressTracker> GetProgressTracker() const;
174 nsITimedChannel* TimedChannel()
176 if (!GetOwner()) {
177 return nullptr;
179 return GetOwner()->GetTimedChannel();
182 already_AddRefed<Image> GetImage() const;
183 bool HasImage() const;
184 imgRequest* GetOwner() const;
186 nsresult PerformClone(imgINotificationObserver* aObserver,
187 imgRequestProxy* (aAllocFn)(imgRequestProxy*),
188 imgRequestProxy** aClone);
190 public:
191 NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
193 protected:
194 mozilla::UniquePtr<ProxyBehaviour> mBehaviour;
196 private:
197 friend class imgCacheValidator;
198 friend imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis);
200 // The URI of our request.
201 RefPtr<ImageURL> mURI;
203 // mListener is only promised to be a weak ref (see imgILoader.idl),
204 // but we actually keep a strong ref to it until we've seen our
205 // first OnStopRequest.
206 imgINotificationObserver* MOZ_UNSAFE_REF("Observers must call Cancel() or "
207 "CancelAndForgetObserver() before "
208 "they are destroyed") mListener;
210 nsCOMPtr<nsILoadGroup> mLoadGroup;
212 nsLoadFlags mLoadFlags;
213 uint32_t mLockCount;
214 uint32_t mAnimationConsumers;
215 bool mCanceled;
216 bool mIsInLoadGroup;
217 bool mListenerIsStrongRef;
218 bool mDecodeRequested;
220 // Whether we want to defer our notifications by the non-virtual Observer
221 // interfaces as image loads proceed.
222 bool mDeferNotifications;
225 // Used for static image proxies for which no requests are available, so
226 // certain behaviours must be overridden to compensate.
227 class imgRequestProxyStatic : public imgRequestProxy
230 public:
231 imgRequestProxyStatic(Image* aImage, nsIPrincipal* aPrincipal);
233 NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) override;
235 using imgRequestProxy::Clone;
237 virtual nsresult Clone(imgINotificationObserver* aObserver,
238 imgRequestProxy** aClone) override;
240 protected:
241 friend imgRequestProxy* NewStaticProxy(imgRequestProxy*);
243 // Our principal. We have to cache it, rather than accessing the underlying
244 // request on-demand, because static proxies don't have an underlying request.
245 nsCOMPtr<nsIPrincipal> mPrincipal;
248 #endif // mozilla_image_imgRequestProxy_h