michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsFaviconService_h_ michael@0: #define nsFaviconService_h_ michael@0: michael@0: #include "nsIFaviconService.h" michael@0: #include "mozIAsyncFavicons.h" michael@0: michael@0: #include "nsCOMPtr.h" michael@0: #include "nsString.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsServiceManagerUtils.h" michael@0: #include "nsTHashtable.h" michael@0: #include "nsToolkitCompsCID.h" michael@0: #include "nsURIHashKey.h" michael@0: #include "nsITimer.h" michael@0: #include "Database.h" michael@0: #include "mozilla/storage.h" michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: #include "AsyncFaviconHelpers.h" michael@0: michael@0: // Favicons bigger than this size should not be saved to the db to avoid michael@0: // bloating it with large image blobs. michael@0: // This still allows us to accept a favicon even if we cannot optimize it. michael@0: #define MAX_FAVICON_SIZE 10240 michael@0: michael@0: // Most icons will be smaller than this rough estimate of the size of an michael@0: // uncompressed 16x16 RGBA image of the same dimensions. michael@0: #define MAX_ICON_FILESIZE(s) ((uint32_t) s*s*4) michael@0: michael@0: // forward class definitions michael@0: class mozIStorageStatementCallback; michael@0: michael@0: class UnassociatedIconHashKey : public nsURIHashKey michael@0: { michael@0: public: michael@0: UnassociatedIconHashKey(const nsIURI* aURI) michael@0: : nsURIHashKey(aURI) michael@0: { michael@0: } michael@0: UnassociatedIconHashKey(const UnassociatedIconHashKey& aOther) michael@0: : nsURIHashKey(aOther) michael@0: { michael@0: NS_NOTREACHED("Do not call me!"); michael@0: } michael@0: mozilla::places::IconData iconData; michael@0: PRTime created; michael@0: }; michael@0: michael@0: class nsFaviconService MOZ_FINAL : public nsIFaviconService michael@0: , public mozIAsyncFavicons michael@0: , public nsITimerCallback michael@0: { michael@0: public: michael@0: nsFaviconService(); michael@0: michael@0: /** michael@0: * Obtains the service's object. michael@0: */ michael@0: static already_AddRefed GetSingleton(); michael@0: michael@0: /** michael@0: * Initializes the service's object. This should only be called once. michael@0: */ michael@0: nsresult Init(); michael@0: michael@0: /** michael@0: * Returns a cached pointer to the favicon service for consumers in the michael@0: * places directory. michael@0: */ michael@0: static nsFaviconService* GetFaviconService() michael@0: { michael@0: if (!gFaviconService) { michael@0: nsCOMPtr serv = michael@0: do_GetService(NS_FAVICONSERVICE_CONTRACTID); michael@0: NS_ENSURE_TRUE(serv, nullptr); michael@0: NS_ASSERTION(gFaviconService, "Should have static instance pointer now"); michael@0: } michael@0: return gFaviconService; michael@0: } michael@0: michael@0: // addition to API for strings to prevent excessive parsing of URIs michael@0: nsresult GetFaviconLinkForIconString(const nsCString& aIcon, nsIURI** aOutput); michael@0: void GetFaviconSpecForIconString(const nsCString& aIcon, nsACString& aOutput); michael@0: michael@0: nsresult OptimizeFaviconImage(const uint8_t* aData, uint32_t aDataLen, michael@0: const nsACString& aMimeType, michael@0: nsACString& aNewData, nsACString& aNewMimeType); michael@0: int32_t GetOptimizedIconDimension() { return mOptimizedIconDimension; } michael@0: michael@0: /** michael@0: * Obtains the favicon data asynchronously. michael@0: * michael@0: * @param aFaviconURI michael@0: * The URI representing the favicon we are looking for. michael@0: * @param aCallback michael@0: * The callback where results or errors will be dispatch to. In the michael@0: * returned result, the favicon binary data will be at index 0, and the michael@0: * mime type will be at index 1. michael@0: */ michael@0: nsresult GetFaviconDataAsync(nsIURI* aFaviconURI, michael@0: mozIStorageStatementCallback* aCallback); michael@0: michael@0: /** michael@0: * Call to send out favicon changed notifications. Should only be called michael@0: * when there is data loaded for the favicon. michael@0: * @param aPageURI michael@0: * The URI of the page to notify about. michael@0: * @param aFaviconURI michael@0: * The moz-anno:favicon URI of the icon. michael@0: * @param aGUID michael@0: * The unique ID associated with the page. michael@0: */ michael@0: void SendFaviconNotifications(nsIURI* aPageURI, nsIURI* aFaviconURI, michael@0: const nsACString& aGUID); michael@0: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIFAVICONSERVICE michael@0: NS_DECL_MOZIASYNCFAVICONS michael@0: NS_DECL_NSITIMERCALLBACK michael@0: michael@0: private: michael@0: ~nsFaviconService(); michael@0: michael@0: nsRefPtr mDB; michael@0: michael@0: nsCOMPtr mExpireUnassociatedIconsTimer; michael@0: michael@0: static nsFaviconService* gFaviconService; michael@0: michael@0: /** michael@0: * A cached URI for the default icon. We return this a lot, and don't want to michael@0: * re-parse and normalize our unchanging string many times. Important: do michael@0: * not return this directly; use Clone() since callers may change the object michael@0: * they get back. May be null, in which case it needs initialization. michael@0: */ michael@0: nsCOMPtr mDefaultIcon; michael@0: michael@0: // The target dimension, in pixels, for favicons we optimize. michael@0: // If we find images that are as large or larger than an uncompressed RGBA michael@0: // image of this size (mOptimizedIconDimension*mOptimizedIconDimension*4), michael@0: // we will try to optimize it. michael@0: int32_t mOptimizedIconDimension; michael@0: michael@0: uint32_t mFailedFaviconSerial; michael@0: nsDataHashtable mFailedFavicons; michael@0: michael@0: // AsyncFetchAndSetIconForPage needs access to the icon cache michael@0: friend class mozilla::places::AsyncFetchAndSetIconForPage; michael@0: friend class mozilla::places::RemoveIconDataCacheEntry; michael@0: nsTHashtable mUnassociatedIcons; michael@0: }; michael@0: michael@0: #define FAVICON_ANNOTATION_NAME "favicon" michael@0: michael@0: #endif // nsFaviconService_h_