image/src/imgRequestProxy.h

Thu, 15 Jan 2015 15:59:08 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:59:08 +0100
branch
TOR_BUG_9701
changeset 10
ac0c01689b40
permissions
-rw-r--r--

Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/. */
     7 #ifndef imgRequestProxy_h__
     8 #define imgRequestProxy_h__
    10 #include "mozilla/WeakPtr.h"
    11 #include "imgIRequest.h"
    12 #include "nsISecurityInfoProvider.h"
    14 #include "nsILoadGroup.h"
    15 #include "nsISupportsPriority.h"
    16 #include "nsITimedChannel.h"
    17 #include "nsCOMPtr.h"
    18 #include "nsAutoPtr.h"
    19 #include "nsThreadUtils.h"
    20 #include "mozilla/TimeStamp.h"
    22 #include "imgRequest.h"
    24 #define NS_IMGREQUESTPROXY_CID \
    25 { /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */         \
    26      0x20557898,                                     \
    27      0x1dd2,                                         \
    28      0x11b2,                                         \
    29     {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
    30 }
    32 class imgINotificationObserver;
    33 class imgRequestNotifyRunnable;
    34 class imgStatusNotifyRunnable;
    35 class nsIntRect;
    36 class ProxyBehaviour;
    38 namespace mozilla {
    39 namespace image {
    40 class Image;
    41 class ImageURL;
    42 } // namespace image
    43 } // namespace mozilla
    45 class imgRequestProxy : public imgIRequest,
    46                         public nsISupportsPriority,
    47                         public nsISecurityInfoProvider,
    48                         public nsITimedChannel,
    49                         public mozilla::SupportsWeakPtr<imgRequestProxy>
    50 {
    51 public:
    52   MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
    53   typedef mozilla::image::ImageURL ImageURL;
    54   NS_DECL_ISUPPORTS
    55   NS_DECL_IMGIREQUEST
    56   NS_DECL_NSIREQUEST
    57   NS_DECL_NSISUPPORTSPRIORITY
    58   NS_DECL_NSISECURITYINFOPROVIDER
    59   // nsITimedChannel declared below
    61   imgRequestProxy();
    62   virtual ~imgRequestProxy();
    64   // Callers to Init or ChangeOwner are required to call NotifyListener after
    65   // (although not immediately after) doing so.
    66   nsresult Init(imgRequest* aOwner,
    67                 nsILoadGroup *aLoadGroup,
    68                 ImageURL* aURI,
    69                 imgINotificationObserver *aObserver);
    71   nsresult ChangeOwner(imgRequest *aNewOwner); // this will change mOwner.  Do not call this if the previous
    72                                                // owner has already sent notifications out!
    74   void AddToLoadGroup();
    75   void RemoveFromLoadGroup(bool releaseLoadGroup);
    77   inline bool HasObserver() const {
    78     return mListener != nullptr;
    79   }
    81   // Asynchronously notify this proxy's listener of the current state of the
    82   // image, and, if we have an imgRequest mOwner, any status changes that
    83   // happen between the time this function is called and the time the
    84   // notification is scheduled.
    85   void NotifyListener();
    87   // Synchronously notify this proxy's listener of the current state of the
    88   // image. Only use this function if you are currently servicing an
    89   // asynchronously-called function.
    90   void SyncNotifyListener();
    92   // Whether we want notifications from imgStatusTracker to be deferred until
    93   // an event it has scheduled has been fired.
    94   bool NotificationsDeferred() const
    95   {
    96     return mDeferNotifications;
    97   }
    98   void SetNotificationsDeferred(bool aDeferNotifications)
    99   {
   100     mDeferNotifications = aDeferNotifications;
   101   }
   103   // XXXbholley - This eventually gets folded into the new notification API.
   104   void SetHasImage();
   106   // Removes all animation consumers that were created with
   107   // IncrementAnimationConsumers. This is necessary since we need
   108   // to do it before the proxy itself is destroyed. See
   109   // imgRequest::RemoveProxy
   110   void ClearAnimationConsumers();
   112   virtual nsresult Clone(imgINotificationObserver* aObserver, imgRequestProxy** aClone);
   113   nsresult GetStaticRequest(imgRequestProxy** aReturn);
   115   nsresult GetURI(ImageURL **aURI);
   117 protected:
   118   friend class imgStatusTracker;
   119   friend class imgStatusNotifyRunnable;
   120   friend class imgRequestNotifyRunnable;
   122   class imgCancelRunnable;
   123   friend class imgCancelRunnable;
   125   class imgCancelRunnable : public nsRunnable
   126   {
   127     public:
   128       imgCancelRunnable(imgRequestProxy* owner, nsresult status)
   129         : mOwner(owner), mStatus(status)
   130       {}
   132       NS_IMETHOD Run() {
   133         mOwner->DoCancel(mStatus);
   134         return NS_OK;
   135       }
   137     private:
   138       nsRefPtr<imgRequestProxy> mOwner;
   139       nsresult mStatus;
   140   };
   142   // The following notification functions are protected to ensure that (friend
   143   // class) imgStatusTracker is the only class allowed to send us
   144   // notifications.
   146   /* non-virtual imgDecoderObserver methods */
   147   void OnStartDecode     ();
   148   void OnStartContainer  ();
   149   void OnFrameUpdate     (const nsIntRect * aRect);
   150   void OnStopFrame       ();
   151   void OnStopDecode      ();
   152   void OnDiscard         ();
   153   void OnUnlockedDraw    ();
   154   void OnImageIsAnimated ();
   156   /* non-virtual sort-of-nsIRequestObserver methods */
   157   void OnStartRequest();
   158   void OnStopRequest(bool aLastPart);
   160   /* non-virtual imgIOnloadBlocker methods */
   161   void BlockOnload();
   162   void UnblockOnload();
   164   /* Finish up canceling ourselves */
   165   void DoCancel(nsresult status);
   167   /* Do the proper refcount management to null out mListener */
   168   void NullOutListener();
   170   void DoRemoveFromLoadGroup() {
   171     RemoveFromLoadGroup(true);
   172   }
   174   // Return the imgStatusTracker associated with mOwner and/or mImage. It may
   175   // live either on mOwner or mImage, depending on whether
   176   //   (a) we have an mOwner at all
   177   //   (b) whether mOwner has instantiated its image yet
   178   already_AddRefed<imgStatusTracker> GetStatusTracker() const;
   180   nsITimedChannel* TimedChannel()
   181   {
   182     if (!GetOwner())
   183       return nullptr;
   184     return GetOwner()->mTimedChannel;
   185   }
   187   already_AddRefed<mozilla::image::Image> GetImage() const;
   188   bool HasImage() const;
   189   imgRequest* GetOwner() const;
   191   nsresult PerformClone(imgINotificationObserver* aObserver,
   192                         imgRequestProxy* (aAllocFn)(imgRequestProxy*),
   193                         imgRequestProxy** aClone);
   195 public:
   196   NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())
   198 protected:
   199   nsAutoPtr<ProxyBehaviour> mBehaviour;
   201 private:
   202   friend class imgCacheValidator;
   203   friend imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis);
   205   // The URI of our request.
   206   nsRefPtr<ImageURL> mURI;
   208   // mListener is only promised to be a weak ref (see imgILoader.idl),
   209   // but we actually keep a strong ref to it until we've seen our
   210   // first OnStopRequest.
   211   imgINotificationObserver* mListener;
   212   nsCOMPtr<nsILoadGroup> mLoadGroup;
   214   nsLoadFlags mLoadFlags;
   215   uint32_t    mLockCount;
   216   uint32_t    mAnimationConsumers;
   217   bool mCanceled;
   218   bool mIsInLoadGroup;
   219   bool mListenerIsStrongRef;
   220   bool mDecodeRequested;
   222   // Whether we want to defer our notifications by the non-virtual Observer
   223   // interfaces as image loads proceed.
   224   bool mDeferNotifications;
   226   // We only want to send OnStartContainer once for each proxy, but we might
   227   // get multiple OnStartContainer calls.
   228   bool mSentStartContainer;
   229 };
   231 // Used for static image proxies for which no requests are available, so
   232 // certain behaviours must be overridden to compensate.
   233 class imgRequestProxyStatic : public imgRequestProxy
   234 {
   236 public:
   237   imgRequestProxyStatic(mozilla::image::Image* aImage,
   238                         nsIPrincipal* aPrincipal);
   240   NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) MOZ_OVERRIDE;
   242   using imgRequestProxy::Clone;
   244   virtual nsresult Clone(imgINotificationObserver* aObserver,
   245                          imgRequestProxy** aClone) MOZ_OVERRIDE;
   247 protected:
   248   friend imgRequestProxy* NewStaticProxy(imgRequestProxy*);
   250   // Our principal. We have to cache it, rather than accessing the underlying
   251   // request on-demand, because static proxies don't have an underlying request.
   252   nsCOMPtr<nsIPrincipal> mPrincipal;
   253 };
   255 #endif // imgRequestProxy_h__

mercurial