Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/mozilla/css/ImageLoader.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
// A class that handles style system image loads (other image loads are handled
8
// by the nodes in the content tree).
9
10
#ifndef mozilla_css_ImageLoader_h___
11
#define mozilla_css_ImageLoader_h___
12
13
#include "mozilla/CORSMode.h"
14
#include "nsClassHashtable.h"
15
#include "nsHashKeys.h"
16
#include "nsIFrame.h"
17
#include "nsIReflowCallback.h"
18
#include "nsTArray.h"
19
#include "imgIRequest.h"
20
#include "imgINotificationObserver.h"
21
#include "mozilla/Attributes.h"
22
#include "mozilla/net/ReferrerPolicy.h"
23
24
class imgIContainer;
25
class nsIFrame;
26
class nsIDocument;
27
class nsPresContext;
28
class nsIURI;
29
class nsIPrincipal;
30
31
namespace mozilla {
32
namespace css {
33
34
struct ImageValue;
35
36
class ImageLoader final : public imgINotificationObserver
37
{
38
public:
39
  // We also associate flags alongside frames in the request-to-frames hashmap.
40
  // These are used for special handling of events for requests.
41
  typedef uint32_t FrameFlags;
42
  enum {
43
    REQUEST_REQUIRES_REFLOW      = 1u << 0,
44
    REQUEST_HAS_BLOCKED_ONLOAD   = 1u << 1,
45
  };
46
47
  typedef mozilla::css::ImageValue Image;
48
49
  explicit ImageLoader(nsIDocument* aDocument)
50
  : mDocument(aDocument),
51
    mInClone(false)
52
0
  {
53
0
    MOZ_ASSERT(mDocument);
54
0
  }
55
56
  NS_DECL_ISUPPORTS
57
  NS_DECL_IMGINOTIFICATIONOBSERVER
58
59
  void DropDocumentReference();
60
61
  void MaybeRegisterCSSImage(Image* aImage);
62
  void DeregisterCSSImage(Image* aImage);
63
64
  void AssociateRequestToFrame(imgIRequest* aRequest,
65
                               nsIFrame* aFrame,
66
                               FrameFlags aFlags);
67
68
  void DisassociateRequestFromFrame(imgIRequest* aRequest,
69
                                    nsIFrame* aFrame);
70
71
  void DropRequestsForFrame(nsIFrame* aFrame);
72
73
  void SetAnimationMode(uint16_t aMode);
74
75
  // The prescontext for this ImageLoader's document. We need it to be passed
76
  // in because this can be called during presentation destruction after the
77
  // presshell pointer on the document has been cleared.
78
  void ClearFrames(nsPresContext* aPresContext);
79
80
  void LoadImage(nsIURI* aURI, nsIPrincipal* aPrincipal, nsIURI* aReferrer,
81
                 mozilla::net::ReferrerPolicy aPolicy, Image* aCSSValue,
82
                 CORSMode aCorsMode);
83
84
  void DestroyRequest(imgIRequest* aRequest);
85
86
  void FlushUseCounters();
87
88
private:
89
  // This callback is used to unblock document onload after a reflow
90
  // triggered from an image load.
91
  struct ImageReflowCallback final : public nsIReflowCallback
92
  {
93
    RefPtr<ImageLoader> mLoader;
94
    WeakFrame mFrame;
95
    nsCOMPtr<imgIRequest> const mRequest;
96
97
    ImageReflowCallback(ImageLoader* aLoader,
98
                        nsIFrame* aFrame,
99
                        imgIRequest* aRequest)
100
    : mLoader(aLoader)
101
    , mFrame(aFrame)
102
    , mRequest(aRequest)
103
0
    {}
104
105
    bool ReflowFinished() override;
106
    void ReflowCallbackCanceled() override;
107
  };
108
109
0
  ~ImageLoader() {}
110
111
  // We need to be able to look up the frames associated with a request (for
112
  // delivering notifications) and the requests associated with a frame (when
113
  // the frame goes away). Thus we maintain hashtables going both ways.  These
114
  // should always be in sync.
115
116
  struct FrameWithFlags {
117
    explicit FrameWithFlags(nsIFrame* aFrame)
118
    : mFrame(aFrame),
119
      mFlags(0)
120
0
    {
121
0
      MOZ_ASSERT(mFrame);
122
0
    }
123
    nsIFrame* const mFrame;
124
    FrameFlags mFlags;
125
  };
126
127
  // A helper class to compare FrameWithFlags by comparing mFrame and
128
  // ignoring mFlags.
129
  class FrameOnlyComparator {
130
    public:
131
      bool Equals(const FrameWithFlags& aElem1,
132
                  const FrameWithFlags& aElem2) const
133
0
      { return aElem1.mFrame == aElem2.mFrame; }
134
135
      bool LessThan(const FrameWithFlags& aElem1,
136
                    const FrameWithFlags& aElem2) const
137
0
      { return aElem1.mFrame < aElem2.mFrame; }
138
  };
139
140
  typedef nsTArray<FrameWithFlags> FrameSet;
141
  typedef nsTArray<nsCOMPtr<imgIRequest> > RequestSet;
142
  typedef nsTHashtable<nsPtrHashKey<Image> > ImageHashSet;
143
  typedef nsClassHashtable<nsISupportsHashKey,
144
                           FrameSet> RequestToFrameMap;
145
  typedef nsClassHashtable<nsPtrHashKey<nsIFrame>,
146
                           RequestSet> FrameToRequestMap;
147
148
  void AddImage(Image* aCSSImage);
149
  void RemoveImage(Image* aCSSImage);
150
151
  nsPresContext* GetPresContext();
152
153
  void DoRedraw(FrameSet* aFrameSet, bool aForcePaint);
154
  void UnblockOnloadIfNeeded(nsIFrame* aFrame, imgIRequest* aRequest);
155
  void RequestReflowIfNeeded(FrameSet* aFrameSet, imgIRequest* aRequest);
156
  void RequestReflowOnFrame(FrameWithFlags* aFwf, imgIRequest* aRequest);
157
158
  nsresult OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage);
159
  nsresult OnFrameComplete(imgIRequest* aRequest);
160
  nsresult OnImageIsAnimated(imgIRequest* aRequest);
161
  nsresult OnFrameUpdate(imgIRequest* aRequest);
162
  nsresult OnLoadComplete(imgIRequest* aRequest);
163
164
  // Helpers for DropRequestsForFrame / DisassociateRequestFromFrame above.
165
  void RemoveRequestToFrameMapping(imgIRequest* aRequest, nsIFrame* aFrame);
166
  void RemoveFrameToRequestMapping(imgIRequest* aRequest, nsIFrame* aFrame);
167
168
  // A map of imgIRequests to the nsIFrames that are using them.
169
  RequestToFrameMap mRequestToFrameMap;
170
171
  // A map of nsIFrames to the imgIRequests they use.
172
  FrameToRequestMap mFrameToRequestMap;
173
174
  // A weak pointer to our document. Nulled out by DropDocumentReference.
175
  nsIDocument* mDocument;
176
177
  // The set of all nsCSSValue::Images (whether they're associated a frame or
178
  // not).  We'll need this when we go away to remove any requests associated
179
  // with our document from those Images.
180
  ImageHashSet mImages;
181
182
  // Are we cloning?  If so, ignore any notifications we get.
183
  bool mInClone;
184
};
185
186
} // namespace css
187
} // namespace mozilla
188
189
#endif /* mozilla_css_ImageLoader_h___ */