michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : 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 AsyncFaviconHelpers_h_ michael@0: #define AsyncFaviconHelpers_h_ michael@0: michael@0: #include "nsIFaviconService.h" michael@0: #include "nsIChannelEventSink.h" michael@0: #include "nsIInterfaceRequestor.h" michael@0: #include "nsIStreamListener.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: #include "Database.h" michael@0: #include "mozilla/storage.h" michael@0: michael@0: #define ICON_STATUS_UNKNOWN 0 michael@0: #define ICON_STATUS_CHANGED 1 << 0 michael@0: #define ICON_STATUS_SAVED 1 << 1 michael@0: #define ICON_STATUS_ASSOCIATED 1 << 2 michael@0: #define ICON_STATUS_CACHED 1 << 3 michael@0: michael@0: #define TO_CHARBUFFER(_buffer) \ michael@0: reinterpret_cast(const_cast(_buffer)) michael@0: #define TO_INTBUFFER(_string) \ michael@0: reinterpret_cast(const_cast(_string.get())) michael@0: michael@0: /** michael@0: * The maximum time we will keep a favicon around. We always ask the cache, if michael@0: * we can, but default to this value if we do not get a time back, or the time michael@0: * is more in the future than this. michael@0: * Currently set to one week from now. michael@0: */ michael@0: #define MAX_FAVICON_EXPIRATION ((PRTime)7 * 24 * 60 * 60 * PR_USEC_PER_SEC) michael@0: michael@0: namespace mozilla { michael@0: namespace places { michael@0: michael@0: /** michael@0: * Indicates when a icon should be fetched from network. michael@0: */ michael@0: enum AsyncFaviconFetchMode { michael@0: FETCH_NEVER = 0 michael@0: , FETCH_IF_MISSING michael@0: , FETCH_ALWAYS michael@0: }; michael@0: michael@0: /** michael@0: * Data cache for a icon entry. michael@0: */ michael@0: struct IconData michael@0: { michael@0: IconData() michael@0: : id(0) michael@0: , expiration(0) michael@0: , fetchMode(FETCH_NEVER) michael@0: , status(ICON_STATUS_UNKNOWN) michael@0: { michael@0: guid.SetIsVoid(true); michael@0: } michael@0: michael@0: int64_t id; michael@0: nsCString spec; michael@0: nsCString data; michael@0: nsCString mimeType; michael@0: PRTime expiration; michael@0: enum AsyncFaviconFetchMode fetchMode; michael@0: uint16_t status; // This is a bitset, see ICON_STATUS_* defines above. michael@0: nsCString guid; michael@0: }; michael@0: michael@0: /** michael@0: * Data cache for a page entry. michael@0: */ michael@0: struct PageData michael@0: { michael@0: PageData() michael@0: : id(0) michael@0: , canAddToHistory(true) michael@0: , iconId(0) michael@0: { michael@0: guid.SetIsVoid(true); michael@0: } michael@0: michael@0: int64_t id; michael@0: nsCString spec; michael@0: nsCString bookmarkedSpec; michael@0: nsString revHost; michael@0: bool canAddToHistory; // False for disabled history and unsupported schemas. michael@0: int64_t iconId; michael@0: nsCString guid; michael@0: }; michael@0: michael@0: /** michael@0: * Base class for events declared in this file. This class's main purpose is michael@0: * to declare a destructor which releases mCallback on the main thread. michael@0: */ michael@0: class AsyncFaviconHelperBase : public nsRunnable michael@0: { michael@0: protected: michael@0: AsyncFaviconHelperBase(nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncFaviconHelperBase(); michael@0: michael@0: nsRefPtr mDB; michael@0: // Strong reference since we are responsible for its existence. michael@0: nsCOMPtr mCallback; michael@0: }; michael@0: michael@0: /** michael@0: * Async fetches icon from database or network, associates it with the required michael@0: * page and finally notifies the change. michael@0: */ michael@0: class AsyncFetchAndSetIconForPage : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: /** michael@0: * Creates the event and dispatches it to the async thread. michael@0: * michael@0: * @param aFaviconURI michael@0: * URI of the icon to be fetched and associated. michael@0: * @param aPageURI michael@0: * URI of the page to which associate the icon. michael@0: * @param aFetchMode michael@0: * Specifies whether a icon should be fetched from network if not found michael@0: * in the database. michael@0: * @param aCallback michael@0: * Function to be called when the fetch-and-associate process finishes. michael@0: */ michael@0: static nsresult start(nsIURI* aFaviconURI, michael@0: nsIURI* aPageURI, michael@0: enum AsyncFaviconFetchMode aFetchMode, michael@0: uint32_t aFaviconLoadType, michael@0: nsIFaviconDataCallback* aCallback); michael@0: michael@0: /** michael@0: * Constructor. michael@0: * michael@0: * @param aIcon michael@0: * Icon to be fetched and associated. michael@0: * @param aPage michael@0: * Page to which associate the icon. michael@0: * @param aCallback michael@0: * Function to be called when the fetch-and-associate process finishes. michael@0: */ michael@0: AsyncFetchAndSetIconForPage(IconData& aIcon, michael@0: PageData& aPage, michael@0: uint32_t aFaviconLoadType, michael@0: nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncFetchAndSetIconForPage(); michael@0: michael@0: protected: michael@0: IconData mIcon; michael@0: PageData mPage; michael@0: const bool mFaviconLoadPrivate; michael@0: }; michael@0: michael@0: /** michael@0: * If needed will asynchronously fetch the icon from the network. It will michael@0: * finally dispatch an event to the async thread to associate the icon with michael@0: * the required page. michael@0: */ michael@0: class AsyncFetchAndSetIconFromNetwork : public AsyncFaviconHelperBase michael@0: , public nsIStreamListener michael@0: , public nsIInterfaceRequestor michael@0: , public nsIChannelEventSink michael@0: { michael@0: public: michael@0: NS_DECL_NSISTREAMLISTENER michael@0: NS_DECL_NSIINTERFACEREQUESTOR michael@0: NS_DECL_NSICHANNELEVENTSINK michael@0: NS_DECL_NSIREQUESTOBSERVER michael@0: NS_DECL_NSIRUNNABLE michael@0: NS_DECL_ISUPPORTS_INHERITED michael@0: michael@0: /** michael@0: * Constructor. michael@0: * michael@0: * @param aIcon michael@0: * Icon to be fetched and associated. michael@0: * @param aPage michael@0: * Page to which associate the icon. michael@0: * @param aCallback michael@0: * Function to be called when the fetch-and-associate process finishes. michael@0: */ michael@0: AsyncFetchAndSetIconFromNetwork(IconData& aIcon, michael@0: PageData& aPage, michael@0: bool aFaviconLoadPrivate, michael@0: nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncFetchAndSetIconFromNetwork(); michael@0: michael@0: protected: michael@0: IconData mIcon; michael@0: PageData mPage; michael@0: const bool mFaviconLoadPrivate; michael@0: }; michael@0: michael@0: /** michael@0: * Associates the icon to the required page, finally dispatches an event to the michael@0: * main thread to notify the change to observers. michael@0: */ michael@0: class AsyncAssociateIconToPage : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: /** michael@0: * Constructor. michael@0: * michael@0: * @param aIcon michael@0: * Icon to be associated. michael@0: * @param aPage michael@0: * Page to which associate the icon. michael@0: * @param aCallback michael@0: * Function to be called when the associate process finishes. michael@0: */ michael@0: AsyncAssociateIconToPage(IconData& aIcon, michael@0: PageData& aPage, michael@0: nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncAssociateIconToPage(); michael@0: michael@0: protected: michael@0: IconData mIcon; michael@0: PageData mPage; michael@0: }; michael@0: michael@0: /** michael@0: * Asynchronously tries to get the URL of a page's favicon, then notifies the michael@0: * given observer. michael@0: */ michael@0: class AsyncGetFaviconURLForPage : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: /** michael@0: * Creates the event and dispatches it to the I/O thread. michael@0: * michael@0: * @param aPageURI michael@0: * URL of the page whose favicon's URL we're fetching michael@0: * @param aCallback michael@0: * function to be called once finished michael@0: */ michael@0: static nsresult start(nsIURI* aPageURI, michael@0: nsIFaviconDataCallback* aCallback); michael@0: michael@0: /** michael@0: * Constructor. michael@0: * michael@0: * @param aPageSpec michael@0: * URL of the page whose favicon's URL we're fetching michael@0: * @param aCallback michael@0: * function to be called once finished michael@0: */ michael@0: AsyncGetFaviconURLForPage(const nsACString& aPageSpec, michael@0: nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncGetFaviconURLForPage(); michael@0: michael@0: private: michael@0: nsCString mPageSpec; michael@0: }; michael@0: michael@0: michael@0: /** michael@0: * Asynchronously tries to get the URL and data of a page's favicon, then michael@0: * notifies the given observer. michael@0: */ michael@0: class AsyncGetFaviconDataForPage : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: /** michael@0: * Creates the event and dispatches it to the I/O thread. michael@0: * michael@0: * @param aPageURI michael@0: * URL of the page whose favicon URL and data we're fetching michael@0: * @param aCallback michael@0: * function to be called once finished michael@0: */ michael@0: static nsresult start(nsIURI* aPageURI, michael@0: nsIFaviconDataCallback* aCallback); michael@0: michael@0: /** michael@0: * Constructor. michael@0: * michael@0: * @param aPageSpec michael@0: * URL of the page whose favicon URL and data we're fetching michael@0: * @param aCallback michael@0: * function to be called once finished michael@0: */ michael@0: AsyncGetFaviconDataForPage(const nsACString& aPageSpec, michael@0: nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncGetFaviconDataForPage(); michael@0: michael@0: private: michael@0: nsCString mPageSpec; michael@0: }; michael@0: michael@0: class AsyncReplaceFaviconData : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: static nsresult start(IconData *aIcon); michael@0: michael@0: AsyncReplaceFaviconData(IconData &aIcon, michael@0: nsCOMPtr& aCallback); michael@0: michael@0: virtual ~AsyncReplaceFaviconData(); michael@0: michael@0: protected: michael@0: IconData mIcon; michael@0: }; michael@0: michael@0: class RemoveIconDataCacheEntry : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: RemoveIconDataCacheEntry(IconData &aIcon, michael@0: nsCOMPtr& aCallback); michael@0: virtual ~RemoveIconDataCacheEntry(); michael@0: michael@0: protected: michael@0: IconData mIcon; michael@0: }; michael@0: michael@0: /** michael@0: * Notifies the icon change to favicon observers. michael@0: */ michael@0: class NotifyIconObservers : public AsyncFaviconHelperBase michael@0: { michael@0: public: michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: /** michael@0: * Constructor. michael@0: * michael@0: * @param aIcon michael@0: * Icon information. Can be empty if no icon is associated to the page. michael@0: * @param aPage michael@0: * Page to which the icon information applies. michael@0: * @param aCallback michael@0: * Function to be notified in all cases. michael@0: */ michael@0: NotifyIconObservers(IconData& aIcon, michael@0: PageData& aPage, michael@0: nsCOMPtr& aCallback); michael@0: virtual ~NotifyIconObservers(); michael@0: michael@0: protected: michael@0: IconData mIcon; michael@0: PageData mPage; michael@0: michael@0: void SendGlobalNotifications(nsIURI* aIconURI); michael@0: }; michael@0: michael@0: } // namespace places michael@0: } // namespace mozilla michael@0: michael@0: #endif // AsyncFaviconHelpers_h_