File: FaviconHelpers.h

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (298 lines) | stat: -rw-r--r-- 7,824 bytes parent folder | download | duplicates (2)
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
 * 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/. */

#pragma once

#include "nsIFaviconService.h"
#include "nsIChannelEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIStreamListener.h"
#include "mozIPlacesPendingOperation.h"
#include "nsThreadUtils.h"
#include "nsProxyRelease.h"
#include "imgLoader.h"
#include "ConcurrentConnection.h"

class nsIPrincipal;

#include "Database.h"
#include "mozilla/storage.h"
#include "mozilla/ipc/IPCCore.h"

#define ICON_STATUS_UNKNOWN 0
#define ICON_STATUS_CHANGED 1 << 0
#define ICON_STATUS_SAVED 1 << 1
#define ICON_STATUS_ASSOCIATED 1 << 2
#define ICON_STATUS_CACHED 1 << 3

#define TO_CHARBUFFER(_buffer) \
  reinterpret_cast<char*>(const_cast<uint8_t*>(_buffer))
#define TO_INTBUFFER(_string) \
  reinterpret_cast<uint8_t*>(const_cast<char*>(_string.get()))

#define PNG_MIME_TYPE "image/png"
#define SVG_MIME_TYPE "image/svg+xml"

// Always ensure a minimum expiration time, so icons are not already expired
// on addition.
#define MIN_FAVICON_EXPIRATION ((PRTime)1 * 24 * 60 * 60 * PR_USEC_PER_SEC)
// The maximum time we will keep a favicon around.  We always ask the cache
// first and default to this value if we can't get a time, or the time we get
// is far in the future.
#define MAX_FAVICON_EXPIRATION ((PRTime)7 * 24 * 60 * 60 * PR_USEC_PER_SEC)

namespace mozilla {
namespace places {

/**
 * Represents one of the payloads (frames) of an icon entry.
 */
struct IconPayload {
  IconPayload() : id(0), width(0) {
    data.SetIsVoid(true);
    mimeType.SetIsVoid(true);
  }

  int64_t id;
  uint16_t width;
  nsCString data;
  nsCString mimeType;
};

/**
 * Represents an icon entry.
 */
struct IconData {
  IconData()
      : expiration(0), status(ICON_STATUS_UNKNOWN), rootIcon(0), flags(0) {}

  nsCString spec;
  nsCString host;
  PRTime expiration;
  uint16_t status;  // This is a bitset, see ICON_STATUS_* defines above.
  uint8_t rootIcon;
  CopyableTArray<IconPayload> payloads;
  uint16_t flags;  // This is a bitset, see ICONDATA_FLAGS_* defines
                   // in toolkit/components/places/nsIFaviconService.idl.
};

/**
 * Data cache for a page entry.
 */
struct PageData {
  PageData() : id(0), placeId(0), canAddToHistory(true) {
    guid.SetIsVoid(true);
  }

  int64_t id;       // This is the moz_pages_w_icons id.
  int64_t placeId;  // This is the moz_places page id.
  nsCString spec;
  nsCString host;
  nsCString bookmarkedSpec;
  bool canAddToHistory;  // False for disabled history and unsupported schemas.
  nsCString guid;
};

/**
 * Info for a frame.
 */
struct FrameData {
  FrameData(uint16_t aIndex, uint16_t aWidth) : index(aIndex), width(aWidth) {}

  uint16_t index;
  uint16_t width;
};

/**
 * Associates the icon to the required page, finally dispatches an event to the
 * main thread to notify the change to observers.
 */
class AsyncAssociateIconToPage final : public Runnable {
 public:
  NS_DECL_NSIRUNNABLE

  /**
   * Constructor.
   *
   * @param aIcon
   *        Icon to be associated.
   * @param aPage
   *        Page to which associate the icon.
   */
  AsyncAssociateIconToPage(const IconData& aIcon, const PageData& aPage);

 private:
  IconData mIcon;
  PageData mPage;
};

/**
 * Set favicon for the page, finally dispatches an event to the
 * main thread to notify the change to observers.
 */
class AsyncSetIconForPage final : public Runnable {
 public:
  NS_DECL_NSIRUNNABLE

  /**
   * Constructor.
   *
   * @param aIcon
   *        Icon to be associated.
   * @param aPage
   *        Page to which associate the icon.
   * @param aPromise
   *        Promise that returns the result.
   */
  AsyncSetIconForPage(const IconData& aIcon, const PageData& aPage,
                      dom::Promise* aPromise);

