Bug 531236 - Crash [@ nsNavBookmarks::GetBookmarksHash], r=dietrich a=blocking192

This commit is contained in:
Marco Bonardo 2009-12-01 14:00:45 +01:00
parent 56aa915b4b
commit 01598799f4
11 changed files with 211 additions and 151 deletions

View File

@ -53,6 +53,7 @@
#include "nsNavBookmarks.h"
#include "nsPlacesTables.h"
#include "nsPlacesIndexes.h"
#include "nsPlacesMacros.h"
const PRInt32 nsAnnotationService::kAnnoIndex_ID = 0;
const PRInt32 nsAnnotationService::kAnnoIndex_PageOrItem = 1;
@ -65,7 +66,7 @@ const PRInt32 nsAnnotationService::kAnnoIndex_Type = 7;
const PRInt32 nsAnnotationService::kAnnoIndex_DateAdded = 8;
const PRInt32 nsAnnotationService::kAnnoIndex_LastModified = 9;
nsAnnotationService* nsAnnotationService::gAnnotationService;
PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsAnnotationService, gAnnotationService)
NS_IMPL_ISUPPORTS1(nsAnnotationService,
nsIAnnotationService)
@ -75,7 +76,7 @@ NS_IMPL_ISUPPORTS1(nsAnnotationService,
nsAnnotationService::nsAnnotationService()
{
NS_ASSERTION(!gAnnotationService,
"ATTEMPTING TO CREATE TWO INSTANCES OF THE ANNOTATION SERVICE!");
"Attempting to create two instances of the service!");
gAnnotationService = this;
}
@ -85,7 +86,7 @@ nsAnnotationService::nsAnnotationService()
nsAnnotationService::~nsAnnotationService()
{
NS_ASSERTION(gAnnotationService == this,
"Deleting a non-singleton annotation service");
"Deleting a non-singleton instance of the service");
if (gAnnotationService == this)
gAnnotationService = nsnull;
}
@ -101,9 +102,9 @@ nsAnnotationService::Init()
// The history service will normally already be created and will call our
// static InitTables function. It will get autocreated here if it hasn't
// already been created.
nsNavHistory* history = nsNavHistory::GetHistoryService();
if (! history)
return NS_ERROR_FAILURE;
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
mDBConn = history->GetStorageConnection();
// annotation statements
@ -1778,8 +1779,8 @@ nsAnnotationService::CopyPageAnnotations(nsIURI* aSourceURI,
// it gets the names. If this function requires optimization, we should only
// do this once and get the names ourselves using the IDs.
PRInt64 sourceID, destID;
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_FAILURE);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
rv = history->GetUrlIdFor(aSourceURI, &sourceID, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
@ -1964,7 +1965,7 @@ nsAnnotationService::StartGetAnnotationFromItemId(PRInt64 aItemId,
PRBool
nsAnnotationService::InPrivateBrowsingMode() const
{
nsNavHistory* history = nsNavHistory::GetHistoryService();
nsNavHistory *history = nsNavHistory::GetHistoryService();
return history && history->InPrivateBrowsingMode();
}
@ -1973,8 +1974,8 @@ nsresult
nsAnnotationService::GetPlaceIdForURI(nsIURI* aURI, PRInt64* _retval,
PRBool aAutoCreate)
{
nsNavHistory* history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_FAILURE);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
return history->GetUrlIdFor(aURI, _retval, aAutoCreate);
}
@ -2004,7 +2005,7 @@ nsAnnotationService::StartSetAnnotation(PRInt64 aFkId,
// Disallow setting item-annotations on invalid item ids
if (aIsItemAnnotation) {
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_STATE(bookmarks);
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
if (!bookmarks->ItemExists(aFkId))
return NS_ERROR_INVALID_ARG;
}

View File

@ -46,12 +46,21 @@
#include "mozIStorageService.h"
#include "mozIStorageConnection.h"
#include "nsServiceManagerUtils.h"
#include "nsToolkitCompsCID.h"
class nsAnnotationService : public nsIAnnotationService
{
public:
nsAnnotationService();
/**
* Obtains the service's object.
*/
static nsAnnotationService *GetSingleton();
/**
* Initializes the service's object. This should only be called once.
*/
nsresult Init();
static nsresult InitTables(mozIStorageConnection* aDBConn);
@ -60,21 +69,15 @@ public:
* Returns a cached pointer to the annotation service for consumers in the
* places directory.
*/
static nsAnnotationService* GetAnnotationService()
static nsAnnotationService * GetAnnotationService()
{
if (! gAnnotationService) {
// note that we actually have to set the service to a variable here
// because the work in do_GetService actually happens during assignment >:(
nsresult rv;
nsCOMPtr<nsIAnnotationService> serv(do_GetService("@mozilla.org/browser/annotation-service;1", &rv));
NS_ENSURE_SUCCESS(rv, nsnull);
// our constructor should have set the static variable. If it didn't,
// something is wrong.
NS_ASSERTION(gAnnotationService, "Annotation service creation failed");
if (!gAnnotationService) {
nsCOMPtr<nsIAnnotationService> serv =
do_GetService(NS_ANNOTATIONSERVICE_CONTRACTID);
NS_ENSURE_TRUE(serv, nsnull);
NS_ASSERTION(gAnnotationService,
"Should have static instance pointer now");
}
// the service manager will keep the pointer to our service around, so
// this should always be valid even if nobody currently has a reference.
return gAnnotationService;
}
@ -111,7 +114,7 @@ protected:
nsCOMArray<nsIAnnotationObserver> mObservers;
static nsAnnotationService* gAnnotationService;
static nsAnnotationService *gAnnotationService;
static const int kAnnoIndex_ID;
static const int kAnnoIndex_PageOrItem;

View File

@ -66,7 +66,7 @@
#include "nsStringStream.h"
#include "plbase64.h"
#include "nsPlacesTables.h"
#include "nsPlacesTables.h"
#include "nsPlacesMacros.h"
#include "nsIPrefService.h"
#include "Helpers.h"
@ -145,7 +145,7 @@ private:
bool *mFaviconsExpirationRunning;
};
nsFaviconService* nsFaviconService::gFaviconService;
PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsFaviconService, gFaviconService)
NS_IMPL_ISUPPORTS1(
nsFaviconService
@ -173,7 +173,7 @@ GetEffectivePageForFavicon(nsIURI *aPageURI,
nsCOMPtr<nsIURI> pageURI(aPageURI);
nsNavHistory* history = nsNavHistory::GetHistoryService();
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, nsnull);
PRBool canAddToHistory;
@ -325,14 +325,15 @@ nsFaviconService::nsFaviconService() : mFaviconsExpirationRunning(false)
, mOptimizedIconDimension(OPTIMIZED_FAVICON_DIMENSION)
, mFailedFaviconSerial(0)
{
NS_ASSERTION(! gFaviconService, "ATTEMPTING TO CREATE TWO FAVICON SERVICES!");
NS_ASSERTION(!gFaviconService,
"Attempting to create two instances of the service!");
gFaviconService = this;
}
nsFaviconService::~nsFaviconService()
{
NS_ASSERTION(gFaviconService == this, "Deleting a non-singleton favicon service");
NS_ASSERTION(gFaviconService == this,
"Deleting a non-singleton instance of the service");
if (gFaviconService == this)
gFaviconService = nsnull;
}
@ -621,7 +622,7 @@ nsFaviconService::UpdateBookmarkRedirectFavicon(nsIURI* aPageURI,
NS_ENSURE_ARG_POINTER(aFaviconURI);
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
nsCOMPtr<nsIURI> bookmarkURI;
nsresult rv = bookmarks->GetBookmarkedURIFor(aPageURI,
@ -1226,7 +1227,7 @@ FaviconLoadListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
nsresult aStatusCode)
{
nsFaviconService *fs = nsFaviconService::GetFaviconService();
NS_ENSURE_TRUE(fs, NS_ERROR_UNEXPECTED);
NS_ENSURE_TRUE(fs, NS_ERROR_OUT_OF_MEMORY);
if (NS_FAILED(aStatusCode) || mData.Length() == 0) {
// load failed, add to failed cache

View File

@ -44,6 +44,7 @@
#include "mozIStorageConnection.h"
#include "mozIStorageValueArray.h"
#include "mozIStorageStatement.h"
#include "nsToolkitCompsCID.h"
// Favicons bigger than this size should not be saved to the db to avoid
// bloating it with large image blobs.
@ -60,6 +61,15 @@ class nsFaviconService : public nsIFaviconService
{
public:
nsFaviconService();
/**
* Obtains the service's object.
*/
static nsFaviconService * GetSingleton();
/**
* Initializes the service's object. This should only be called once.
*/
nsresult Init();
// called by nsNavHistory::Init
@ -69,21 +79,14 @@ public:
* Returns a cached pointer to the favicon service for consumers in the
* places directory.
*/
static nsFaviconService* GetFaviconService()
static nsFaviconService * GetFaviconService()
{
if (! gFaviconService) {
// note that we actually have to set the service to a variable here
// because the work in do_GetService actually happens during assignment >:(
nsresult rv;
nsCOMPtr<nsIFaviconService> serv(do_GetService("@mozilla.org/browser/favicon-service;1", &rv));
NS_ENSURE_SUCCESS(rv, nsnull);
// our constructor should have set the static variable. If it didn't,
// something is wrong.
NS_ASSERTION(gFaviconService, "Favicon service creation failed");
if (!gFaviconService) {
nsCOMPtr<nsIFaviconService> serv =
do_GetService(NS_FAVICONSERVICE_CONTRACTID);
NS_ENSURE_TRUE(serv, nsnull);
NS_ASSERTION(gFaviconService, "Should have static instance pointer now");
}
// the service manager will keep the pointer to our service around, so
// this should always be valid even if nobody currently has a reference.
return gFaviconService;
}
@ -143,7 +146,7 @@ private:
nsCOMPtr<mozIStorageStatement> mDBUpdateIcon;
nsCOMPtr<mozIStorageStatement> mDBSetPageFavicon;
static nsFaviconService* gFaviconService;
static nsFaviconService *gFaviconService;
/**
* A cached URI for the default icon. We return this a lot, and don't want to

View File

@ -92,7 +92,7 @@ const PRInt32 nsNavBookmarks::kInsertBookmarkIndex_ServiceContractId = 6;
const PRInt32 nsNavBookmarks::kInsertBookmarkIndex_DateAdded = 7;
const PRInt32 nsNavBookmarks::kInsertBookmarkIndex_LastModified = 8;
nsNavBookmarks* nsNavBookmarks::sInstance = nsnull;
PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsNavBookmarks, gBookmarksService)
#define BOOKMARKS_ANNO_PREFIX "bookmarks/"
#define BOOKMARKS_TOOLBAR_FOLDER_ANNO NS_LITERAL_CSTRING(BOOKMARKS_ANNO_PREFIX "toolbarFolder")
@ -109,14 +109,17 @@ nsNavBookmarks::nsNavBookmarks() : mItemCount(0)
, mCanNotify(false)
, mCacheObservers("bookmark-observers")
{
NS_ASSERTION(!sInstance, "Multiple nsNavBookmarks instances!");
sInstance = this;
NS_ASSERTION(!gBookmarksService,
"Attempting to create two instances of the service!");
gBookmarksService = this;
}
nsNavBookmarks::~nsNavBookmarks()
{
NS_ASSERTION(sInstance == this, "Expected sInstance == this");
sInstance = nsnull;
NS_ASSERTION(gBookmarksService == this,
"Deleting a non-singleton instance of the service");
if (gBookmarksService == this)
gBookmarksService = nsnull;
}
NS_IMPL_ISUPPORTS3(nsNavBookmarks,
@ -127,7 +130,7 @@ NS_IMPL_ISUPPORTS3(nsNavBookmarks,
nsresult
nsNavBookmarks::Init()
{
nsNavHistory *history = History();
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
mDBConn = history->GetStorageConnection();
mozStorageTransaction transaction(mDBConn, PR_FALSE);
@ -572,7 +575,9 @@ nsNavBookmarks::InitRoots()
// Set titles for special folders
// We cannot rely on createdPlacesRoot due to Fx3beta->final migration path
PRUint16 databaseStatus = nsINavHistoryService::DATABASE_STATUS_OK;
rv = History()->GetDatabaseStatus(&databaseStatus);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
rv = history->GetDatabaseStatus(&databaseStatus);
if (NS_FAILED(rv) ||
databaseStatus != nsINavHistoryService::DATABASE_STATUS_OK) {
rv = InitDefaults();
@ -590,7 +595,9 @@ nsNavBookmarks::InitRoots()
nsresult
nsNavBookmarks::InitDefaults()
{
nsIStringBundle *bundle = History()->GetBundle();
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
nsIStringBundle *bundle = history->GetBundle();
NS_ENSURE_TRUE(bundle, NS_ERROR_OUT_OF_MEMORY);
// Bookmarks Menu
@ -1127,9 +1134,12 @@ nsNavBookmarks::InsertBookmark(PRInt64 aFolder,
mozStorageTransaction transaction(mDBConn, PR_FALSE);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
// This is really a place ID
PRInt64 childID;
nsresult rv = History()->GetUrlIdFor(aURI, &childID, PR_TRUE);
nsresult rv = history->GetUrlIdFor(aURI, &childID, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 index;
@ -1187,7 +1197,7 @@ nsNavBookmarks::InsertBookmark(PRInt64 aFolder,
// when we created the moz_place entry for the new bookmark
// (a side effect of calling GetUrlIdFor()) frecency -1;
// now we re-calculate the frecency for this moz_place entry.
rv = History()->UpdateFrecency(childID, isBookmark);
rv = history->UpdateFrecency(childID, isBookmark);
NS_ENSURE_SUCCESS(rv, rv);
rv = transaction.Commit();
@ -1196,7 +1206,7 @@ nsNavBookmarks::InsertBookmark(PRInt64 aFolder,
AddBookmarkToHash(childID, 0);
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemAdded(*aNewBookmarkId, aFolder, index, TYPE_BOOKMARK))
OnItemAdded(*aNewBookmarkId, aFolder, index, TYPE_BOOKMARK));
// If the bookmark has been added to a tag container, notify all
// bookmark-folder result nodes which contain a bookmark for the new
@ -1219,7 +1229,7 @@ nsNavBookmarks::InsertBookmark(PRInt64 aFolder,
PR_FALSE,
EmptyCString(),
0,
TYPE_BOOKMARK))
TYPE_BOOKMARK));
}
}
}
@ -1266,7 +1276,7 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId)
}
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnBeforeItemRemoved(aItemId, itemType))
OnBeforeItemRemoved(aItemId, itemType));
mozStorageTransaction transaction(mDBConn, PR_FALSE);
@ -1300,12 +1310,14 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId)
// UpdateFrecency needs to know whether placeId is still bookmarked.
// Although we removed aItemId, placeId may still be bookmarked elsewhere;
// IsRealBookmark will know.
rv = History()->UpdateFrecency(placeId, IsRealBookmark(placeId));
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
rv = history->UpdateFrecency(placeId, IsRealBookmark(placeId));
NS_ENSURE_SUCCESS(rv, rv);
}
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemRemoved(aItemId, folderId, childIndex, itemType))
OnItemRemoved(aItemId, folderId, childIndex, itemType));
if (itemType == TYPE_BOOKMARK) {
// If the removed bookmark was a child of a tag container, notify all
@ -1331,7 +1343,7 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId)
PR_FALSE,
EmptyCString(),
0,
TYPE_BOOKMARK))
TYPE_BOOKMARK));
}
}
}
@ -1440,7 +1452,7 @@ nsNavBookmarks::CreateContainerWithID(PRInt64 aItemId, PRInt64 aParent,
NS_ENSURE_SUCCESS(rv, rv);
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemAdded(*aNewFolder, aParent, index, containerType))
OnItemAdded(*aNewFolder, aParent, index, containerType));
*aIndex = index;
return NS_OK;
@ -1482,7 +1494,7 @@ nsNavBookmarks::InsertSeparator(PRInt64 aParent, PRInt32 aIndex,
NS_ENSURE_SUCCESS(rv, rv);
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemAdded(*aNewItemId, aParent, index, TYPE_SEPARATOR))
OnItemAdded(*aNewItemId, aParent, index, TYPE_SEPARATOR));
return NS_OK;
}
@ -1573,7 +1585,7 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolderId)
NS_ENSURE_TRUE(aFolderId != mRoot, NS_ERROR_INVALID_ARG);
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnBeforeItemRemoved(aFolderId, TYPE_FOLDER))
OnBeforeItemRemoved(aFolderId, TYPE_FOLDER));
mozStorageTransaction transaction(mDBConn, PR_FALSE);
@ -1647,7 +1659,7 @@ nsNavBookmarks::RemoveFolder(PRInt64 aFolderId)
}
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemRemoved(aFolderId, parent, index, TYPE_FOLDER))
OnItemRemoved(aFolderId, parent, index, TYPE_FOLDER));
return NS_OK;
}
@ -1768,7 +1780,7 @@ nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolderId)
// Notify observers that we are about to remove this child.
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnBeforeItemRemoved(child.itemId, child.itemType))
OnBeforeItemRemoved(child.itemId, child.itemType));
if (child.itemType == TYPE_FOLDER) {
foldersToRemove.AppendLiteral(",");
@ -1828,7 +1840,9 @@ nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolderId)
// UpdateFrecency needs to know whether placeId is still bookmarked.
// Although we removed a child of aFolderId that bookmarked it, it may
// still be bookmarked elsewhere; IsRealBookmark will know.
rv = History()->UpdateFrecency(placeId, IsRealBookmark(placeId));
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
rv = history->UpdateFrecency(placeId, IsRealBookmark(placeId));
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -1868,7 +1882,7 @@ nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolderId)
PR_FALSE,
EmptyCString(),
0,
TYPE_BOOKMARK))
TYPE_BOOKMARK));
}
}
}
@ -2029,7 +2043,7 @@ nsNavBookmarks::MoveItem(PRInt64 aItemId, PRInt64 aNewParent, PRInt32 aIndex)
// notify bookmark observers
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemMoved(aItemId, oldParent, oldIndex, aNewParent,
newIndex, itemType))
newIndex, itemType));
// notify dynamic container provider if there is one
if (!folderType.IsEmpty()) {
@ -2428,8 +2442,9 @@ nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
PRInt64 id = mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_ItemId);
nsRefPtr<nsNavHistoryResultNode> node;
if (itemType == TYPE_BOOKMARK) {
rv = History()->RowToResult(mDBGetChildren, options,
getter_AddRefs(node));
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
rv = history->RowToResult(mDBGetChildren, options, getter_AddRefs(node));
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 nodeType;
@ -2509,8 +2524,8 @@ nsNavBookmarks::IsBookmarked(nsIURI *aURI, PRBool *aBookmarked)
NS_ENSURE_ARG(aURI);
NS_ENSURE_ARG_POINTER(aBookmarked);
nsNavHistory* history = History();
NS_ENSURE_TRUE(history, NS_ERROR_UNEXPECTED);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
// convert the URL to an ID
PRInt64 urlID;
@ -2551,8 +2566,8 @@ nsNavBookmarks::GetBookmarkedURIFor(nsIURI* aURI, nsIURI** _retval)
*_retval = nsnull;
nsNavHistory* history = History();
NS_ENSURE_TRUE(history, NS_ERROR_UNEXPECTED);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
// convert the URL to an ID
PRInt64 urlID;
@ -2591,8 +2606,11 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
mozStorageTransaction transaction(mDBConn, PR_FALSE);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
PRInt64 placeId;
nsresult rv = History()->GetUrlIdFor(aNewURI, &placeId, PR_TRUE);
nsresult rv = history->GetUrlIdFor(aNewURI, &placeId, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
if (!placeId)
return NS_ERROR_INVALID_ARG;
@ -2603,7 +2621,7 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
PRInt64 oldPlaceId;
rv = GetBookmarkURI(aBookmarkId, getter_AddRefs(oldURI));
NS_ENSURE_SUCCESS(rv, rv);
rv = History()->GetUrlIdFor(oldURI, &oldPlaceId, PR_FALSE);
rv = history->GetUrlIdFor(oldURI, &oldPlaceId, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIStorageStatement> statement;
@ -2635,7 +2653,7 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
// Upon changing the URI for a bookmark, update the frecency for the new place.
// UpdateFrecency needs to know whether placeId is bookmarked (as opposed
// to a livemark item). Bookmarking it is exactly what we did above.
rv = History()->UpdateFrecency(placeId, PR_TRUE /* isBookmarked */);
rv = history->UpdateFrecency(placeId, PR_TRUE /* isBookmarked */);
NS_ENSURE_SUCCESS(rv, rv);
// Upon changing the URI for a bookmark, update the frecency for the old place.
@ -2645,7 +2663,7 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
// items, i.e., whose parents are not livemarks. If any such bookmarks exist,
// oldPlaceId is still bookmarked.
rv = History()->UpdateFrecency(oldPlaceId, IsRealBookmark(oldPlaceId));
rv = history->UpdateFrecency(oldPlaceId, IsRealBookmark(oldPlaceId));
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString spec;
@ -2655,7 +2673,7 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
// Pass the new URI to OnItemChanged.
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemChanged(aBookmarkId, NS_LITERAL_CSTRING("uri"), PR_FALSE, spec,
lastModified, TYPE_BOOKMARK))
lastModified, TYPE_BOOKMARK));
return NS_OK;
}
@ -2804,7 +2822,7 @@ nsNavBookmarks::SetItemIndex(PRInt64 aItemId, PRInt32 aNewIndex)
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemMoved(aItemId, parent, oldIndex, parent,
aNewIndex, itemType))
aNewIndex, itemType));
return NS_OK;
}
@ -2893,7 +2911,7 @@ nsNavBookmarks::SetKeywordForBookmark(PRInt64 aBookmarkId, const nsAString& aKey
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemChanged(aBookmarkId, NS_LITERAL_CSTRING("keyword"),
PR_FALSE, NS_ConvertUTF16toUTF8(aKeyword),
lastModified, TYPE_BOOKMARK))
lastModified, TYPE_BOOKMARK));
return NS_OK;
}
@ -2981,7 +2999,7 @@ nsNavBookmarks::BeginUpdateBatch()
conn->BeginTransaction();
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnBeginUpdateBatch())
OnBeginUpdateBatch());
}
return NS_OK;
}
@ -2994,7 +3012,7 @@ nsNavBookmarks::EndUpdateBatch()
mDBConn->CommitTransaction();
mBatchHasTransaction = PR_FALSE;
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnEndUpdateBatch())
OnEndUpdateBatch());
}
return NS_OK;
}
@ -3059,7 +3077,7 @@ nsNavBookmarks::OnVisit(nsIURI *aURI, PRInt64 aVisitID, PRTime aTime,
if (bookmarks.Length()) {
for (PRUint32 i = 0; i < bookmarks.Length(); i++)
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavBookmarkObserver,
OnItemVisited(bookmarks[i], aVisitID, aTime))
OnItemVisited(bookmarks[i], aVisitID, aTime));
}
}
return NS_OK;
@ -3092,7 +3110,7 @@ nsNavBookmarks::OnDeleteURI(nsIURI *aURI)
PR_FALSE,
EmptyCString(),
0,
TYPE_BOOKMARK))
TYPE_BOOKMARK));
}
}
return NS_OK;
@ -3128,8 +3146,8 @@ nsNavBookmarks::OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
rv = aURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
nsNavHistory* history = History();
NS_ENSURE_TRUE(history, NS_ERROR_UNEXPECTED);
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
nsCOMArray<nsNavHistoryQuery> queries;
nsCOMPtr<nsNavHistoryQueryOptions> options;

