LCOV - code coverage report
Current view: directory - image/src - imgStatusTracker.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 235 186 79.1 %
Date: 2012-06-02 Functions: 46 35 76.1 %

       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                 : #include "imgStatusTracker.h"
      41                 : 
      42                 : #include "imgRequest.h"
      43                 : #include "imgIContainer.h"
      44                 : #include "imgRequestProxy.h"
      45                 : #include "Image.h"
      46                 : #include "ImageLogging.h"
      47                 : #include "RasterImage.h"
      48                 : 
      49                 : using namespace mozilla::image;
      50                 : 
      51                 : static nsresult
      52              29 : GetResultFromImageStatus(PRUint32 aStatus)
      53                 : {
      54              29 :   if (aStatus & imgIRequest::STATUS_ERROR)
      55               9 :     return NS_IMAGELIB_ERROR_FAILURE;
      56              20 :   if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE)
      57              20 :     return NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
      58               0 :   return NS_OK;
      59                 : }
      60                 : 
      61              24 : imgStatusTracker::imgStatusTracker(Image* aImage)
      62                 :   : mImage(aImage),
      63                 :     mState(0),
      64                 :     mImageStatus(imgIRequest::STATUS_NONE),
      65              24 :     mHadLastPart(false)
      66              24 : {}
      67                 : 
      68               0 : imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
      69                 :   : mImage(aOther.mImage),
      70                 :     mState(aOther.mState),
      71                 :     mImageStatus(aOther.mImageStatus),
      72               0 :     mHadLastPart(aOther.mHadLastPart)
      73                 :     // Note: we explicitly don't copy mRequestRunnable, because it won't be
      74                 :     // nulled out when the mRequestRunnable's Run function eventually gets
      75                 :     // called.
      76               0 : {}
      77                 : 
      78                 : void
      79               8 : imgStatusTracker::SetImage(Image* aImage)
      80                 : {
      81               8 :   NS_ABORT_IF_FALSE(aImage, "Setting null image");
      82               8 :   NS_ABORT_IF_FALSE(!mImage, "Setting image when we already have one");
      83               8 :   mImage = aImage;
      84               8 : }
      85                 : 
      86                 : bool
      87              12 : imgStatusTracker::IsLoading() const
      88                 : {
      89                 :   // Checking for whether OnStopRequest has fired allows us to say we're
      90                 :   // loading before OnStartRequest gets called, letting the request properly
      91                 :   // get removed from the cache in certain cases.
      92              12 :   return !(mState & stateRequestStopped);
      93                 : }
      94                 : 
      95                 : PRUint32
      96               0 : imgStatusTracker::GetImageStatus() const
      97                 : {
      98               0 :   return mImageStatus;
      99                 : }
     100                 : 
     101                 : // A helper class to allow us to call SyncNotify asynchronously.
     102                 : class imgRequestNotifyRunnable : public nsRunnable
     103              20 : {
     104                 :   public:
     105               5 :     imgRequestNotifyRunnable(imgRequest* request, imgRequestProxy* requestproxy)
     106               5 :       : mRequest(request)
     107                 :     {
     108               5 :       mProxies.AppendElement(requestproxy);
     109               5 :     }
     110                 : 
     111               5 :     NS_IMETHOD Run()
     112                 :     {
     113               5 :       imgStatusTracker& statusTracker = mRequest->GetStatusTracker();
     114                 : 
     115              12 :       for (PRUint32 i = 0; i < mProxies.Length(); ++i) {
     116               7 :         mProxies[i]->SetNotificationsDeferred(false);
     117               7 :         statusTracker.SyncNotify(mProxies[i]);
     118                 :       }
     119                 : 
     120               5 :       statusTracker.mRequestRunnable = nsnull;
     121               5 :       return NS_OK;
     122                 :     }
     123                 : 
     124               2 :     void AddProxy(imgRequestProxy* aRequestProxy)
     125                 :     {
     126               2 :       mProxies.AppendElement(aRequestProxy);
     127               2 :     }
     128                 : 
     129                 :   private:
     130                 :     friend class imgStatusTracker;
     131                 : 
     132                 :     nsRefPtr<imgRequest> mRequest;
     133                 :     nsTArray<nsRefPtr<imgRequestProxy> > mProxies;
     134                 : };
     135                 : 
     136                 : void
     137               7 : imgStatusTracker::Notify(imgRequest* request, imgRequestProxy* proxy)
     138                 : {
     139                 : #ifdef PR_LOGGING
     140              14 :   nsCOMPtr<nsIURI> uri;
     141               7 :   request->GetURI(getter_AddRefs(uri));
     142              14 :   nsCAutoString spec;
     143               7 :   uri->GetSpec(spec);
     144               7 :   LOG_FUNC_WITH_PARAM(gImgLog, "imgStatusTracker::Notify async", "uri", spec.get());
     145                 : #endif
     146                 : 
     147               7 :   proxy->SetNotificationsDeferred(true);
     148                 : 
     149                 :   // If we have an existing runnable that we can use, we just append this proxy
     150                 :   // to its list of proxies to be notified. This ensures we don't unnecessarily
     151                 :   // delay onload.
     152               7 :   imgRequestNotifyRunnable* runnable = static_cast<imgRequestNotifyRunnable*>(mRequestRunnable.get());
     153               7 :   if (runnable && runnable->mRequest == request) {
     154               2 :     runnable->AddProxy(proxy);
     155                 :   } else {
     156                 :     // It's okay to overwrite an existing mRequestRunnable, because adding a
     157                 :     // new proxy is strictly a performance optimization. The notification will
     158                 :     // always happen, regardless of whether we hold a reference to a runnable.
     159               5 :     mRequestRunnable = new imgRequestNotifyRunnable(request, proxy);
     160               5 :     NS_DispatchToCurrentThread(mRequestRunnable);
     161                 :   }
     162               7 : }
     163                 : 
     164                 : // A helper class to allow us to call SyncNotify asynchronously for a given,
     165                 : // fixed, state.
     166                 : class imgStatusNotifyRunnable : public nsRunnable
     167               0 : {
     168                 :   public:
     169               0 :     imgStatusNotifyRunnable(imgStatusTracker& status,
     170                 :                             imgRequestProxy* requestproxy)
     171               0 :       : mStatus(status), mImage(status.mImage), mProxy(requestproxy)
     172               0 :     {}
     173                 : 
     174               0 :     NS_IMETHOD Run()
     175                 :     {
     176               0 :       mProxy->SetNotificationsDeferred(false);
     177                 : 
     178               0 :       mStatus.SyncNotify(mProxy);
     179               0 :       return NS_OK;
     180                 :     }
     181                 : 
     182                 :   private:
     183                 :     imgStatusTracker mStatus;
     184                 :     // We have to hold on to a reference to the tracker's image, just in case
     185                 :     // it goes away while we're in the event queue.
     186                 :     nsRefPtr<Image> mImage;
     187                 :     nsRefPtr<imgRequestProxy> mProxy;
     188                 : };
     189                 : 
     190                 : void
     191               0 : imgStatusTracker::NotifyCurrentState(imgRequestProxy* proxy)
     192                 : {
     193                 : #ifdef PR_LOGGING
     194               0 :   nsCOMPtr<nsIURI> uri;
     195               0 :   proxy->GetURI(getter_AddRefs(uri));
     196               0 :   nsCAutoString spec;
     197               0 :   uri->GetSpec(spec);
     198               0 :   LOG_FUNC_WITH_PARAM(gImgLog, "imgStatusTracker::NotifyCurrentState", "uri", spec.get());
     199                 : #endif
     200                 : 
     201               0 :   proxy->SetNotificationsDeferred(true);
     202                 : 
     203                 :   // We don't keep track of 
     204               0 :   nsCOMPtr<nsIRunnable> ev = new imgStatusNotifyRunnable(*this, proxy);
     205               0 :   NS_DispatchToCurrentThread(ev);
     206               0 : }
     207                 : 
     208                 : void
     209              21 : imgStatusTracker::SyncNotify(imgRequestProxy* proxy)
     210                 : {
     211              21 :   NS_ABORT_IF_FALSE(!proxy->NotificationsDeferred(),
     212                 :     "Calling imgStatusTracker::Notify() on a proxy that doesn't want notifications!");
     213                 : 
     214                 : #ifdef PR_LOGGING
     215              42 :   nsCOMPtr<nsIURI> uri;
     216              21 :   proxy->GetURI(getter_AddRefs(uri));
     217              42 :   nsCAutoString spec;
     218              21 :   uri->GetSpec(spec);
     219              42 :   LOG_SCOPE_WITH_PARAM(gImgLog, "imgStatusTracker::SyncNotify", "uri", spec.get());
     220                 : #endif
     221                 : 
     222              42 :   nsCOMPtr<imgIRequest> kungFuDeathGrip(proxy);
     223                 : 
     224                 :   // OnStartRequest
     225              21 :   if (mState & stateRequestStarted)
     226              21 :     proxy->OnStartRequest();
     227                 : 
     228                 :   // OnStartContainer
     229              21 :   if (mState & stateHasSize)
     230              12 :     proxy->OnStartContainer(mImage);
     231                 : 
     232                 :   // OnStartDecode
     233              21 :   if (mState & stateDecodeStarted)
     234               2 :     proxy->OnStartDecode();
     235                 : 
     236              21 :   if (mImage) {
     237              13 :     PRInt16 imageType = mImage->GetType();
     238                 :     // Send frame messages (OnStartFrame, OnDataAvailable, OnStopFrame)
     239              26 :     if (imageType == imgIContainer::TYPE_VECTOR ||
     240              13 :         static_cast<RasterImage*>(mImage)->GetNumFrames() > 0) {
     241                 : 
     242                 :       PRUint32 frame = (imageType == imgIContainer::TYPE_VECTOR) ?
     243               2 :         0 : static_cast<RasterImage*>(mImage)->GetCurrentFrameIndex();
     244                 : 
     245               2 :       proxy->OnStartFrame(frame);
     246                 : 
     247                 :       // OnDataAvailable
     248                 :       // XXX - Should only send partial rects here, but that needs to
     249                 :       // wait until we fix up the observer interface
     250               2 :       nsIntRect r;
     251               2 :       mImage->GetCurrentFrameRect(r);
     252               2 :       proxy->OnDataAvailable(frame, &r);
     253                 : 
     254               2 :       if (mState & stateFrameStopped)
     255               2 :         proxy->OnStopFrame(frame);
     256                 :     }
     257                 : 
     258                 :     // OnImageIsAnimated
     259              13 :     bool isAnimated = false;
     260                 : 
     261              13 :     nsresult rv = mImage->GetAnimated(&isAnimated);
     262              13 :     if (NS_SUCCEEDED(rv) && isAnimated) {
     263               0 :       proxy->OnImageIsAnimated();
     264                 :     }
     265                 :   }
     266                 : 
     267                 :   // See bug 505385 and imgRequest::OnStopDecode for more information on why we
     268                 :   // call OnStopContainer based on stateDecodeStopped, and why OnStopDecode is
     269                 :   // called with OnStopRequest.
     270              21 :   if (mState & stateDecodeStopped) {
     271               2 :     NS_ABORT_IF_FALSE(mImage, "stopped decoding without ever having an image?");
     272               2 :     proxy->OnStopContainer(mImage);
     273                 :   }
     274                 : 
     275              21 :   if (mState & stateRequestStopped) {
     276              13 :     proxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nsnull);
     277              13 :     proxy->OnStopRequest(mHadLastPart);
     278                 :   }
     279              21 : }
     280                 : 
     281                 : void
     282              27 : imgStatusTracker::EmulateRequestFinished(imgRequestProxy* aProxy, nsresult aStatus,
     283                 :                                                 bool aOnlySendStopRequest)
     284                 : {
     285              54 :   nsCOMPtr<imgIRequest> kungFuDeathGrip(aProxy);
     286                 : 
     287              27 :   if (!aOnlySendStopRequest) {
     288                 :     // The "real" OnStopDecode - fix this with bug 505385.
     289               0 :     if (!(mState & stateDecodeStopped)) {
     290               0 :       aProxy->OnStopContainer(mImage);
     291                 :     }
     292                 : 
     293               0 :     if (!(mState & stateRequestStopped)) {
     294               0 :       aProxy->OnStopDecode(aStatus, nsnull);
     295                 :     }
     296                 :   }
     297                 : 
     298              27 :   if (!(mState & stateRequestStopped)) {
     299               0 :     aProxy->OnStopRequest(true);
     300                 :   }
     301              27 : }
     302                 : 
     303                 : void
     304               8 : imgStatusTracker::RecordCancel()
     305                 : {
     306               8 :   if (!(mImageStatus & imgIRequest::STATUS_LOAD_PARTIAL))
     307               8 :     mImageStatus |= imgIRequest::STATUS_ERROR;
     308               8 : }
     309                 : 
     310                 : void
     311               2 : imgStatusTracker::RecordLoaded()
     312                 : {
     313               2 :   NS_ABORT_IF_FALSE(mImage, "RecordLoaded called before we have an Image");
     314               2 :   mState |= stateRequestStarted | stateHasSize | stateRequestStopped;
     315               2 :   mImageStatus |= imgIRequest::STATUS_SIZE_AVAILABLE | imgIRequest::STATUS_LOAD_COMPLETE;
     316               2 :   mHadLastPart = true;
     317               2 : }
     318                 : 
     319                 : void
     320               2 : imgStatusTracker::RecordDecoded()
     321                 : {
     322               2 :   NS_ABORT_IF_FALSE(mImage, "RecordDecoded called before we have an Image");
     323               2 :   mState |= stateDecodeStarted | stateDecodeStopped | stateFrameStopped;
     324               2 :   mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE | imgIRequest::STATUS_DECODE_COMPLETE;
     325               2 : }
     326                 : 
     327                 : /* non-virtual imgIDecoderObserver methods */
     328                 : void
     329               2 : imgStatusTracker::RecordStartDecode()
     330                 : {
     331               2 :   NS_ABORT_IF_FALSE(mImage, "RecordStartDecode without an Image");
     332               2 :   mState |= stateDecodeStarted;
     333               2 : }
     334                 : 
     335                 : void
     336              10 : imgStatusTracker::SendStartDecode(imgRequestProxy* aProxy)
     337                 : {
     338              10 :   if (!aProxy->NotificationsDeferred())
     339              10 :     aProxy->OnStartDecode();
     340              10 : }
     341                 : 
     342                 : void
     343               6 : imgStatusTracker::RecordStartContainer(imgIContainer* aContainer)
     344                 : {
     345               6 :   NS_ABORT_IF_FALSE(mImage,
     346                 :                     "RecordStartContainer called before we have an Image");
     347               6 :   NS_ABORT_IF_FALSE(mImage == aContainer,
     348                 :                     "RecordStartContainer called with wrong Image");
     349               6 :   mState |= stateHasSize;
     350               6 :   mImageStatus |= imgIRequest::STATUS_SIZE_AVAILABLE;
     351               6 : }
     352                 : 
     353                 : void
     354              20 : imgStatusTracker::SendStartContainer(imgRequestProxy* aProxy, imgIContainer* aContainer)
     355                 : {
     356              20 :   if (!aProxy->NotificationsDeferred())
     357              18 :     aProxy->OnStartContainer(aContainer);
     358              20 : }
     359                 : 
     360                 : void
     361               4 : imgStatusTracker::RecordStartFrame(PRUint32 aFrame)
     362                 : {
     363               4 :   NS_ABORT_IF_FALSE(mImage, "RecordStartFrame called before we have an Image");
     364                 :   // no bookkeeping necessary here - this is implied by imgIContainer's number
     365                 :   // of frames
     366               4 : }
     367                 : 
     368                 : void
     369              20 : imgStatusTracker::SendStartFrame(imgRequestProxy* aProxy, PRUint32 aFrame)
     370                 : {
     371              20 :   if (!aProxy->NotificationsDeferred())
     372              20 :     aProxy->OnStartFrame(aFrame);
     373              20 : }
     374                 : 
     375                 : void
     376               2 : imgStatusTracker::RecordDataAvailable(bool aCurrentFrame, const nsIntRect* aRect)
     377                 : {
     378               2 :   NS_ABORT_IF_FALSE(mImage,
     379                 :                     "RecordDataAvailable called before we have an Image");
     380                 :   // no bookkeeping necessary here - this is implied by imgIContainer's
     381                 :   // number of frames and frame rect
     382               2 : }
     383                 : 
     384                 : void
     385              10 : imgStatusTracker::SendDataAvailable(imgRequestProxy* aProxy, bool aCurrentFrame,
     386                 :                                          const nsIntRect* aRect)
     387                 : {
     388              10 :   if (!aProxy->NotificationsDeferred())
     389              10 :     aProxy->OnDataAvailable(aCurrentFrame, aRect);
     390              10 : }
     391                 : 
     392                 : 
     393                 : void
     394               4 : imgStatusTracker::RecordStopFrame(PRUint32 aFrame)
     395                 : {
     396               4 :   NS_ABORT_IF_FALSE(mImage, "RecordStopFrame called before we have an Image");
     397               4 :   mState |= stateFrameStopped;
     398               4 :   mImageStatus |= imgIRequest::STATUS_FRAME_COMPLETE;
     399               4 : }
     400                 : 
     401                 : void
     402              20 : imgStatusTracker::SendStopFrame(imgRequestProxy* aProxy, PRUint32 aFrame)
     403                 : {
     404              20 :   if (!aProxy->NotificationsDeferred())
     405              20 :     aProxy->OnStopFrame(aFrame);
     406              20 : }
     407                 : 
     408                 : void
     409               2 : imgStatusTracker::RecordStopContainer(imgIContainer* aContainer)
     410                 : {
     411               2 :   NS_ABORT_IF_FALSE(mImage,
     412                 :                     "RecordStopContainer called before we have an Image");
     413                 :   // No-op: see imgRequest::OnStopDecode for more information
     414               2 : }
     415                 : 
     416                 : void
     417              10 : imgStatusTracker::SendStopContainer(imgRequestProxy* aProxy, imgIContainer* aContainer)
     418                 : {
     419                 :   // No-op: see imgRequest::OnStopDecode for more information
     420              10 : }
     421                 : 
     422                 : void
     423               2 : imgStatusTracker::RecordStopDecode(nsresult aStatus, const PRUnichar* statusArg)
     424                 : {
     425               2 :   NS_ABORT_IF_FALSE(mImage,
     426                 :                     "RecordStopDecode called before we have an Image");
     427               2 :   mState |= stateDecodeStopped;
     428                 : 
     429               2 :   if (NS_SUCCEEDED(aStatus))
     430               2 :     mImageStatus |= imgIRequest::STATUS_DECODE_COMPLETE;
     431                 :   // If we weren't successful, clear all success status bits and set error.
     432                 :   else
     433               0 :     mImageStatus = imgIRequest::STATUS_ERROR;
     434               2 : }
     435                 : 
     436                 : void
     437              10 : imgStatusTracker::SendStopDecode(imgRequestProxy* aProxy, nsresult aStatus,
     438                 :                                  const PRUnichar* statusArg)
     439                 : {
     440                 :   // See imgRequest::OnStopDecode for more information on why we call
     441                 :   // OnStopContainer from here this, and why imgRequestProxy::OnStopDecode() is
     442                 :   // called from OnStopRequest() and SyncNotify().
     443              10 :   if (!aProxy->NotificationsDeferred())
     444              10 :     aProxy->OnStopContainer(mImage);
     445              10 : }
     446                 : 
     447                 : void
     448               0 : imgStatusTracker::RecordDiscard()
     449                 : {
     450               0 :   NS_ABORT_IF_FALSE(mImage,
     451                 :                     "RecordDiscard called before we have an Image");
     452                 :   // Clear the state bits we no longer deserve.
     453               0 :   PRUint32 stateBitsToClear = stateDecodeStarted | stateDecodeStopped;
     454               0 :   mState &= ~stateBitsToClear;
     455                 : 
     456                 :   // Clear the status bits we no longer deserve.
     457                 :   PRUint32 statusBitsToClear = imgIRequest::STATUS_FRAME_COMPLETE
     458               0 :                                | imgIRequest::STATUS_DECODE_COMPLETE;
     459               0 :   mImageStatus &= ~statusBitsToClear;
     460               0 : }
     461                 : 
     462                 : void
     463               5 : imgStatusTracker::SendImageIsAnimated(imgRequestProxy* aProxy)
     464                 : {
     465               5 :   if (!aProxy->NotificationsDeferred())
     466               5 :     aProxy->OnImageIsAnimated();
     467               5 : }
     468                 : 
     469                 : void
     470               2 : imgStatusTracker::RecordImageIsAnimated()
     471                 : {
     472               2 :   NS_ABORT_IF_FALSE(mImage,
     473                 :                     "RecordImageIsAnimated called before we have an Image");
     474                 :   // No bookkeeping necessary here - once decoding is complete, GetAnimated()
     475                 :   // will accurately return that this is an animated image. Until that time,
     476                 :   // the OnImageIsAnimated notification is the only indication an observer
     477                 :   // will have that an image has more than 1 frame.
     478               2 : }
     479                 : 
     480                 : void
     481               0 : imgStatusTracker::SendDiscard(imgRequestProxy* aProxy)
     482                 : {
     483               0 :   if (!aProxy->NotificationsDeferred())
     484               0 :     aProxy->OnDiscard();
     485               0 : }
     486                 : 
     487                 : /* non-virtual imgIContainerObserver methods */
     488                 : void
     489               0 : imgStatusTracker::RecordFrameChanged(imgIContainer* aContainer,
     490                 :                                      const nsIntRect* aDirtyRect)
     491                 : {
     492               0 :   NS_ABORT_IF_FALSE(mImage,
     493                 :                     "RecordFrameChanged called before we have an Image");
     494                 :   // no bookkeeping necessary here - this is only for in-frame updates, which we
     495                 :   // don't fire while we're recording
     496               0 : }
     497                 : 
     498                 : void
     499               0 : imgStatusTracker::SendFrameChanged(imgRequestProxy* aProxy, imgIContainer* aContainer,
     500                 :                                    const nsIntRect* aDirtyRect)
     501                 : {
     502               0 :   if (!aProxy->NotificationsDeferred())
     503               0 :     aProxy->FrameChanged(aContainer, aDirtyRect);
     504               0 : }
     505                 : 
     506                 : /* non-virtual sort-of-nsIRequestObserver methods */
     507                 : void
     508               8 : imgStatusTracker::RecordStartRequest()
     509                 : {
     510                 :   // We're starting a new load, so clear any status and state bits indicating
     511                 :   // load/decode
     512               8 :   mImageStatus &= ~imgIRequest::STATUS_LOAD_PARTIAL;
     513               8 :   mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE;
     514               8 :   mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE;
     515               8 :   mState &= ~stateRequestStarted;
     516               8 :   mState &= ~stateDecodeStarted;
     517               8 :   mState &= ~stateDecodeStopped;
     518               8 :   mState &= ~stateRequestStopped;
     519                 : 
     520               8 :   mState |= stateRequestStarted;
     521               8 : }
     522                 : 
     523                 : void
     524              19 : imgStatusTracker::SendStartRequest(imgRequestProxy* aProxy)
     525                 : {
     526              19 :   if (!aProxy->NotificationsDeferred())
     527              16 :     aProxy->OnStartRequest();
     528              19 : }
     529                 : 
     530                 : void
     531               8 : imgStatusTracker::RecordStopRequest(bool aLastPart, nsresult aStatus)
     532                 : {
     533               8 :   mHadLastPart = aLastPart;
     534               8 :   mState |= stateRequestStopped;
     535                 : 
     536                 :   // If we were successful in loading, note that the image is complete.
     537               8 :   if (NS_SUCCEEDED(aStatus))
     538               4 :     mImageStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
     539               8 : }
     540                 : 
     541                 : void
     542              23 : imgStatusTracker::SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus)
     543                 : {
     544                 :   // See bug 505385 and imgRequest::OnStopDecode for more information on why
     545                 :   // OnStopDecode is called with OnStopRequest.
     546              23 :   if (!aProxy->NotificationsDeferred()) {
     547              16 :     aProxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nsnull);
     548              16 :     aProxy->OnStopRequest(aLastPart);
     549                 :   }
     550              23 : }

Generated by: LCOV version 1.7