 private:
  nsMainThreadPtrHandle<dom::Promise> mPromise;
  IconData mIcon;
  PageData mPage;
};

using FaviconPromise =
    mozilla::MozPromise<nsCOMPtr<nsIFavicon>, nsresult, true>;
using BoolPromise = mozilla::MozPromise<bool, nsresult, true>;

/**
 * Asynchronously tries to get the URL and data of a page's favicon, then
 * resolve given promise with the result.
 */
class AsyncGetFaviconForPageRunnable final : public Runnable {
 public:
  NS_DECL_NSIRUNNABLE

  /**
   * Constructor.
   *
   * @param aPageURI
   *        URI of the page whose favicon's URL we're fetching
   * @param aPreferredWidth
   *        The preferred size of the icon.  We will try to return an icon close
   *        to this size.
   * @param aPromise
   *        Promise that returns the result.
   */
  AsyncGetFaviconForPageRunnable(
      const nsCOMPtr<nsIURI>& aPageURI, uint16_t aPreferredWidth,
      const RefPtr<FaviconPromise::Private>& aPromise, bool aOnConcurrentConn);

 private:
  ~AsyncGetFaviconForPageRunnable();

  nsCOMPtr<nsIURI> mPageURI;
  uint16_t mPreferredWidth;
  nsMainThreadPtrHandle<FaviconPromise::Private> mPromise;
  bool mOnConcurrentConn;
};

/**
 * Notifies the icon change to favicon observers.
 */
class NotifyIconObservers final : public Runnable {
 public:
  NS_DECL_NSIRUNNABLE

  /**
   * Constructor.
   *
   * @param aIcon
   *        Icon information. Can be empty if no icon is associated to the page.
   * @param aPage
   *        Page to which the icon information applies.
   */
  NotifyIconObservers(const IconData& aIcon, const PageData& aPage);

 private:
  IconData mIcon;
  PageData mPage;
};

/**
 * Asynchronously tries to copy the favicons asociated to the URL.
 */
class AsyncTryCopyFaviconsRunnable final : public Runnable {
 public:
  NS_DECL_NSIRUNNABLE

  /**
   * Constructor.
   *
   * @param aFromPageURI
   *        The originating URI.
   * @param aToPageURI
   *        The destination URI.
   * @param aCanAddToHistoryForToPage
   *        Whether or not can add history to aToPageURI.
   * @param aPromise
   *        Promise that returns the result.
   */
  AsyncTryCopyFaviconsRunnable(const nsCOMPtr<nsIURI>& aFromPageURI,
                               const nsCOMPtr<nsIURI>& aToPageURI,
                               const bool aCanAddToHistoryForToPage,
                               const RefPtr<BoolPromise::Private>& aPromise);

 private:
  nsCOMPtr<nsIURI> mFromPageURI;
  nsCOMPtr<nsIURI> mToPageURI;
  bool mCanAddToHistoryForToPage;
  nsMainThreadPtrHandle<BoolPromise::Private> mPromise;
};

/**
 * Provides a uniform way to obtain statements from either the
 * main Places Database or a ConcurrentConnection.
 */
class ConnectionAdapter {
 public:
  /**
   * Constructor.
   *
   * @param aDB
   *  The main Database object.
   */
  explicit ConnectionAdapter(const RefPtr<Database>& aDB)
      : mDatabase(aDB), mConcurrentConnection(nullptr) {}

  /**
   * Constructor.
   *
   * @param aConn
   *  The read-only ConcurrentConnection.
   */
  explicit ConnectionAdapter(const RefPtr<ConcurrentConnection>& aConn)
      : mDatabase(nullptr), mConcurrentConnection(aConn) {}

  already_AddRefed<mozIStorageStatement> GetStatement(

      const nsCString& aQuery) const {
    MOZ_ASSERT(!NS_IsMainThread(), "Must be on helper thread");

    if (mDatabase) {
      return mDatabase->GetStatement(aQuery);
    } else if (mConcurrentConnection) {
      auto conn = mConcurrentConnection.get();
      if (conn) {
        return conn->GetStatementOnHelperThread(aQuery);
      }
    }
    return nullptr;
  }

  explicit operator bool() const {
    return mDatabase || mConcurrentConnection.get();
  }

 private:
  RefPtr<Database> mDatabase;
  RefPtr<ConcurrentConnection> mConcurrentConnection;
};

}  // namespace places
}  // namespace mozilla