View File

@ -62,19 +62,29 @@ public:
NS_DECL_NSIANNOTATIONOBSERVER
nsNavBookmarks();
/**
* Obtains the service's object.
*/
static nsNavBookmarks *GetSingleton();
/**
* Initializes the service's object. This should only be called once.
*/
nsresult Init();
// called by nsNavHistory::Init
static nsresult InitTables(mozIStorageConnection* aDBConn);
static nsNavBookmarks* GetBookmarksService() {
if (!sInstance) {
nsresult rv;
nsCOMPtr<nsINavBookmarksService> serv(do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, nsnull);
NS_ASSERTION(sInstance, "Should have static instance pointer now");
static nsNavBookmarks * GetBookmarksService() {
if (!gBookmarksService) {
nsCOMPtr<nsINavBookmarksService> serv =
do_GetService(NS_NAVBOOKMARKSSERVICE_CONTRACTID);
NS_ENSURE_TRUE(serv, nsnull);
NS_ASSERTION(gBookmarksService,
"Should have static instance pointer now");
}
return sInstance;
return gBookmarksService;
}
nsresult AddBookmarkToHash(PRInt64 aBookmarkId, PRTime aMinTime);
@ -119,7 +129,7 @@ public:
nsresult FinalizeStatements();
private:
static nsNavBookmarks *sInstance;
static nsNavBookmarks *gBookmarksService;
~nsNavBookmarks();
@ -151,9 +161,6 @@ private:
nsresult GetLastChildId(PRInt64 aFolder, PRInt64* aItemId);
// remove me when there is better query initialization
nsNavHistory* History() { return nsNavHistory::GetHistoryService(); }
nsCOMPtr<mozIStorageConnection> mDBConn;
nsString mGUIDBase;
@ -334,7 +341,7 @@ private:
NS_IMETHOD DoTransaction() {
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = bookmarks->GetParentAndIndexOfFolder(mID, &mParent, &mIndex);
NS_ENSURE_SUCCESS(rv, rv);
@ -351,6 +358,7 @@ private:
NS_IMETHOD UndoTransaction() {
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
PRInt64 newFolder;
return bookmarks->CreateContainerWithID(mID, mParent, mTitle, mType, PR_TRUE,
&mIndex, &newFolder);
@ -385,8 +393,18 @@ private:
struct nsBookmarksUpdateBatcher
{
nsBookmarksUpdateBatcher() { nsNavBookmarks::GetBookmarksService()->BeginUpdateBatch(); }
~nsBookmarksUpdateBatcher() { nsNavBookmarks::GetBookmarksService()->EndUpdateBatch(); }
nsBookmarksUpdateBatcher()
{
nsNavBookmarks *bookmarks = nsNavBookmarks::GetBookmarksService();
if (bookmarks)
bookmarks->BeginUpdateBatch();
}
~nsBookmarksUpdateBatcher()
{
nsNavBookmarks *bookmarks = nsNavBookmarks::GetBookmarksService();
if (bookmarks)
bookmarks->EndUpdateBatch();
}
};

View File

@ -377,25 +377,7 @@ const char nsNavHistory::kAnnotationPreviousEncoding[] = "history/encoding";
// USECS_PER_DAY == PR_USEC_PER_SEC * 60 * 60 * 24;
static const PRInt64 USECS_PER_DAY = LL_INIT(20, 500654080);
nsNavHistory *nsNavHistory::gHistoryService = nsnull;
nsNavHistory *
nsNavHistory::GetSingleton()
{
if (gHistoryService) {
NS_ADDREF(gHistoryService);
return gHistoryService;
}
gHistoryService = new nsNavHistory();
if (gHistoryService) {
NS_ADDREF(gHistoryService);
if (NS_FAILED(gHistoryService->Init()))
NS_RELEASE(gHistoryService);
}
return gHistoryService;
}
PLACES_FACTORY_SINGLETON_IMPLEMENTATION(nsNavHistory, gHistoryService)
// nsNavHistory::nsNavHistory
@ -417,7 +399,8 @@ nsNavHistory::nsNavHistory() : mBatchLevel(0),
mLazyTimerSet = PR_TRUE;
mLazyTimerDeferments = 0;
#endif
NS_ASSERTION(! gHistoryService, "YOU ARE CREATING 2 COPIES OF THE HISTORY SERVICE. Everything will break.");
NS_ASSERTION(!gHistoryService,
"Attempting to create two instances of the service!");
gHistoryService = this;
}
@ -427,8 +410,10 @@ nsNavHistory::~nsNavHistory()
{
// remove the static reference to the service. Check to make sure its us
// in case somebody creates an extra instance of the service.
NS_ASSERTION(gHistoryService == this, "YOU CREATED 2 COPIES OF THE HISTORY SERVICE.");
gHistoryService = nsnull;
NS_ASSERTION(gHistoryService == this,
"Deleting a non-singleton instance of the service");
if (gHistoryService == this)
gHistoryService = nsnull;
}
@ -2769,6 +2754,7 @@ nsNavHistory::AddVisit(nsIURI* aURI, PRTime aTime, nsIURI* aReferringURI,
// Swallow errors here, since if we've gotten this far, it's more
// important to notify the observers below.
nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bs, NS_ERROR_OUT_OF_MEMORY);
(void)UpdateFrecency(pageID, bs->IsRealBookmark(pageID));
// Notify observers: The hidden detection code must match that in
@ -3150,6 +3136,7 @@ nsresult
PlacesSQLQueryBuilder::SelectAsURI()
{
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
nsCAutoString tagsSqlFragment;
switch (mQueryType) {
@ -3304,6 +3291,7 @@ nsresult
PlacesSQLQueryBuilder::SelectAsVisit()
{
nsNavHistory *history = nsNavHistory::GetHistoryService();
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
nsCAutoString tagsSqlFragment;
GetTagsSqlFragment(history->GetTagsFolder(),
NS_LITERAL_CSTRING("h.id"),
@ -4212,7 +4200,7 @@ nsNavHistory::BeginUpdateBatch()
mDBConn->BeginTransaction();
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavHistoryObserver,
OnBeginUpdateBatch())
OnBeginUpdateBatch());
}
return NS_OK;
}
@ -4226,7 +4214,7 @@ nsNavHistory::EndUpdateBatch()
mDBConn->CommitTransaction();
mBatchHasTransaction = PR_FALSE;
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavHistoryObserver,
OnEndUpdateBatch())
OnEndUpdateBatch());
}
return NS_OK;
}
@ -4544,7 +4532,7 @@ nsNavHistory::RemovePage(nsIURI *aURI)
// Before we remove, we have to notify our observers!
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
nsINavHistoryObserver, OnBeforeDeleteURI(aURI))
nsINavHistoryObserver, OnBeforeDeleteURI(aURI));
nsIURI** URIs = &aURI;
nsresult rv = RemovePages(URIs, 1, PR_FALSE);
@ -4552,7 +4540,7 @@ nsNavHistory::RemovePage(nsIURI *aURI)
// Notify our observers that the URI has been removed.
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
nsINavHistoryObserver, OnDeleteURI(aURI))
nsINavHistoryObserver, OnDeleteURI(aURI));
return NS_OK;
}
@ -5460,7 +5448,7 @@ nsNavHistory::NotifyOnPageExpired(nsIURI *aURI, PRTime aVisitTime,
if (aWholeEntry) {
// Notify our observers that the URI has been removed.
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers,
nsINavHistoryObserver, OnDeleteURI(aURI))
nsINavHistoryObserver, OnDeleteURI(aURI));
}
return NS_OK;
@ -7017,7 +7005,7 @@ nsNavHistory::SetPageTitleInternal(nsIURI* aURI, const nsAString& aTitle)
// observers (have to check first if it's bookmarked)
ENUMERATE_OBSERVERS(mCanNotify, mCacheObservers, mObservers, nsINavHistoryObserver,
OnTitleChanged(aURI, aTitle))
OnTitleChanged(aURI, aTitle));
return NS_OK;
}
@ -7653,6 +7641,7 @@ nsNavHistory::CalculateFrecency(PRInt64 aPlaceId,
// place: queries from showing up in the URL bar autocomplete results
if (!IsQueryURI(aURL) && aPlaceId != -1) {
nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bs, NS_ERROR_OUT_OF_MEMORY);
isBookmark = bs->IsRealBookmark(aPlaceId);
}
@ -7698,8 +7687,11 @@ nsNavHistory::FixInvalidFrecencies()
invalidFrecencies->GetUTF8String(4, url);
PRBool isBook = PR_FALSE;
if (!IsQueryURI(url))
isBook = nsNavBookmarks::GetBookmarksService()-> IsRealBookmark(placeId);
if (!IsQueryURI(url)) {
nsNavBookmarks *bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
isBook = bookmarks->IsRealBookmark(placeId);
}
rv = UpdateFrecencyInternal(placeId, typed, hidden, oldFrecency, isBook);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -59,6 +59,7 @@
#include "nsCategoryCache.h"
#include "nsICharsetResolver.h"
#include "nsNetCID.h"
#include "nsToolkitCompsCID.h"
#include "nsINavBookmarksService.h"
#include "nsIPrivateBrowsingService.h"
@ -128,7 +129,7 @@ public:
/**
* Obtains the nsNavHistory object.
*/
static nsNavHistory *GetSingleton();
static nsNavHistory * GetSingleton();
/**
* Initializes the nsNavHistory object. This should only be called once.
@ -140,15 +141,14 @@ public:
* service to get a reference to this history object. Returns a pointer to
* the service if it exists. Otherwise creates one. Returns NULL on error.
*/
static nsNavHistory* GetHistoryService()
static nsNavHistory * GetHistoryService()
{
if (gHistoryService)
return gHistoryService;
nsCOMPtr<nsINavHistoryService> serv =
do_GetService("@mozilla.org/browser/nav-history-service;1");
NS_ENSURE_TRUE(serv, nsnull);
if (!gHistoryService) {
nsCOMPtr<nsINavHistoryService> serv =
do_GetService(NS_NAVHISTORYSERVICE_CONTRACTID);
NS_ENSURE_TRUE(serv, nsnull);
NS_ASSERTION(gHistoryService, "Should have static instance pointer now");
}
return gHistoryService;
}
@ -373,7 +373,7 @@ public:
~nsNavHistory();
// used by GetHistoryService
static nsNavHistory* gHistoryService;
static nsNavHistory *gHistoryService;
protected:

