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 "nsINamed.h" 20 #include "nsITimer.h" 21 #include "Database.h" 22 #include "imgITools.h" 23 #include "mozilla/storage.h" 24 #include "mozilla/Attributes.h" 25 26 #include "FaviconHelpers.h" 27 28 // The target dimension in pixels for favicons we store, in reverse order. 29 static uint16_t sFaviconSizes[8] = {256, 192, 144, 96, 64, 48, 32, 16}; 30 31 // forward class definitions 32 class mozIStorageStatementCallback; 33 34 class UnassociatedIconHashKey : public nsURIHashKey { 35 public: UnassociatedIconHashKey(const nsIURI * aURI)36 explicit UnassociatedIconHashKey(const nsIURI* aURI) : nsURIHashKey(aURI) {} UnassociatedIconHashKey(const UnassociatedIconHashKey & aOther)37 UnassociatedIconHashKey(const UnassociatedIconHashKey& aOther) 38 : nsURIHashKey(aOther) { 39 NS_NOTREACHED("Do not call me!"); 40 } 41 mozilla::places::IconData iconData; 42 PRTime created; 43 }; 44 45 class nsFaviconService final : public nsIFaviconService, 46 public mozIAsyncFavicons, 47 public nsITimerCallback, 48 public nsINamed { 49 public: 50 nsFaviconService(); 51 52 /** 53 * Obtains the service's object. 54 */ 55 static already_AddRefed<nsFaviconService> GetSingleton(); 56 57 /** 58 * Initializes the service's object. This should only be called once. 59 */ 60 nsresult Init(); 61 62 /** 63 * Returns a cached pointer to the favicon service for consumers in the 64 * places directory. 65 */ GetFaviconService()66 static nsFaviconService* GetFaviconService() { 67 if (!gFaviconService) { 68 nsCOMPtr<nsIFaviconService> serv = 69 do_GetService(NS_FAVICONSERVICE_CONTRACTID); 70 NS_ENSURE_TRUE(serv, nullptr); 71 NS_ASSERTION(gFaviconService, "Should have static instance pointer now"); 72 } 73 return gFaviconService; 74 } 75 76 /** 77 * Fetch and migrate favicons from an unsupported payload to a supported one. 78 */ 79 static void ConvertUnsupportedPayloads(mozIStorageConnection* aDBConn); 80 81 // addition to API for strings to prevent excessive parsing of URIs 82 nsresult GetFaviconLinkForIconString(const nsCString& aIcon, 83 nsIURI** aOutput); 84 85 nsresult OptimizeIconSizes(mozilla::places::IconData& aIcon); 86 87 /** 88 * Obtains the favicon data asynchronously. 89 * 90 * @param aFaviconSpec 91 * The spec of the URI representing the favicon we are looking for. 92 * @param aCallback 93 * The callback where results or errors will be dispatch to. In the 94 * returned result, the favicon binary data will be at index 0, and the 95 * mime type will be at index 1. 96 */ 97 nsresult GetFaviconDataAsync(const nsCString& aFaviconSpec, 98 mozIStorageStatementCallback* aCallback); 99 100 /** 101 * Call to send out favicon changed notifications. Should only be called 102 * when there is data loaded for the favicon. 103 * @param aPageURI 104 * The URI of the page to notify about. 105 * @param aFaviconURI 106 * The moz-anno:favicon URI of the icon. 107 * @param aGUID 108 * The unique ID associated with the page. 109 */ 110 void SendFaviconNotifications(nsIURI* aPageURI, nsIURI* aFaviconURI, 111 const nsACString& aGUID); 112 113 static mozilla::Atomic<int64_t> sLastInsertedIconId; 114 static void StoreLastInsertedId(const nsACString& aTable, 115 const int64_t aLastInsertedId); 116 117 NS_DECL_ISUPPORTS 118 NS_DECL_NSIFAVICONSERVICE 119 NS_DECL_MOZIASYNCFAVICONS 120 NS_DECL_NSITIMERCALLBACK 121 NS_DECL_NSINAMED 122 123 private: GetImgTools()124 imgITools* GetImgTools() { 125 if (!mImgTools) { 126 mImgTools = do_CreateInstance("@mozilla.org/image/tools;1"); 127 } 128 return mImgTools; 129 } 130 131 ~nsFaviconService(); 132 133 RefPtr<mozilla::places::Database> mDB; 134 135 nsCOMPtr<nsITimer> mExpireUnassociatedIconsTimer; 136 nsCOMPtr<imgITools> mImgTools; 137 138 static nsFaviconService* gFaviconService; 139 140 /** 141 * A cached URI for the default icon. We return this a lot, and don't want to 142 * re-parse and normalize our unchanging string many times. Important: do 143 * not return this directly; use Clone() since callers may change the object 144 * they get back. May be null, in which case it needs initialization. 145 */ 146 nsCOMPtr<nsIURI> mDefaultIcon; 147 148 uint32_t mFailedFaviconSerial; 149 nsDataHashtable<nsCStringHashKey, uint32_t> mFailedFavicons; 150 151 // This class needs access to the icons cache. 152 friend class mozilla::places::AsyncReplaceFaviconData; 153 nsTHashtable<UnassociatedIconHashKey> mUnassociatedIcons; 154 155 uint16_t mDefaultIconURIPreferredSize; 156 }; 157 158 #define FAVICON_ANNOTATION_NAME "favicon" 159 160 #endif // nsFaviconService_h_ 161