1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 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/. */ 6 7 #pragma once 8 9 #include "nsIFaviconService.h" 10 #include "nsIChannelEventSink.h" 11 #include "nsIInterfaceRequestor.h" 12 #include "nsIStreamListener.h" 13 #include "mozIPlacesPendingOperation.h" 14 #include "nsThreadUtils.h" 15 #include "nsProxyRelease.h" 16 #include "imgLoader.h" 17 18 class nsIPrincipal; 19 20 #include "Database.h" 21 #include "mozilla/storage.h" 22 23 #define ICON_STATUS_UNKNOWN 0 24 #define ICON_STATUS_CHANGED 1 << 0 25 #define ICON_STATUS_SAVED 1 << 1 26 #define ICON_STATUS_ASSOCIATED 1 << 2 27 #define ICON_STATUS_CACHED 1 << 3 28 29 #define TO_CHARBUFFER(_buffer) \ 30 reinterpret_cast<char*>(const_cast<uint8_t*>(_buffer)) 31 #define TO_INTBUFFER(_string) \ 32 reinterpret_cast<uint8_t*>(const_cast<char*>(_string.get())) 33 34 #define PNG_MIME_TYPE "image/png" 35 #define SVG_MIME_TYPE "image/svg+xml" 36 37 // Always ensure a minimum expiration time, so icons are not already expired 38 // on addition. 39 #define MIN_FAVICON_EXPIRATION ((PRTime)1 * 24 * 60 * 60 * PR_USEC_PER_SEC) 40 // The maximum time we will keep a favicon around. We always ask the cache 41 // first and default to this value if we can't get a time, or the time we get 42 // is far in the future. 43 #define MAX_FAVICON_EXPIRATION ((PRTime)7 * 24 * 60 * 60 * PR_USEC_PER_SEC) 44 45 namespace mozilla { 46 namespace places { 47 48 /** 49 * Indicates when a icon should be fetched from network. 50 */ 51 enum AsyncFaviconFetchMode { FETCH_NEVER = 0, FETCH_IF_MISSING, FETCH_ALWAYS }; 52 53 /** 54 * Represents one of the payloads (frames) of an icon entry. 55 */ 56 struct IconPayload { IconPayloadIconPayload57 IconPayload() : id(0), width(0) { 58 data.SetIsVoid(true); 59 mimeType.SetIsVoid(true); 60 } 61 62 int64_t id; 63 uint16_t width; 64 nsCString data; 65 nsCString mimeType; 66 }; 67 68 /** 69 * Represents an icon entry. 70 */ 71 struct IconData { IconDataIconData72 IconData() 73 : expiration(0), 74 fetchMode(FETCH_NEVER), 75 status(ICON_STATUS_UNKNOWN), 76 rootIcon(0) {} 77 78 nsCString spec; 79 nsCString host; 80 PRTime expiration; 81 enum AsyncFaviconFetchMode fetchMode; 82 uint16_t status; // This is a bitset, see ICON_STATUS_* defines above. 83 uint8_t rootIcon; 84 CopyableTArray<IconPayload> payloads; 85 }; 86 87 /** 88 * Data cache for a page entry. 89 */ 90 struct PageData { PageDataPageData91 PageData() : id(0), placeId(0), canAddToHistory(true) { 92 guid.SetIsVoid(true); 93 } 94 95 int64_t id; // This is the moz_pages_w_icons id. 96 int64_t placeId; // This is the moz_places page id. 97 nsCString spec; 98 nsCString host; 99 nsCString bookmarkedSpec; 100 bool canAddToHistory; // False for disabled history and unsupported schemas. 101 nsCString guid; 102 }; 103 104 /** 105 * Info for a frame. 106 */ 107 struct FrameData { FrameDataFrameData108 FrameData(uint16_t aIndex, uint16_t aWidth) : index(aIndex), width(aWidth) {} 109 110 uint16_t index; 111 uint16_t width; 112 }; 113 114 /** 115 * Async fetches icon from database or network, associates it with the required 116 * page and finally notifies the change. 117 */ 118 class AsyncFetchAndSetIconForPage final : public Runnable, 119 public nsIStreamListener, 120 public nsIInterfaceRequestor, 121 public nsIChannelEventSink, 122 public mozIPlacesPendingOperation { 123 public: 124 NS_DECL_NSIRUNNABLE 125 NS_DECL_NSISTREAMLISTENER 126 NS_DECL_NSIINTERFACEREQUESTOR 127 NS_DECL_NSICHANNELEVENTSINK 128 NS_DECL_NSIREQUESTOBSERVER 129 NS_DECL_MOZIPLACESPENDINGOPERATION 130 NS_DECL_ISUPPORTS_INHERITED 131 132 /** 133 * Constructor. 134 * 135 * @param aIcon 136 * Icon to be fetched and associated. 137 * @param aPage 138 * Page to which associate the icon. 139 * @param aFaviconLoadPrivate 140 * Whether this favicon load is in private browsing. 141 * @param aCallback 142 * Function to be called when the fetch-and-associate process finishes. 143 * @param aLoadingPrincipal 144 * LoadingPrincipal of the icon to be fetched. 145 */ 146 AsyncFetchAndSetIconForPage(IconData& aIcon, PageData& aPage, 147 bool aFaviconLoadPrivate, 148 nsIFaviconDataCallback* aCallback, 149 nsIPrincipal* aLoadingPrincipal, 150 uint64_t aRequestContextID); 151 152 private: 153 nsresult FetchFromNetwork(); 154 virtual ~AsyncFetchAndSetIconForPage() = default; 155 156 nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback; 157 IconData mIcon; 158 PageData mPage; 159 const bool mFaviconLoadPrivate; 160 nsMainThreadPtrHandle<nsIPrincipal> mLoadingPrincipal; 161 bool mCanceled; 162 nsCOMPtr<nsIRequest> mRequest; 163 uint64_t mRequestContextID; 164 }; 165 166 /** 167 * Associates the icon to the required page, finally dispatches an event to the 168 * main thread to notify the change to observers. 169 */ 170 class AsyncAssociateIconToPage final : public Runnable { 171 public: 172 NS_DECL_NSIRUNNABLE 173 174 /** 175 * Constructor. 176 * 177 * @param aIcon 178 * Icon to be associated. 179 * @param aPage 180 * Page to which associate the icon. 181 * @param aCallback 182 * Function to be called when the associate process finishes. 183 */ 184 AsyncAssociateIconToPage( 185 const IconData& aIcon, const PageData& aPage, 186 const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback); 187 188 private: 189 nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback; 190 IconData mIcon; 191 PageData mPage; 192 }; 193 194 /** 195 * Asynchronously tries to get the URL of a page's favicon, then notifies the 196 * given observer. 197 */ 198 class AsyncGetFaviconURLForPage final : public Runnable { 199 public: 200 NS_DECL_NSIRUNNABLE 201 202 /** 203 * Constructor. 204 * 205 * @param aPageSpec 206 * URL of the page whose favicon's URL we're fetching 207 * @param aPageHost 208 * Host of the page whose favicon's URL we're fetching 209 * @param aCallback 210 * function to be called once finished 211 * @param aPreferredWidth 212 * The preferred size for the icon 213 */ 214 AsyncGetFaviconURLForPage(const nsACString& aPageSpec, 215 const nsACString& aPageHost, 216 uint16_t aPreferredWidth, 217 nsIFaviconDataCallback* aCallback); 218 219 private: 220 uint16_t mPreferredWidth; 221 nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback; 222 nsCString mPageSpec; 223 nsCString mPageHost; 224 }; 225 226 /** 227 * Asynchronously tries to get the URL and data of a page's favicon, then 228 * notifies the given observer. 229 */ 230 class AsyncGetFaviconDataForPage final : public Runnable { 231 public: 232 NS_DECL_NSIRUNNABLE 233 234 /** 235 * Constructor. 236 * 237 * @param aPageSpec 238 * URL of the page whose favicon URL and data we're fetching 239 * @param aPageHost 240 * Host of the page whose favicon's URL we're fetching 241 * @param aPreferredWidth 242 * The preferred size of the icon. We will try to return an icon close 243 * to this size. 244 * @param aCallback 245 * function to be called once finished 246 */ 247 AsyncGetFaviconDataForPage(const nsACString& aPageSpec, 248 const nsACString& aPageHost, 249 uint16_t aPreferredWidth, 250 nsIFaviconDataCallback* aCallback); 251 252 private: 253 uint16_t mPreferredWidth; 254 nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback; 255 nsCString mPageSpec; 256 nsCString mPageHost; 257 }; 258 259 class AsyncReplaceFaviconData final : public Runnable { 260 public: 261 NS_DECL_NSIRUNNABLE 262 263 explicit AsyncReplaceFaviconData(const IconData& aIcon); 264 265 private: 266 nsresult RemoveIconDataCacheEntry(); 267 268 IconData mIcon; 269 }; 270 271 /** 272 * Notifies the icon change to favicon observers. 273 */ 274 class NotifyIconObservers final : public Runnable { 275 public: 276 NS_DECL_NSIRUNNABLE 277 278 /** 279 * Constructor. 280 * 281 * @param aIcon 282 * Icon information. Can be empty if no icon is associated to the page. 283 * @param aPage 284 * Page to which the icon information applies. 285 * @param aCallback 286 * Function to be notified in all cases. 287 */ 288 NotifyIconObservers( 289 const IconData& aIcon, const PageData& aPage, 290 const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback); 291 292 private: 293 nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback; 294 IconData mIcon; 295 PageData mPage; 296 }; 297 298 /** 299 * Copies Favicons from one page to another one. 300 */ 301 class AsyncCopyFavicons final : public Runnable { 302 public: 303 NS_DECL_NSIRUNNABLE 304 305 /** 306 * Constructor. 307 * 308 * @param aFromPage 309 * The originating page. 310 * @param aToPage 311 * The destination page. 312 * @param aFaviconLoadPrivate 313 * Whether this favicon load is in private browsing. 314 * @param aCallback 315 * An optional callback to invoke when done. 316 */ 317 AsyncCopyFavicons(PageData& aFromPage, PageData& aToPage, 318 nsIFaviconDataCallback* aCallback); 319 320 private: 321 PageData mFromPage; 322 PageData mToPage; 323 nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback; 324 }; 325 326 } // namespace places 327 } // namespace mozilla 328