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"
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 */ \
30 {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
33 class imgINotificationObserver
;
34 class imgStatusNotifyRunnable
;
41 class ProgressTracker
;
43 } // namespace mozilla
45 class imgRequestProxy
: public imgIRequest
,
46 public mozilla::image::IProgressObserver
,
47 public nsISupportsPriority
,
48 public nsISecurityInfoProvider
,
49 public nsITimedChannel
52 virtual ~imgRequestProxy();
55 typedef mozilla::image::Image Image
;
56 typedef mozilla::image::ImageURL ImageURL
;
57 typedef mozilla::image::ProgressTracker ProgressTracker
;
59 MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy
)
63 NS_DECL_NSISUPPORTSPRIORITY
64 NS_DECL_NSISECURITYINFOPROVIDER
65 // nsITimedChannel declared below
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
,
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
);
135 friend class mozilla::image::ProgressTracker
;
136 friend class imgStatusNotifyRunnable
;
138 class imgCancelRunnable
;
139 friend class imgCancelRunnable
;
141 class imgCancelRunnable
: public nsRunnable
144 imgCancelRunnable(imgRequestProxy
* owner
, nsresult status
)
145 : mOwner(owner
), mStatus(status
)
148 NS_IMETHOD
Run() override
{
149 mOwner
->DoCancel(mStatus
);
154 RefPtr
<imgRequestProxy
> mOwner
;
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()
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
);
191 NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
194 mozilla::UniquePtr
<ProxyBehaviour
> mBehaviour
;
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
;
214 uint32_t mAnimationConsumers
;
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
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
;
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