1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : *
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is mozilla.org code.
17 : *
18 : * The Initial Developer of the Original Code is Mozilla Foundation.
19 : *
20 : * Portions created by the Initial Developer are Copyright (C) 2010
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Joe Drew <joe@drew.ca> (original author)
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef imgStatusTracker_h__
41 : #define imgStatusTracker_h__
42 :
43 : class imgIContainer;
44 : class imgRequest;
45 : class imgRequestProxy;
46 : class imgStatusNotifyRunnable;
47 : class imgRequestNotifyRunnable;
48 : struct nsIntRect;
49 : namespace mozilla {
50 : namespace image {
51 : class Image;
52 : } // namespace image
53 : } // namespace mozilla
54 :
55 :
56 : #include "nsCOMPtr.h"
57 : #include "nsIRunnable.h"
58 : #include "prtypes.h"
59 : #include "nscore.h"
60 :
61 : enum {
62 : stateRequestStarted = PR_BIT(0),
63 : stateHasSize = PR_BIT(1),
64 : stateDecodeStarted = PR_BIT(2),
65 : stateDecodeStopped = PR_BIT(3),
66 : stateFrameStopped = PR_BIT(4),
67 : stateRequestStopped = PR_BIT(5)
68 : };
69 :
70 : /*
71 : * The image status tracker is a class that encapsulates all the loading and
72 : * decoding status about an Image, and makes it possible to send notifications
73 : * to imgRequestProxys, both synchronously (i.e., the status now) and
74 : * asynchronously (the status later).
75 : *
76 : * When a new proxy needs to be notified of the current state of an image, call
77 : * the Notify() method on this class with the relevant proxy as its argument,
78 : * and the notifications will be replayed to the proxy asynchronously.
79 : */
80 :
81 : class imgStatusTracker
82 24 : {
83 : public:
84 : // aImage is the image that this status tracker will pass to the
85 : // imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
86 : // alive as long as this instance is, because we hold a weak reference to it.
87 : imgStatusTracker(mozilla::image::Image* aImage);
88 : imgStatusTracker(const imgStatusTracker& aOther);
89 :
90 : // Image-setter, for imgStatusTrackers created by imgRequest::Init, which
91 : // are created before their Image is created. This method should only
92 : // be called once, and only on an imgStatusTracker that was initialized
93 : // without an image.
94 : void SetImage(mozilla::image::Image* aImage);
95 :
96 : // Schedule an asynchronous "replaying" of all the notifications that would
97 : // have to happen to put us in the current state.
98 : // We will also take note of any notifications that happen between the time
99 : // Notify() is called and when we call SyncNotify on |proxy|, and replay them
100 : // as well.
101 : void Notify(imgRequest* request, imgRequestProxy* proxy);
102 :
103 : // Schedule an asynchronous "replaying" of all the notifications that would
104 : // have to happen to put us in the state we are in right now.
105 : // Unlike Notify(), does *not* take into account future notifications.
106 : // This is only useful if you do not have an imgRequest, e.g., if you are a
107 : // static request returned from imgIRequest::GetStaticRequest().
108 : void NotifyCurrentState(imgRequestProxy* proxy);
109 :
110 : // "Replay" all of the notifications that would have to happen to put us in
111 : // the state we're currently in.
112 : // Only use this if you're already servicing an asynchronous call (e.g.
113 : // OnStartRequest).
114 : void SyncNotify(imgRequestProxy* proxy);
115 :
116 : // Send all notifications that would be necessary to make |proxy| believe the
117 : // request is finished downloading and decoding.
118 : // If aOnlySendStopRequest is true, we will only send OnStopRequest, and then
119 : // only if that is necessary.
120 : void EmulateRequestFinished(imgRequestProxy* proxy, nsresult aStatus,
121 : bool aOnlySendStopRequest);
122 :
123 : // Returns whether we are in the process of loading; that is, whether we have
124 : // not received OnStopRequest.
125 : bool IsLoading() const;
126 :
127 : // Get the current image status (as in imgIRequest).
128 : PRUint32 GetImageStatus() const;
129 :
130 : // Following are all the notification methods. You must call the Record
131 : // variant on this status tracker, then call the Send variant for each proxy
132 : // you want to notify.
133 :
134 : // Call when the request is being cancelled.
135 : void RecordCancel();
136 :
137 : // Shorthand for recording all the load notifications: StartRequest,
138 : // StartContainer, StopRequest.
139 : void RecordLoaded();
140 :
141 : // Shorthand for recording all the decode notifications: StartDecode,
142 : // StartFrame, DataAvailable, StopFrame, StopContainer, StopDecode.
143 : void RecordDecoded();
144 :
145 : /* non-virtual imgIDecoderObserver methods */
146 : void RecordStartDecode();
147 : void SendStartDecode(imgRequestProxy* aProxy);
148 : void RecordStartContainer(imgIContainer* aContainer);
149 : void SendStartContainer(imgRequestProxy* aProxy, imgIContainer* aContainer);
150 : void RecordStartFrame(PRUint32 aFrame);
151 : void SendStartFrame(imgRequestProxy* aProxy, PRUint32 aFrame);
152 : void RecordDataAvailable(bool aCurrentFrame, const nsIntRect* aRect);
153 : void SendDataAvailable(imgRequestProxy* aProxy, bool aCurrentFrame, const nsIntRect* aRect);
154 : void RecordStopFrame(PRUint32 aFrame);
155 : void SendStopFrame(imgRequestProxy* aProxy, PRUint32 aFrame);
156 : void RecordStopContainer(imgIContainer* aContainer);
157 : void SendStopContainer(imgRequestProxy* aProxy, imgIContainer* aContainer);
158 : void RecordStopDecode(nsresult status, const PRUnichar* statusArg);
159 : void SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus, const PRUnichar* statusArg);
160 : void RecordDiscard();
161 : void SendDiscard(imgRequestProxy* aProxy);
162 : void RecordImageIsAnimated();
163 : void SendImageIsAnimated(imgRequestProxy *aProxy);
164 :
165 : /* non-virtual imgIContainerObserver methods */
166 : void RecordFrameChanged(imgIContainer* aContainer,
167 : const nsIntRect* aDirtyRect);
168 : void SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer,
169 : const nsIntRect* aDirtyRect);
170 :
171 : /* non-virtual sort-of-nsIRequestObserver methods */
172 : void RecordStartRequest();
173 : void SendStartRequest(imgRequestProxy* aProxy);
174 : void RecordStopRequest(bool aLastPart, nsresult aStatus);
175 : void SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus);
176 :
177 : private:
178 : friend class imgStatusNotifyRunnable;
179 : friend class imgRequestNotifyRunnable;
180 :
181 : nsCOMPtr<nsIRunnable> mRequestRunnable;
182 :
183 : // A weak pointer to the Image, because it owns us, and we
184 : // can't create a cycle.
185 : mozilla::image::Image* mImage;
186 : PRUint32 mState;
187 : nsresult mImageStatus;
188 : bool mHadLastPart;
189 : };
190 :
191 : #endif
|