зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1269737 - Make AsyncFaviconHelpers more maintainable. r=adw
MozReview-Commit-ID: l0GnzPZK8w --HG-- rename : toolkit/components/places/AsyncFaviconHelpers.cpp => toolkit/components/places/FaviconHelpers.cpp rename : toolkit/components/places/AsyncFaviconHelpers.h => toolkit/components/places/FaviconHelpers.h extra : rebase_source : d164e8d246ee66b555bbd7d4db0d552da5ff2b28
This commit is contained in:
Родитель
6290ac73e4
Коммит
817566c802
|
@ -4,7 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "AsyncFaviconHelpers.h"
|
||||
#include "FaviconHelpers.h"
|
||||
|
||||
#include "nsICacheEntry.h"
|
||||
#include "nsICachingChannel.h"
|
||||
|
@ -40,12 +40,11 @@ namespace {
|
|||
* Page that should be fetched.
|
||||
*/
|
||||
nsresult
|
||||
FetchPageInfo(RefPtr<Database>& aDB,
|
||||
FetchPageInfo(const RefPtr<Database>& aDB,
|
||||
PageData& _page)
|
||||
{
|
||||
NS_PRECONDITION(_page.spec.Length(), "Must have a non-empty spec!");
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread");
|
||||
MOZ_ASSERT(_page.spec.Length(), "Must have a non-empty spec!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
// This query finds the bookmarked uri we want to set the icon for,
|
||||
// walking up to two redirect levels.
|
||||
|
@ -139,11 +138,10 @@ FetchPageInfo(RefPtr<Database>& aDB,
|
|||
* Icon that should be stored.
|
||||
*/
|
||||
nsresult
|
||||
SetIconInfo(RefPtr<Database>& aDB,
|
||||
IconData& aIcon)
|
||||
SetIconInfo(const RefPtr<Database>& aDB,
|
||||
const IconData& aIcon)
|
||||
{
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt = aDB->GetStatement(
|
||||
"INSERT OR REPLACE INTO moz_favicons "
|
||||
|
@ -178,12 +176,11 @@ SetIconInfo(RefPtr<Database>& aDB,
|
|||
* Icon that should be fetched.
|
||||
*/
|
||||
nsresult
|
||||
FetchIconInfo(RefPtr<Database>& aDB,
|
||||
FetchIconInfo(const RefPtr<Database>& aDB,
|
||||
IconData& _icon)
|
||||
{
|
||||
NS_PRECONDITION(_icon.spec.Length(), "Must have a non-empty spec!");
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread");
|
||||
MOZ_ASSERT(_icon.spec.Length(), "Must have a non-empty spec!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
if (_icon.status & ICON_STATUS_CACHED) {
|
||||
return NS_OK;
|
||||
|
@ -238,13 +235,12 @@ FetchIconInfo(RefPtr<Database>& aDB,
|
|||
}
|
||||
|
||||
nsresult
|
||||
FetchIconURL(RefPtr<Database>& aDB,
|
||||
FetchIconURL(const RefPtr<Database>& aDB,
|
||||
const nsACString& aPageSpec,
|
||||
nsACString& aIconSpec)
|
||||
{
|
||||
NS_PRECONDITION(!aPageSpec.IsEmpty(), "Page spec must not be empty.");
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread.");
|
||||
MOZ_ASSERT(!aPageSpec.IsEmpty(), "Page spec must not be empty.");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
aIconSpec.Truncate();
|
||||
|
||||
|
@ -280,8 +276,7 @@ FetchIconURL(RefPtr<Database>& aDB,
|
|||
PRTime
|
||||
GetExpirationTimeFromChannel(nsIChannel* aChannel)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Attempt to get an expiration time from the cache. If this fails, we'll
|
||||
// make one up.
|
||||
|
@ -320,8 +315,7 @@ nsresult
|
|||
OptimizeIconSize(IconData& aIcon,
|
||||
nsFaviconService* aFaviconSvc)
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Even if the page provides a large image for the favicon (eg, a highres
|
||||
// image or a multiresolution .ico file), don't try to store more data than
|
||||
|
@ -343,25 +337,6 @@ OptimizeIconSize(IconData& aIcon,
|
|||
|
||||
} // namespace
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// AsyncFaviconHelperBase
|
||||
|
||||
AsyncFaviconHelperBase::AsyncFaviconHelperBase(
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
)
|
||||
{
|
||||
// Don't AddRef or Release in runnables for thread-safety.
|
||||
mCallback.swap(aCallback);
|
||||
}
|
||||
|
||||
AsyncFaviconHelperBase::~AsyncFaviconHelperBase()
|
||||
{
|
||||
if (mCallback) {
|
||||
NS_ReleaseOnMainThread(mCallback.forget(), true);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// AsyncFetchAndSetIconForPage
|
||||
|
||||
|
@ -374,95 +349,26 @@ NS_IMPL_ISUPPORTS_INHERITED(
|
|||
, mozIPlacesPendingOperation
|
||||
)
|
||||
|
||||
// static
|
||||
nsresult
|
||||
AsyncFetchAndSetIconForPage::start(nsIURI* aFaviconURI,
|
||||
nsIURI* aPageURI,
|
||||
enum AsyncFaviconFetchMode aFetchMode,
|
||||
bool aFaviconLoadPrivate,
|
||||
nsIFaviconDataCallback* aCallback,
|
||||
nsIPrincipal* aLoadingPrincipal,
|
||||
mozIPlacesPendingOperation** _canceler)
|
||||
{
|
||||
NS_ENSURE_ARG(aLoadingPrincipal);
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread");
|
||||
|
||||
PageData page;
|
||||
nsresult rv = aPageURI->GetSpec(page.spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// URIs can arguably miss a host.
|
||||
(void)GetReversedHostname(aPageURI, page.revHost);
|
||||
bool canAddToHistory;
|
||||
nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
|
||||
NS_ENSURE_TRUE(navHistory, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = navHistory->CanAddURI(aPageURI, &canAddToHistory);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
page.canAddToHistory = !!canAddToHistory && !aFaviconLoadPrivate;
|
||||
|
||||
IconData icon;
|
||||
|
||||
nsFaviconService* favicons = nsFaviconService::GetFaviconService();
|
||||
NS_ENSURE_STATE(favicons);
|
||||
|
||||
UnassociatedIconHashKey* iconKey =
|
||||
favicons->mUnassociatedIcons.GetEntry(aFaviconURI);
|
||||
|
||||
if (iconKey) {
|
||||
icon = iconKey->iconData;
|
||||
favicons->mUnassociatedIcons.RemoveEntry(iconKey);
|
||||
} else {
|
||||
icon.fetchMode = aFetchMode;
|
||||
rv = aFaviconURI->GetSpec(icon.spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// If the page url points to an image, the icon's url will be the same.
|
||||
// In future evaluate to store a resample of the image. For now avoid that
|
||||
// for database size concerns.
|
||||
// Don't store favicons for error pages too.
|
||||
if (icon.spec.Equals(page.spec) ||
|
||||
icon.spec.Equals(FAVICON_ERRORPAGE_URL)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// The event will swap owning pointers, thus we need a new pointer.
|
||||
nsCOMPtr<nsIFaviconDataCallback> callback(aCallback);
|
||||
RefPtr<AsyncFetchAndSetIconForPage> event =
|
||||
new AsyncFetchAndSetIconForPage(icon, page, aFaviconLoadPrivate,
|
||||
callback, aLoadingPrincipal);
|
||||
|
||||
// Get the target thread and start the work.
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
// Return this event to the caller to allow aborting an eventual fetch.
|
||||
event.forget(_canceler);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AsyncFetchAndSetIconForPage::AsyncFetchAndSetIconForPage(
|
||||
IconData& aIcon
|
||||
, PageData& aPage
|
||||
, bool aFaviconLoadPrivate
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
, nsIFaviconDataCallback* aCallback
|
||||
, nsIPrincipal* aLoadingPrincipal
|
||||
) : AsyncFaviconHelperBase(aCallback)
|
||||
) : mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(aCallback))
|
||||
, mIcon(aIcon)
|
||||
, mPage(aPage)
|
||||
, mFaviconLoadPrivate(aFaviconLoadPrivate)
|
||||
, mLoadingPrincipal(new nsMainThreadPtrHolder<nsIPrincipal>(aLoadingPrincipal))
|
||||
, mCanceled(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncFetchAndSetIconForPage::Run()
|
||||
{
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
// Try to fetch the icon from the database.
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
|
@ -591,7 +497,7 @@ AsyncFetchAndSetIconForPage::OnDataAvailable(nsIRequest* aRequest,
|
|||
|
||||
NS_IMETHODIMP
|
||||
AsyncFetchAndSetIconForPage::GetInterface(const nsIID& uuid,
|
||||
void** aResult)
|
||||
void** aResult)
|
||||
{
|
||||
return QueryInterface(uuid, aResult);
|
||||
}
|
||||
|
@ -715,24 +621,19 @@ AsyncFetchAndSetIconForPage::OnStopRequest(nsIRequest* aRequest,
|
|||
//// AsyncAssociateIconToPage
|
||||
|
||||
AsyncAssociateIconToPage::AsyncAssociateIconToPage(
|
||||
IconData& aIcon
|
||||
, PageData& aPage
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
) : AsyncFaviconHelperBase(aCallback)
|
||||
const IconData& aIcon
|
||||
, const PageData& aPage
|
||||
, const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback
|
||||
) : mCallback(aCallback)
|
||||
, mIcon(aIcon)
|
||||
, mPage(aPage)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncAssociateIconToPage::~AsyncAssociateIconToPage()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncAssociateIconToPage::Run()
|
||||
{
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
|
@ -814,48 +715,19 @@ AsyncAssociateIconToPage::Run()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// AsyncGetFaviconURLForPage
|
||||
|
||||
// static
|
||||
nsresult
|
||||
AsyncGetFaviconURLForPage::start(nsIURI* aPageURI,
|
||||
nsIFaviconDataCallback* aCallback)
|
||||
{
|
||||
NS_ENSURE_ARG(aCallback);
|
||||
NS_ENSURE_ARG(aPageURI);
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread.");
|
||||
|
||||
nsAutoCString pageSpec;
|
||||
nsresult rv = aPageURI->GetSpec(pageSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFaviconDataCallback> callback = aCallback;
|
||||
RefPtr<AsyncGetFaviconURLForPage> event =
|
||||
new AsyncGetFaviconURLForPage(pageSpec, callback);
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AsyncGetFaviconURLForPage::AsyncGetFaviconURLForPage(
|
||||
const nsACString& aPageSpec
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
) : AsyncFaviconHelperBase(aCallback)
|
||||
, nsIFaviconDataCallback* aCallback
|
||||
) : mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(aCallback))
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mPageSpec.Assign(aPageSpec);
|
||||
}
|
||||
|
||||
AsyncGetFaviconURLForPage::~AsyncGetFaviconURLForPage()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncGetFaviconURLForPage::Run()
|
||||
{
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread.");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
|
@ -881,48 +753,19 @@ AsyncGetFaviconURLForPage::Run()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// AsyncGetFaviconDataForPage
|
||||
|
||||
// static
|
||||
nsresult
|
||||
AsyncGetFaviconDataForPage::start(nsIURI* aPageURI,
|
||||
nsIFaviconDataCallback* aCallback)
|
||||
{
|
||||
NS_ENSURE_ARG(aCallback);
|
||||
NS_ENSURE_ARG(aPageURI);
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread.");
|
||||
|
||||
nsAutoCString pageSpec;
|
||||
nsresult rv = aPageURI->GetSpec(pageSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFaviconDataCallback> callback = aCallback;
|
||||
RefPtr<AsyncGetFaviconDataForPage> event =
|
||||
new AsyncGetFaviconDataForPage(pageSpec, callback);
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AsyncGetFaviconDataForPage::AsyncGetFaviconDataForPage(
|
||||
const nsACString& aPageSpec
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
) : AsyncFaviconHelperBase(aCallback)
|
||||
{
|
||||
, nsIFaviconDataCallback* aCallback
|
||||
) : mCallback(new nsMainThreadPtrHolder<nsIFaviconDataCallback>(aCallback))
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mPageSpec.Assign(aPageSpec);
|
||||
}
|
||||
|
||||
AsyncGetFaviconDataForPage::~AsyncGetFaviconDataForPage()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncGetFaviconDataForPage::Run()
|
||||
{
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread.");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
|
@ -953,42 +796,15 @@ AsyncGetFaviconDataForPage::Run()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// AsyncReplaceFaviconData
|
||||
|
||||
// static
|
||||
nsresult
|
||||
AsyncReplaceFaviconData::start(IconData *aIcon)
|
||||
{
|
||||
NS_ENSURE_ARG(aIcon);
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread.");
|
||||
|
||||
nsCOMPtr<nsIFaviconDataCallback> callback;
|
||||
RefPtr<AsyncReplaceFaviconData> event =
|
||||
new AsyncReplaceFaviconData(*aIcon, callback);
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AsyncReplaceFaviconData::AsyncReplaceFaviconData(
|
||||
IconData &aIcon
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
) : AsyncFaviconHelperBase(aCallback)
|
||||
, mIcon(aIcon)
|
||||
{
|
||||
}
|
||||
|
||||
AsyncReplaceFaviconData::~AsyncReplaceFaviconData()
|
||||
AsyncReplaceFaviconData::AsyncReplaceFaviconData(const IconData &aIcon)
|
||||
: mIcon(aIcon)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AsyncReplaceFaviconData::Run()
|
||||
{
|
||||
NS_PRECONDITION(!NS_IsMainThread(),
|
||||
"This should not be called on the main thread");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
|
@ -1005,35 +821,18 @@ AsyncReplaceFaviconData::Run()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We can invalidate the cache version since we now persist the icon.
|
||||
nsCOMPtr<nsIRunnable> event = new RemoveIconDataCacheEntry(mIcon, mCallback);
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
NewRunnableMethod(this, &AsyncReplaceFaviconData::RemoveIconDataCacheEntry);
|
||||
rv = NS_DispatchToMainThread(event);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// RemoveIconDataCacheEntry
|
||||
|
||||
RemoveIconDataCacheEntry::RemoveIconDataCacheEntry(
|
||||
IconData& aIcon
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
)
|
||||
: AsyncFaviconHelperBase(aCallback)
|
||||
, mIcon(aIcon)
|
||||
nsresult
|
||||
AsyncReplaceFaviconData::RemoveIconDataCacheEntry()
|
||||
{
|
||||
}
|
||||
|
||||
RemoveIconDataCacheEntry::~RemoveIconDataCacheEntry()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
RemoveIconDataCacheEntry::Run()
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIURI> iconURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(iconURI), mIcon.spec);
|
||||
|
@ -1051,25 +850,20 @@ RemoveIconDataCacheEntry::Run()
|
|||
//// NotifyIconObservers
|
||||
|
||||
NotifyIconObservers::NotifyIconObservers(
|
||||
IconData& aIcon
|
||||
, PageData& aPage
|
||||
, nsCOMPtr<nsIFaviconDataCallback>& aCallback
|
||||
const IconData& aIcon
|
||||
, const PageData& aPage
|
||||
, const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback
|
||||
)
|
||||
: AsyncFaviconHelperBase(aCallback)
|
||||
: mCallback(aCallback)
|
||||
, mIcon(aIcon)
|
||||
, mPage(aPage)
|
||||
{
|
||||
}
|
||||
|
||||
NotifyIconObservers::~NotifyIconObservers()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NotifyIconObservers::Run()
|
||||
{
|
||||
NS_PRECONDITION(NS_IsMainThread(),
|
||||
"This should be called on the main thread");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIURI> iconURI;
|
||||
if (!mIcon.spec.IsEmpty()) {
|
||||
|
@ -1117,7 +911,7 @@ NotifyIconObservers::SendGlobalNotifications(nsIURI* aIconURI)
|
|||
if (!DB)
|
||||
return;
|
||||
// This will be silent, so be sure to not pass in the current callback.
|
||||
nsCOMPtr<nsIFaviconDataCallback> nullCallback;
|
||||
nsMainThreadPtrHandle<nsIFaviconDataCallback> nullCallback;
|
||||
RefPtr<AsyncAssociateIconToPage> event =
|
||||
new AsyncAssociateIconToPage(mIcon, bookmarkedPage, nullCallback);
|
||||
DB->DispatchToAsyncThread(event);
|
|
@ -4,8 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef AsyncFaviconHelpers_h_
|
||||
#define AsyncFaviconHelpers_h_
|
||||
#pragma once
|
||||
|
||||
#include "nsIFaviconService.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
|
@ -95,65 +94,25 @@ struct PageData
|
|||
nsCString guid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for events declared in this file. This class's main purpose is
|
||||
* to declare a destructor which releases mCallback on the main thread.
|
||||
*/
|
||||
class AsyncFaviconHelperBase : public Runnable
|
||||
{
|
||||
protected:
|
||||
explicit AsyncFaviconHelperBase(nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
|
||||
virtual ~AsyncFaviconHelperBase();
|
||||
|
||||
// Strong reference since we are responsible for its existence.
|
||||
nsCOMPtr<nsIFaviconDataCallback> mCallback;
|
||||
};
|
||||
|
||||
/**
|
||||
* Async fetches icon from database or network, associates it with the required
|
||||
* page and finally notifies the change.
|
||||
*/
|
||||
class AsyncFetchAndSetIconForPage final : public AsyncFaviconHelperBase
|
||||
class AsyncFetchAndSetIconForPage final : public Runnable
|
||||
, public nsIStreamListener
|
||||
, public nsIInterfaceRequestor
|
||||
, public nsIChannelEventSink
|
||||
, public mozIPlacesPendingOperation
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSIRUNNABLE
|
||||
NS_DECL_MOZIPLACESPENDINGOPERATION
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
/**
|
||||
* Creates the event and dispatches it to the async thread.
|
||||
*
|
||||
* @param aFaviconURI
|
||||
* URI of the icon to be fetched and associated.
|
||||
* @param aPageURI
|
||||
* URI of the page to which associate the icon.
|
||||
* @param aFetchMode
|
||||
* Specifies whether a icon should be fetched from network if not found
|
||||
* in the database.
|
||||
* @param aFaviconLoadPrivate
|
||||
* Whether this favicon load is in private browsing.
|
||||
* @param aCallback
|
||||
* Function to be called when the fetch-and-associate process finishes.
|
||||
* @param aLoadingPrincipal
|
||||
* LoadingPrincipal of the icon to be fetched.
|
||||
*/
|
||||
static nsresult start(nsIURI* aFaviconURI,
|
||||
nsIURI* aPageURI,
|
||||
enum AsyncFaviconFetchMode aFetchMode,
|
||||
bool aFaviconLoadPrivate,
|
||||
nsIFaviconDataCallback* aCallback,
|
||||
nsIPrincipal* aLoadingPrincipal,
|
||||
mozIPlacesPendingOperation ** _canceler);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -171,13 +130,14 @@ class AsyncFetchAndSetIconForPage final : public AsyncFaviconHelperBase
|
|||
AsyncFetchAndSetIconForPage(IconData& aIcon,
|
||||
PageData& aPage,
|
||||
bool aFaviconLoadPrivate,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback,
|
||||
nsIFaviconDataCallback* aCallback,
|
||||
nsIPrincipal* aLoadingPrincipal);
|
||||
|
||||
private:
|
||||
nsresult FetchFromNetwork();
|
||||
virtual ~AsyncFetchAndSetIconForPage() {}
|
||||
|
||||
nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback;
|
||||
IconData mIcon;
|
||||
PageData mPage;
|
||||
const bool mFaviconLoadPrivate;
|
||||
|
@ -190,7 +150,7 @@ private:
|
|||
* Associates the icon to the required page, finally dispatches an event to the
|
||||
* main thread to notify the change to observers.
|
||||
*/
|
||||
class AsyncAssociateIconToPage : public AsyncFaviconHelperBase
|
||||
class AsyncAssociateIconToPage final : public Runnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
@ -205,13 +165,12 @@ public:
|
|||
* @param aCallback
|
||||
* Function to be called when the associate process finishes.
|
||||
*/
|
||||
AsyncAssociateIconToPage(IconData& aIcon,
|
||||
PageData& aPage,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
AsyncAssociateIconToPage(const IconData& aIcon,
|
||||
const PageData& aPage,
|
||||
const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback);
|
||||
|
||||
virtual ~AsyncAssociateIconToPage();
|
||||
|
||||
protected:
|
||||
private:
|
||||
nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback;
|
||||
IconData mIcon;
|
||||
PageData mPage;
|
||||
};
|
||||
|
@ -220,22 +179,11 @@ protected:
|
|||
* Asynchronously tries to get the URL of a page's favicon, then notifies the
|
||||
* given observer.
|
||||
*/
|
||||
class AsyncGetFaviconURLForPage : public AsyncFaviconHelperBase
|
||||
class AsyncGetFaviconURLForPage final : public Runnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
/**
|
||||
* Creates the event and dispatches it to the I/O thread.
|
||||
*
|
||||
* @param aPageURI
|
||||
* URL of the page whose favicon's URL we're fetching
|
||||
* @param aCallback
|
||||
* function to be called once finished
|
||||
*/
|
||||
static nsresult start(nsIURI* aPageURI,
|
||||
nsIFaviconDataCallback* aCallback);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -245,11 +193,10 @@ public:
|
|||
* function to be called once finished
|
||||
*/
|
||||
AsyncGetFaviconURLForPage(const nsACString& aPageSpec,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
|
||||
virtual ~AsyncGetFaviconURLForPage();
|
||||
nsIFaviconDataCallback* aCallback);
|
||||
|
||||
private:
|
||||
nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback;
|
||||
nsCString mPageSpec;
|
||||
};
|
||||
|
||||
|
@ -258,22 +205,11 @@ private:
|
|||
* Asynchronously tries to get the URL and data of a page's favicon, then
|
||||
* notifies the given observer.
|
||||
*/
|
||||
class AsyncGetFaviconDataForPage : public AsyncFaviconHelperBase
|
||||
class AsyncGetFaviconDataForPage final : public Runnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
/**
|
||||
* Creates the event and dispatches it to the I/O thread.
|
||||
*
|
||||
* @param aPageURI
|
||||
* URL of the page whose favicon URL and data we're fetching
|
||||
* @param aCallback
|
||||
* function to be called once finished
|
||||
*/
|
||||
static nsresult start(nsIURI* aPageURI,
|
||||
nsIFaviconDataCallback* aCallback);
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
|
@ -283,47 +219,30 @@ public:
|
|||
* function to be called once finished
|
||||
*/
|
||||
AsyncGetFaviconDataForPage(const nsACString& aPageSpec,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
|
||||
virtual ~AsyncGetFaviconDataForPage();
|
||||
nsIFaviconDataCallback* aCallback);
|
||||
|
||||
private:
|
||||
nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback;
|
||||
nsCString mPageSpec;
|
||||
};
|
||||
|
||||
class AsyncReplaceFaviconData : public AsyncFaviconHelperBase
|
||||
class AsyncReplaceFaviconData final : public Runnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
static nsresult start(IconData *aIcon);
|
||||
explicit AsyncReplaceFaviconData(const IconData& aIcon);
|
||||
|
||||
AsyncReplaceFaviconData(IconData &aIcon,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
private:
|
||||
nsresult RemoveIconDataCacheEntry();
|
||||
|
||||
virtual ~AsyncReplaceFaviconData();
|
||||
|
||||
protected:
|
||||
IconData mIcon;
|
||||
};
|
||||
|
||||
class RemoveIconDataCacheEntry : public AsyncFaviconHelperBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
RemoveIconDataCacheEntry(IconData &aIcon,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
virtual ~RemoveIconDataCacheEntry();
|
||||
|
||||
protected:
|
||||
IconData mIcon;
|
||||
};
|
||||
|
||||
/**
|
||||
* Notifies the icon change to favicon observers.
|
||||
*/
|
||||
class NotifyIconObservers : public AsyncFaviconHelperBase
|
||||
class NotifyIconObservers final : public Runnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
@ -338,12 +257,12 @@ public:
|
|||
* @param aCallback
|
||||
* Function to be notified in all cases.
|
||||
*/
|
||||
NotifyIconObservers(IconData& aIcon,
|
||||
PageData& aPage,
|
||||
nsCOMPtr<nsIFaviconDataCallback>& aCallback);
|
||||
virtual ~NotifyIconObservers();
|
||||
NotifyIconObservers(const IconData& aIcon,
|
||||
const PageData& aPage,
|
||||
const nsMainThreadPtrHandle<nsIFaviconDataCallback>& aCallback);
|
||||
|
||||
protected:
|
||||
private:
|
||||
nsMainThreadPtrHandle<nsIFaviconDataCallback> mCallback;
|
||||
IconData mIcon;
|
||||
PageData mPage;
|
||||
|
||||
|
@ -352,5 +271,3 @@ protected:
|
|||
|
||||
} // namespace places
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // AsyncFaviconHelpers_h_
|
|
@ -35,8 +35,8 @@ if CONFIG['MOZ_PLACES']:
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'AsyncFaviconHelpers.cpp',
|
||||
'Database.cpp',
|
||||
'FaviconHelpers.cpp',
|
||||
'Helpers.cpp',
|
||||
'History.cpp',
|
||||
'nsAnnoProtocolHandler.cpp',
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "nsNavHistory.h"
|
||||
#include "nsPlacesMacros.h"
|
||||
#include "Helpers.h"
|
||||
#include "AsyncFaviconHelpers.h"
|
||||
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
@ -215,6 +214,7 @@ nsFaviconService::SetAndFetchFaviconForPage(nsIURI* aPageURI,
|
|||
nsIPrincipal* aLoadingPrincipal,
|
||||
mozIPlacesPendingOperation **_canceler)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aPageURI);
|
||||
NS_ENSURE_ARG(aFaviconURI);
|
||||
NS_ENSURE_ARG_POINTER(_canceler);
|
||||
|
@ -242,13 +242,52 @@ nsFaviconService::SetAndFetchFaviconForPage(nsIURI* aPageURI,
|
|||
// Check if the icon already exists and fetch it from the network, if needed.
|
||||
// Finally associate the icon to the requested page if not yet associated.
|
||||
bool loadPrivate = aFaviconLoadType == nsIFaviconService::FAVICON_LOAD_PRIVATE;
|
||||
rv = AsyncFetchAndSetIconForPage::start(
|
||||
aFaviconURI, aPageURI, aForceReload ? FETCH_ALWAYS : FETCH_IF_MISSING,
|
||||
loadPrivate, aCallback, loadingPrincipal, _canceler
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PageData page;
|
||||
rv = aPageURI->GetSpec(page.spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// URIs can arguably miss a host.
|
||||
(void)GetReversedHostname(aPageURI, page.revHost);
|
||||
bool canAddToHistory;
|
||||
nsNavHistory* navHistory = nsNavHistory::GetHistoryService();
|
||||
NS_ENSURE_TRUE(navHistory, NS_ERROR_OUT_OF_MEMORY);
|
||||
rv = navHistory->CanAddURI(aPageURI, &canAddToHistory);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
page.canAddToHistory = !!canAddToHistory && !loadPrivate;
|
||||
|
||||
IconData icon;
|
||||
UnassociatedIconHashKey* iconKey = mUnassociatedIcons.GetEntry(aFaviconURI);
|
||||
if (iconKey) {
|
||||
icon = iconKey->iconData;
|
||||
mUnassociatedIcons.RemoveEntry(iconKey);
|
||||
} else {
|
||||
icon.fetchMode = aForceReload ? FETCH_ALWAYS : FETCH_IF_MISSING;
|
||||
rv = aFaviconURI->GetSpec(icon.spec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// If the page url points to an image, the icon's url will be the same.
|
||||
// In future evaluate to store a resample of the image. For now avoid that
|
||||
// for database size concerns.
|
||||
// Don't store favicons for error pages too.
|
||||
if (icon.spec.Equals(page.spec) ||
|
||||
icon.spec.Equals(FAVICON_ERRORPAGE_URL)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<AsyncFetchAndSetIconForPage> event =
|
||||
new AsyncFetchAndSetIconForPage(icon, page, loadPrivate,
|
||||
aCallback, aLoadingPrincipal);
|
||||
|
||||
// Get the target thread and start the work.
|
||||
// DB will be updated and observers notified when data has finished loading.
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
// Return this event to the caller to allow aborting an eventual fetch.
|
||||
event.forget(_canceler);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -259,6 +298,7 @@ nsFaviconService::ReplaceFaviconData(nsIURI* aFaviconURI,
|
|||
const nsACString& aMimeType,
|
||||
PRTime aExpiration)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aFaviconURI);
|
||||
NS_ENSURE_ARG(aData);
|
||||
NS_ENSURE_TRUE(aDataLen > 0, NS_ERROR_INVALID_ARG);
|
||||
|
@ -311,8 +351,10 @@ nsFaviconService::ReplaceFaviconData(nsIURI* aFaviconURI,
|
|||
// If the database contains an icon at the given url, we will update the
|
||||
// database immediately so that the associated pages are kept in sync.
|
||||
// Otherwise, do nothing and let the icon be picked up from the memory hash.
|
||||
rv = AsyncReplaceFaviconData::start(iconData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
RefPtr<AsyncReplaceFaviconData> event = new AsyncReplaceFaviconData(*iconData);
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -403,11 +445,21 @@ NS_IMETHODIMP
|
|||
nsFaviconService::GetFaviconURLForPage(nsIURI *aPageURI,
|
||||
nsIFaviconDataCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aPageURI);
|
||||
NS_ENSURE_ARG(aCallback);
|
||||
|
||||
nsresult rv = AsyncGetFaviconURLForPage::start(aPageURI, aCallback);
|
||||
nsAutoCString pageSpec;
|
||||
nsresult rv = aPageURI->GetSpec(pageSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<AsyncGetFaviconURLForPage> event =
|
||||
new AsyncGetFaviconURLForPage(pageSpec, aCallback);
|
||||
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -415,11 +467,20 @@ NS_IMETHODIMP
|
|||
nsFaviconService::GetFaviconDataForPage(nsIURI* aPageURI,
|
||||
nsIFaviconDataCallback* aCallback)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
NS_ENSURE_ARG(aPageURI);
|
||||
NS_ENSURE_ARG(aCallback);
|
||||
|
||||
nsresult rv = AsyncGetFaviconDataForPage::start(aPageURI, aCallback);
|
||||
nsAutoCString pageSpec;
|
||||
nsresult rv = aPageURI->GetSpec(pageSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
RefPtr<AsyncGetFaviconDataForPage> event =
|
||||
new AsyncGetFaviconDataForPage(pageSpec, aCallback);
|
||||
RefPtr<Database> DB = Database::GetDatabase();
|
||||
NS_ENSURE_STATE(DB);
|
||||
DB->DispatchToAsyncThread(event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "mozilla/storage.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "AsyncFaviconHelpers.h"
|
||||
#include "FaviconHelpers.h"
|
||||
|
||||
// Favicons bigger than this size should not be saved to the db to avoid
|
||||
// bloating it with large image blobs.
|
||||
|
@ -149,9 +149,8 @@ private:
|
|||
uint32_t mFailedFaviconSerial;
|
||||
nsDataHashtable<nsCStringHashKey, uint32_t> mFailedFavicons;
|
||||
|
||||
// AsyncFetchAndSetIconForPage needs access to the icon cache
|
||||
friend class mozilla::places::AsyncFetchAndSetIconForPage;
|
||||
friend class mozilla::places::RemoveIconDataCacheEntry;
|
||||
// This class needs access to the icons cache.
|
||||
friend class mozilla::places::AsyncReplaceFaviconData;
|
||||
nsTHashtable<UnassociatedIconHashKey> mUnassociatedIcons;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче