|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #ifndef nsFaviconService_h_ |
|
7 #define nsFaviconService_h_ |
|
8 |
|
9 #include "nsIFaviconService.h" |
|
10 #include "mozIAsyncFavicons.h" |
|
11 |
|
12 #include "nsCOMPtr.h" |
|
13 #include "nsString.h" |
|
14 #include "nsDataHashtable.h" |
|
15 #include "nsServiceManagerUtils.h" |
|
16 #include "nsTHashtable.h" |
|
17 #include "nsToolkitCompsCID.h" |
|
18 #include "nsURIHashKey.h" |
|
19 #include "nsITimer.h" |
|
20 #include "Database.h" |
|
21 #include "mozilla/storage.h" |
|
22 #include "mozilla/Attributes.h" |
|
23 |
|
24 #include "AsyncFaviconHelpers.h" |
|
25 |
|
26 // Favicons bigger than this size should not be saved to the db to avoid |
|
27 // bloating it with large image blobs. |
|
28 // This still allows us to accept a favicon even if we cannot optimize it. |
|
29 #define MAX_FAVICON_SIZE 10240 |
|
30 |
|
31 // Most icons will be smaller than this rough estimate of the size of an |
|
32 // uncompressed 16x16 RGBA image of the same dimensions. |
|
33 #define MAX_ICON_FILESIZE(s) ((uint32_t) s*s*4) |
|
34 |
|
35 // forward class definitions |
|
36 class mozIStorageStatementCallback; |
|
37 |
|
38 class UnassociatedIconHashKey : public nsURIHashKey |
|
39 { |
|
40 public: |
|
41 UnassociatedIconHashKey(const nsIURI* aURI) |
|
42 : nsURIHashKey(aURI) |
|
43 { |
|
44 } |
|
45 UnassociatedIconHashKey(const UnassociatedIconHashKey& aOther) |
|
46 : nsURIHashKey(aOther) |
|
47 { |
|
48 NS_NOTREACHED("Do not call me!"); |
|
49 } |
|
50 mozilla::places::IconData iconData; |
|
51 PRTime created; |
|
52 }; |
|
53 |
|
54 class nsFaviconService MOZ_FINAL : public nsIFaviconService |
|
55 , public mozIAsyncFavicons |
|
56 , public nsITimerCallback |
|
57 { |
|
58 public: |
|
59 nsFaviconService(); |
|
60 |
|
61 /** |
|
62 * Obtains the service's object. |
|
63 */ |
|
64 static already_AddRefed<nsFaviconService> GetSingleton(); |
|
65 |
|
66 /** |
|
67 * Initializes the service's object. This should only be called once. |
|
68 */ |
|
69 nsresult Init(); |
|
70 |
|
71 /** |
|
72 * Returns a cached pointer to the favicon service for consumers in the |
|
73 * places directory. |
|
74 */ |
|
75 static nsFaviconService* GetFaviconService() |
|
76 { |
|
77 if (!gFaviconService) { |
|
78 nsCOMPtr<nsIFaviconService> serv = |
|
79 do_GetService(NS_FAVICONSERVICE_CONTRACTID); |
|
80 NS_ENSURE_TRUE(serv, nullptr); |
|
81 NS_ASSERTION(gFaviconService, "Should have static instance pointer now"); |
|
82 } |
|
83 return gFaviconService; |
|
84 } |
|
85 |
|
86 // addition to API for strings to prevent excessive parsing of URIs |
|
87 nsresult GetFaviconLinkForIconString(const nsCString& aIcon, nsIURI** aOutput); |
|
88 void GetFaviconSpecForIconString(const nsCString& aIcon, nsACString& aOutput); |
|
89 |
|
90 nsresult OptimizeFaviconImage(const uint8_t* aData, uint32_t aDataLen, |
|
91 const nsACString& aMimeType, |
|
92 nsACString& aNewData, nsACString& aNewMimeType); |
|
93 int32_t GetOptimizedIconDimension() { return mOptimizedIconDimension; } |
|
94 |
|
95 /** |
|
96 * Obtains the favicon data asynchronously. |
|
97 * |
|
98 * @param aFaviconURI |
|
99 * The URI representing the favicon we are looking for. |
|
100 * @param aCallback |
|
101 * The callback where results or errors will be dispatch to. In the |
|
102 * returned result, the favicon binary data will be at index 0, and the |
|
103 * mime type will be at index 1. |
|
104 */ |
|
105 nsresult GetFaviconDataAsync(nsIURI* aFaviconURI, |
|
106 mozIStorageStatementCallback* aCallback); |
|
107 |
|
108 /** |
|
109 * Call to send out favicon changed notifications. Should only be called |
|
110 * when there is data loaded for the favicon. |
|
111 * @param aPageURI |
|
112 * The URI of the page to notify about. |
|
113 * @param aFaviconURI |
|
114 * The moz-anno:favicon URI of the icon. |
|
115 * @param aGUID |
|
116 * The unique ID associated with the page. |
|
117 */ |
|
118 void SendFaviconNotifications(nsIURI* aPageURI, nsIURI* aFaviconURI, |
|
119 const nsACString& aGUID); |
|
120 |
|
121 NS_DECL_ISUPPORTS |
|
122 NS_DECL_NSIFAVICONSERVICE |
|
123 NS_DECL_MOZIASYNCFAVICONS |
|
124 NS_DECL_NSITIMERCALLBACK |
|
125 |
|
126 private: |
|
127 ~nsFaviconService(); |
|
128 |
|
129 nsRefPtr<mozilla::places::Database> mDB; |
|
130 |
|
131 nsCOMPtr<nsITimer> mExpireUnassociatedIconsTimer; |
|
132 |
|
133 static nsFaviconService* gFaviconService; |
|
134 |
|
135 /** |
|
136 * A cached URI for the default icon. We return this a lot, and don't want to |
|
137 * re-parse and normalize our unchanging string many times. Important: do |
|
138 * not return this directly; use Clone() since callers may change the object |
|
139 * they get back. May be null, in which case it needs initialization. |
|
140 */ |
|
141 nsCOMPtr<nsIURI> mDefaultIcon; |
|
142 |
|
143 // The target dimension, in pixels, for favicons we optimize. |
|
144 // If we find images that are as large or larger than an uncompressed RGBA |
|
145 // image of this size (mOptimizedIconDimension*mOptimizedIconDimension*4), |
|
146 // we will try to optimize it. |
|
147 int32_t mOptimizedIconDimension; |
|
148 |
|
149 uint32_t mFailedFaviconSerial; |
|
150 nsDataHashtable<nsCStringHashKey, uint32_t> mFailedFavicons; |
|
151 |
|
152 // AsyncFetchAndSetIconForPage needs access to the icon cache |
|
153 friend class mozilla::places::AsyncFetchAndSetIconForPage; |
|
154 friend class mozilla::places::RemoveIconDataCacheEntry; |
|
155 nsTHashtable<UnassociatedIconHashKey> mUnassociatedIcons; |
|
156 }; |
|
157 |
|
158 #define FAVICON_ANNOTATION_NAME "favicon" |
|
159 |
|
160 #endif // nsFaviconService_h_ |