DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (d38398e5144e)

VCS Links

imgCancelRunnable

imgRequestProxy

imgRequestProxyStatic

Macros

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_image_imgRequestProxy_h
#define mozilla_image_imgRequestProxy_h

#include "imgIRequest.h"
#include "nsISecurityInfoProvider.h"

#include "nsILoadGroup.h"
#include "nsISupportsPriority.h"
#include "nsITimedChannel.h"
#include "nsCOMPtr.h"
#include "nsThreadUtils.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/gfx/Rect.h"

#include "imgRequest.h"
#include "IProgressObserver.h"

#define NS_IMGREQUESTPROXY_CID \
{ /* 20557898-1dd2-11b2-8f65-9c462ee2bc95 */         \
     0x20557898,                                     \
     0x1dd2,                                         \
     0x11b2,                                         \
    {0x8f, 0x65, 0x9c, 0x46, 0x2e, 0xe2, 0xbc, 0x95} \
}

class imgINotificationObserver;
class imgStatusNotifyRunnable;
class ProxyBehaviour;

namespace mozilla {
namespace image {
class Image;
class ImageURL;
class ProgressTracker;
} // namespace image
} // namespace mozilla

class imgRequestProxy : public imgIRequest,
                        public mozilla::image::IProgressObserver,
                        public nsISupportsPriority,
                        public nsISecurityInfoProvider,
                        public nsITimedChannel
{
protected:
  virtual ~imgRequestProxy();

public:
  typedef mozilla::image::Image Image;
  typedef mozilla::image::ImageURL ImageURL;
  typedef mozilla::image::ProgressTracker ProgressTracker;

  MOZ_DECLARE_REFCOUNTED_TYPENAME(imgRequestProxy)
  NS_DECL_ISUPPORTS
  NS_DECL_IMGIREQUEST
  NS_DECL_NSIREQUEST
  NS_DECL_NSISUPPORTSPRIORITY
  NS_DECL_NSISECURITYINFOPROVIDER
  // nsITimedChannel declared below

  imgRequestProxy();

  // Callers to Init or ChangeOwner are required to call NotifyListener after
  // (although not immediately after) doing so.
  nsresult Init(imgRequest* aOwner,
                nsILoadGroup* aLoadGroup,
                ImageURL* aURI,
                imgINotificationObserver* aObserver);

  nsresult ChangeOwner(imgRequest* aNewOwner); // this will change mOwner.
                                               // Do not call this if the
                                               // previous owner has already
                                               // sent notifications out!

  void AddToLoadGroup();
  void RemoveFromLoadGroup(bool releaseLoadGroup);

  inline bool HasObserver() const {
    return mListener != nullptr;
  }

  // Asynchronously notify this proxy's listener of the current state of the
  // image, and, if we have an imgRequest mOwner, any status changes that
  // happen between the time this function is called and the time the
  // notification is scheduled.
  void NotifyListener();

  // Synchronously notify this proxy's listener of the current state of the
  // image. Only use this function if you are currently servicing an
  // asynchronously-called function.
  void SyncNotifyListener();

  // imgINotificationObserver methods:
  virtual void Notify(int32_t aType,
                      const mozilla::gfx::IntRect* aRect = nullptr) override;
  virtual void OnLoadComplete(bool aLastPart) override;

  // imgIOnloadBlocker methods:
  virtual void BlockOnload() override;
  virtual void UnblockOnload() override;

  // Other, internal-only methods:
  virtual void SetHasImage() override;

  // Whether we want notifications from ProgressTracker to be deferred until
  // an event it has scheduled has been fired.
  virtual bool NotificationsDeferred() const override
  {
    return mDeferNotifications;
  }
  virtual void SetNotificationsDeferred(bool aDeferNotifications) override
  {
    mDeferNotifications = aDeferNotifications;
  }

  // Removes all animation consumers that were created with
  // IncrementAnimationConsumers. This is necessary since we need
  // to do it before the proxy itself is destroyed. See
  // imgRequest::RemoveProxy
  void ClearAnimationConsumers();

  virtual nsresult Clone(imgINotificationObserver* aObserver,
                         imgRequestProxy** aClone);
  nsresult GetStaticRequest(imgRequestProxy** aReturn);

  nsresult GetURI(ImageURL** aURI);

protected:
  friend class mozilla::image::ProgressTracker;
  friend class imgStatusNotifyRunnable;

  class imgCancelRunnable;
  friend class imgCancelRunnable;

  class imgCancelRunnable : public mozilla::Runnable
  {
    public:
      imgCancelRunnable(imgRequestProxy* owner, nsresult status)
        : Runnable("imgCancelRunnable"), mOwner(owner), mStatus(status)
      { }

      NS_IMETHOD Run() override {
        mOwner->DoCancel(mStatus);
        return NS_OK;
      }

    private:
      RefPtr<imgRequestProxy> mOwner;
      nsresult mStatus;
  };

  /* Finish up canceling ourselves */
  void DoCancel(nsresult status);

  /* Do the proper refcount management to null out mListener */
  void NullOutListener();

  void DoRemoveFromLoadGroup() {
    RemoveFromLoadGroup(true);
  }

  // Return the ProgressTracker associated with mOwner and/or mImage. It may
  // live either on mOwner or mImage, depending on whether
  //   (a) we have an mOwner at all
  //   (b) whether mOwner has instantiated its image yet
  already_AddRefed<ProgressTracker> GetProgressTracker() const;

  nsITimedChannel* TimedChannel()
  {
    if (!GetOwner()) {
      return nullptr;
    }
    return GetOwner()->GetTimedChannel();
  }

  already_AddRefed<Image> GetImage() const;
  bool HasImage() const;
  imgRequest* GetOwner() const;

  nsresult PerformClone(imgINotificationObserver* aObserver,
                        imgRequestProxy* (aAllocFn)(imgRequestProxy*),
                        imgRequestProxy** aClone);

public:
  NS_FORWARD_SAFE_NSITIMEDCHANNEL(TimedChannel())

protected:
  mozilla::UniquePtr<ProxyBehaviour> mBehaviour;

private:
  friend class imgCacheValidator;
  friend imgRequestProxy* NewStaticProxy(imgRequestProxy* aThis);

  // The URI of our request.
  RefPtr<ImageURL> mURI;

  // mListener is only promised to be a weak ref (see imgILoader.idl),
  // but we actually keep a strong ref to it until we've seen our
  // first OnStopRequest.
  imgINotificationObserver* MOZ_UNSAFE_REF("Observers must call Cancel() or "
                                           "CancelAndForgetObserver() before "
                                           "they are destroyed") mListener;

  nsCOMPtr<nsILoadGroup> mLoadGroup;

  nsLoadFlags mLoadFlags;
  uint32_t    mLockCount;
  uint32_t    mAnimationConsumers;
  bool mCanceled;
  bool mIsInLoadGroup;
  bool mListenerIsStrongRef;
  bool mDecodeRequested;

  // Whether we want to defer our notifications by the non-virtual Observer
  // interfaces as image loads proceed.
  bool mDeferNotifications;
};

// Used for static image proxies for which no requests are available, so
// certain behaviours must be overridden to compensate.
class imgRequestProxyStatic : public imgRequestProxy
{

public:
  imgRequestProxyStatic(Image* aImage, nsIPrincipal* aPrincipal);

  NS_IMETHOD GetImagePrincipal(nsIPrincipal** aPrincipal) override;

  using imgRequestProxy::Clone;

  virtual nsresult Clone(imgINotificationObserver* aObserver,
                         imgRequestProxy** aClone) override;

protected:
  friend imgRequestProxy* NewStaticProxy(imgRequestProxy*);

  // Our principal. We have to cache it, rather than accessing the underlying
  // request on-demand, because static proxies don't have an underlying request.
  nsCOMPtr<nsIPrincipal> mPrincipal;
};

#endif // mozilla_image_imgRequestProxy_h