View File

@ -261,7 +261,7 @@ nsNavHistoryExpire::ClearHistory()
ENUMERATE_OBSERVERS(mHistory->canNotify(), mHistory->mCacheObservers,
mHistory->mObservers, nsINavHistoryObserver,
OnClearHistory())
OnClearHistory());
return NS_OK;
}

View File

@ -48,3 +48,22 @@
ENUMERATE_WEAKARRAY(array, type, method) \
} \
PR_END_MACRO;
#define PLACES_FACTORY_SINGLETON_IMPLEMENTATION(_className, _sInstance) \
_className * _className::_sInstance = nsnull; \
\
_className * \
_className::GetSingleton() \
{ \
if (_sInstance) { \
NS_ADDREF(_sInstance); \
return _sInstance; \
} \
_sInstance = new _className(); \
if (_sInstance) { \
NS_ADDREF(_sInstance); \
if (NS_FAILED(_sInstance->Init())) \
NS_RELEASE(_sInstance); \
} \
return _sInstance; \
}

View File

@ -13,15 +13,20 @@
NS_CI_INTERFACE_GETTER_NAME(nsNavHistory), \
nsnull, \
&NS_CLASSINFO_NAME(nsNavHistory), \
nsIClassInfo::SINGLETON | nsIClassInfo::THREADSAFE
nsIClassInfo::SINGLETON
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsNavHistory,
nsNavHistory::GetSingleton)
NS_DECL_CLASSINFO(nsNavHistory)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsAnnotationService,
nsAnnotationService::GetSingleton)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsNavBookmarks,
nsNavBookmarks::GetSingleton)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsFaviconService,
nsFaviconService::GetSingleton)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAnnoProtocolHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAnnotationService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsNavBookmarks, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFaviconService, Init)
static const nsModuleComponentInfo components[] =
{
@ -33,7 +38,7 @@ static const nsModuleComponentInfo components[] =
{ "Browser Navigation History",
NS_NAVHISTORYSERVICE_CID,
"@mozilla.org/browser/global-history;2",
NS_GLOBALHISTORY2_CONTRACTID,
nsNavHistoryConstructor,
NS_NAVHISTORY_CLASSINFO },