mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 478718 - Move last Places sync to xpcom-shutdown, r=sdwilsh
--HG-- rename : toolkit/components/places/tests/sync/test_database_sync_after_quit_application.js => toolkit/components/places/tests/sync/test_database_sync_after_shutdown.js rename : toolkit/components/places/tests/sync/test_database_sync_after_quit_application_with_removeAllPages.js => toolkit/components/places/tests/sync/test_database_sync_after_shutdown_with_removeAllPages.js
This commit is contained in:
parent
3103bee835
commit
9679a4ea34
@ -78,7 +78,6 @@ const BrowserGlueServiceFactory = {
|
||||
// Constructor
|
||||
|
||||
function BrowserGlue() {
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "_prefs",
|
||||
"@mozilla.org/preferences-service;1",
|
||||
"nsIPrefBranch");
|
||||
@ -91,14 +90,24 @@ function BrowserGlue() {
|
||||
"@mozilla.org/widget/idleservice;1",
|
||||
"nsIIdleService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "_observerService",
|
||||
"@mozilla.org/observer-service;1",
|
||||
"nsIObserverService");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_distributionCustomizer", function() {
|
||||
return new DistributionCustomizer();
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_sanitizer",
|
||||
function() {
|
||||
let sanitizerScope = {};
|
||||
Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
getService(Ci.mozIJSSubScriptLoader).
|
||||
loadSubScript("chrome://browser/content/sanitize.js", sanitizerScope);
|
||||
return sanitizerScope.Sanitizer;
|
||||
});
|
||||
|
||||
// The observer service is immediately used in _init(), so there's no reason
|
||||
// to have a getter.
|
||||
this._observerService = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
|
||||
this._init();
|
||||
}
|
||||
|
||||
@ -109,15 +118,17 @@ function BrowserGlue() {
|
||||
#endif
|
||||
|
||||
BrowserGlue.prototype = {
|
||||
|
||||
_saveSession: false,
|
||||
_isIdleObserver: false,
|
||||
_isPlacesInitObserver: false,
|
||||
_isPlacesLockedObserver: false,
|
||||
_isPlacesDatabaseLocked: false,
|
||||
|
||||
_setPrefToSaveSession: function()
|
||||
_setPrefToSaveSession: function(aForce)
|
||||
{
|
||||
if (!this._saveSession && !aForce)
|
||||
return;
|
||||
|
||||
this._prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
|
||||
|
||||
// This method can be called via [NSApplication terminate:] on Mac, which
|
||||
@ -153,12 +164,9 @@ BrowserGlue.prototype = {
|
||||
this._onQuitRequest(subject, data);
|
||||
break;
|
||||
case "quit-application-granted":
|
||||
if (this._saveSession) {
|
||||
this._setPrefToSaveSession();
|
||||
}
|
||||
// Everything that uses Places during shutdown should be here, since
|
||||
// on quit-application Places database connection will be closed
|
||||
// and history synchronization could fail.
|
||||
// This pref must be set here because SessionStore will use its value
|
||||
// on quit-application.
|
||||
this._setPrefToSaveSession();
|
||||
this._onProfileShutdown();
|
||||
break;
|
||||
#ifdef OBSERVE_LASTWINDOW_CLOSE_TOPICS
|
||||
@ -168,12 +176,11 @@ BrowserGlue.prototype = {
|
||||
this._onQuitRequest(subject, "lastwindow");
|
||||
break;
|
||||
case "browser-lastwindow-close-granted":
|
||||
if (this._saveSession)
|
||||
this._setPrefToSaveSession();
|
||||
this._setPrefToSaveSession();
|
||||
break;
|
||||
#endif
|
||||
case "session-save":
|
||||
this._setPrefToSaveSession();
|
||||
this._setPrefToSaveSession(true);
|
||||
subject.QueryInterface(Ci.nsISupportsPRBool);
|
||||
subject.data = true;
|
||||
break;
|
||||
@ -191,8 +198,8 @@ BrowserGlue.prototype = {
|
||||
break;
|
||||
case "places-database-locked":
|
||||
this._isPlacesDatabaseLocked = true;
|
||||
// stop observing, so further attempts to load history service
|
||||
// do not show the prompt.
|
||||
// Stop observing, so further attempts to load history service
|
||||
// will not show the prompt.
|
||||
this._observerService.removeObserver(this, "places-database-locked");
|
||||
this._isPlacesLockedObserver = false;
|
||||
break;
|
||||
@ -268,7 +275,7 @@ BrowserGlue.prototype = {
|
||||
// profile startup handler (contains profile initialization routines)
|
||||
_onProfileStartup: function()
|
||||
{
|
||||
this.Sanitizer.onStartup();
|
||||
this._sanitizer.onStartup();
|
||||
// check if we're in safe mode
|
||||
var app = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).
|
||||
QueryInterface(Ci.nsIXULRuntime);
|
||||
@ -302,7 +309,8 @@ BrowserGlue.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
this._observerService.notifyObservers(null, "browser-ui-startup-complete", "");
|
||||
this._observerService
|
||||
.notifyObservers(null, "browser-ui-startup-complete", "");
|
||||
},
|
||||
|
||||
// profile shutdown handler (contains profile cleanup routines)
|
||||
@ -311,7 +319,7 @@ BrowserGlue.prototype = {
|
||||
this._shutdownPlaces();
|
||||
this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
|
||||
this._isIdleObserver = false;
|
||||
this.Sanitizer.onShutdown();
|
||||
this._sanitizer.onShutdown();
|
||||
},
|
||||
|
||||
// Browser startup complete. All initial windows have opened.
|
||||
@ -572,17 +580,6 @@ BrowserGlue.prototype = {
|
||||
browser.selectedTab = browser.addTab(updateUrl);
|
||||
},
|
||||
|
||||
// returns the (cached) Sanitizer constructor
|
||||
get Sanitizer()
|
||||
{
|
||||
if(typeof(Sanitizer) != "function") { // we should dynamically load the script
|
||||
Cc["@mozilla.org/moz/jssubscript-loader;1"].
|
||||
getService(Ci.mozIJSSubScriptLoader).
|
||||
loadSubScript("chrome://browser/content/sanitize.js", null);
|
||||
}
|
||||
return Sanitizer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize Places
|
||||
* - imports the bookmarks html file if bookmarks database is empty, try to
|
||||
@ -907,7 +904,7 @@ BrowserGlue.prototype = {
|
||||
|
||||
sanitize: function(aParentWindow)
|
||||
{
|
||||
this.Sanitizer.sanitize(aParentWindow);
|
||||
this._sanitizer.sanitize(aParentWindow);
|
||||
},
|
||||
|
||||
ensurePlacesDefaultQueriesInitialized: function() {
|
||||
@ -921,7 +918,7 @@ BrowserGlue.prototype = {
|
||||
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
|
||||
const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
|
||||
|
||||
// XXX should this be a pref? see bug #399268
|
||||
// TODO bug 399268: should this be a pref?
|
||||
const MAX_RESULTS = 10;
|
||||
|
||||
// get current smart bookmarks version
|
||||
|
@ -1,65 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dietrich Ayala <dietrich@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// put cleanup of the bookmarks test here.
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
flush_main_thread_events();
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
var os = Cc['@mozilla.org/observer-service;1'].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop, since we enqueue some statement finalization.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
if (pip.DBConnection.connectionReady) {
|
||||
pip.commitPendingChanges();
|
||||
pip.finalizeInternalStatements();
|
||||
pip.DBConnection.close();
|
||||
do_check_false(pip.DBConnection.connectionReady);
|
||||
}
|
@ -205,15 +205,16 @@ tests.push({
|
||||
do_check_false(ps.getBoolPref(PREF_RESTORE_DEFAULT_BOOKMARKS));
|
||||
do_check_false(ps.getBoolPref(PREF_IMPORT_BOOKMARKS_HTML));
|
||||
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
});
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
function finish_test() {
|
||||
// Simulate application closing to remove the idle observer and avoid leaks.
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
// Clean up database from all bookmarks.
|
||||
remove_all_bookmarks();
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
@ -222,16 +223,13 @@ function next_test() {
|
||||
// Clean up database from all bookmarks.
|
||||
remove_all_bookmarks();
|
||||
|
||||
// Simulate application closing to remove the idle observer and avoid leaks.
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
|
||||
// nsBrowserGlue stops observing topics after first notification,
|
||||
// so we add back the observer to test additional runs.
|
||||
os.addObserver(bg, TOPIC_PLACES_INIT_COMPLETE, false);
|
||||
|
||||
// Execute next test.
|
||||
let test = tests.shift();
|
||||
dump("\nTEST " + (++testIndex) + ": " + test.description);
|
||||
print("\nTEST " + (++testIndex) + ": " + test.description);
|
||||
test.exec();
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ tests.push({
|
||||
do_check_eq(profileBookmarksJSONFile.lastModifiedTime, lastMod);
|
||||
do_check_eq(profileBookmarksJSONFile.fileSize, fileSize);
|
||||
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -564,7 +564,6 @@ function test_cache_cleared()
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
os.removeObserver(observer, "cacheservice:empty-cache");
|
||||
shutdownPlaces();
|
||||
do_test_finished();
|
||||
}
|
||||
};
|
||||
|
@ -155,6 +155,4 @@ function do_test()
|
||||
// And check our data
|
||||
for (let i = 0; i < data.length; i++)
|
||||
check_active_download(data[i].source, !data[i].removed);
|
||||
|
||||
shutdownPlaces();
|
||||
}
|
||||
|
@ -110,15 +110,6 @@ function cleanUp()
|
||||
}
|
||||
cleanUp();
|
||||
|
||||
/**
|
||||
* Finalize Places statements during quit-application in order to prevent leaks
|
||||
*/
|
||||
function shutdownPlaces() {
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
}
|
||||
|
||||
var PRIVATEBROWSING_CONTRACT_ID;
|
||||
function run_test_on_all_services() {
|
||||
var contractIDs = [
|
||||
|
@ -40,11 +40,11 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Using Places services on quit-application or later is not reliable, so make
|
||||
* sure to do shutdown work on quit-application-granted, or history
|
||||
* Using Places services after quit-application is not reliable, so make
|
||||
* sure to do any shutdown work on quit-application, or history
|
||||
* synchronization could fail, losing latest changes.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsIArray.idl"
|
||||
#include "nsIURI.idl"
|
||||
|
@ -46,24 +46,11 @@ interface mozIStorageConnection;
|
||||
* database. If outside consumers wish to use this, they should only read from
|
||||
* the database so they do not break any internal invariants.
|
||||
*/
|
||||
[scriptable, uuid(8e6d4f8a-4b8e-4026-9fca-517c4494ddb7)]
|
||||
[scriptable, uuid(5fd91813-229c-4d30-851b-700afa39a987)]
|
||||
interface nsPIPlacesDatabase : nsISupports
|
||||
{
|
||||
/**
|
||||
* The database connection used by Places.
|
||||
*/
|
||||
readonly attribute mozIStorageConnection DBConnection;
|
||||
|
||||
/**
|
||||
* Finalizes all Places internal statements, allowing to safely close the
|
||||
* database connection.
|
||||
*/
|
||||
void finalizeInternalStatements();
|
||||
|
||||
/**
|
||||
* Commits all pending history changes, call this before finalizing
|
||||
* statements and closing the database connection to ensure safety for all
|
||||
* history data.
|
||||
*/
|
||||
void commitPendingChanges();
|
||||
};
|
||||
|
@ -380,7 +380,6 @@ const PRInt32 nsNavHistory::kGetInfoIndex_ItemParentId = 11;
|
||||
const PRInt32 nsNavHistory::kGetInfoIndex_ItemTags = 12;
|
||||
|
||||
|
||||
static const char* gQuitApplicationGrantedMessage = "quit-application-granted";
|
||||
static const char* gXpcomShutdown = "xpcom-shutdown";
|
||||
static const char* gAutoCompleteFeedback = "autocomplete-will-enter-text";
|
||||
static const char* gIdleDaily = "idle-daily";
|
||||
@ -547,7 +546,6 @@ nsNavHistory::Init()
|
||||
pbi->AddObserver(PREF_BROWSER_HISTORY_EXPIRE_SITES, this, PR_FALSE);
|
||||
}
|
||||
|
||||
observerService->AddObserver(this, gQuitApplicationGrantedMessage, PR_FALSE);
|
||||
observerService->AddObserver(this, gXpcomShutdown, PR_FALSE);
|
||||
observerService->AddObserver(this, gAutoCompleteFeedback, PR_FALSE);
|
||||
observerService->AddObserver(this, gIdleDaily, PR_FALSE);
|
||||
@ -4862,18 +4860,11 @@ nsNavHistory::RemoveAllPages()
|
||||
// expire everything
|
||||
mExpire->ClearHistory();
|
||||
|
||||
// Compress DB. Currently commented out because compression is very slow.
|
||||
// Deleted data will be overwritten with 0s by sqlite.
|
||||
#if 0
|
||||
nsresult rv = mDBConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING("VACUUM"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
#endif
|
||||
|
||||
// privacy cleanup, if there's an old history.dat around, just delete it
|
||||
nsCOMPtr<nsIFile> oldHistoryFile;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_APP_HISTORY_50_FILE,
|
||||
getter_AddRefs(oldHistoryFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool fileExists;
|
||||
if (NS_SUCCEEDED(oldHistoryFile->Exists(&fileExists)) && fileExists) {
|
||||
@ -5499,22 +5490,11 @@ nsNavHistory::GetDBConnection(mozIStorageConnection **_DBConnection)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
NS_HIDDEN_(nsresult)
|
||||
nsNavHistory::FinalizeInternalStatements()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
|
||||
|
||||
#ifdef LAZY_ADD
|
||||
// Kill lazy timer or it could fire later when statements won't be valid
|
||||
// anymore.
|
||||
// At this point we should have called CommitPendingChanges before the last
|
||||
// sync, so all data is saved to disk and we can finalize all statements.
|
||||
if (mLazyTimer)
|
||||
mLazyTimer->Cancel();
|
||||
NS_ABORT_IF_FALSE(mLazyMessages.Length() == 0,
|
||||
"There are pending lazy messages, did you call CommitPendingChanges()?");
|
||||
#endif
|
||||
|
||||
// nsNavHistory
|
||||
nsresult rv = FinalizeStatements();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -5540,36 +5520,6 @@ nsNavHistory::FinalizeInternalStatements()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNavHistory::CommitPendingChanges()
|
||||
{
|
||||
#ifdef LAZY_ADD
|
||||
CommitLazyMessages();
|
||||
#endif
|
||||
|
||||
// Immediately serve topics we generated, this way they won't try to access
|
||||
// the database after CommitPendingChanges has been called.
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
NS_ENSURE_TRUE(os, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
nsresult rv = os->EnumerateObservers(PLACES_INIT_COMPLETE_TOPIC,
|
||||
getter_AddRefs(e));
|
||||
if (NS_SUCCEEDED(rv) && e) {
|
||||
nsCOMPtr<nsIObserver> observer;
|
||||
PRBool loop = PR_TRUE;
|
||||
while(NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop)
|
||||
{
|
||||
e->GetNext(getter_AddRefs(observer));
|
||||
rv = observer->Observe(observer,
|
||||
PLACES_INIT_COMPLETE_TOPIC,
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsPIPlacesHistoryListenersNotifier ******************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -5595,25 +5545,67 @@ nsNavHistory::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "This can only be called on the main thread");
|
||||
|
||||
if (strcmp(aTopic, gQuitApplicationGrantedMessage) == 0) {
|
||||
nsresult rv;
|
||||
if (strcmp(aTopic, gXpcomShutdown) == 0) {
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
if (os) {
|
||||
os->RemoveObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC);
|
||||
os->RemoveObserver(this, gIdleDaily);
|
||||
os->RemoveObserver(this, gXpcomShutdown);
|
||||
}
|
||||
|
||||
// If xpcom-shutdown is called in the same scope as the service init, we
|
||||
// should Immediately serve topics we generated, this way they won't try to
|
||||
// access the database later.
|
||||
nsCOMPtr<nsISimpleEnumerator> e;
|
||||
nsresult rv = os->EnumerateObservers(PLACES_INIT_COMPLETE_TOPIC,
|
||||
getter_AddRefs(e));
|
||||
if (NS_SUCCEEDED(rv) && e) {
|
||||
nsCOMPtr<nsIObserver> observer;
|
||||
PRBool loop = PR_TRUE;
|
||||
while(NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop)
|
||||
{
|
||||
e->GetNext(getter_AddRefs(observer));
|
||||
rv = observer->Observe(observer,
|
||||
PLACES_INIT_COMPLETE_TOPIC,
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrefService> prefService =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (prefService)
|
||||
prefService->SavePrefFile(nsnull);
|
||||
|
||||
// Start shutdown expiration.
|
||||
mExpire->OnQuit();
|
||||
}
|
||||
else if (strcmp(aTopic, gXpcomShutdown) == 0) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
|
||||
#ifdef LAZY_ADD
|
||||
// Commit all pending lazy messages.
|
||||
CommitLazyMessages(PR_TRUE);
|
||||
|
||||
// Kill lazy timer or it could fire later when statements won't be valid
|
||||
// anymore.
|
||||
if (mLazyTimer) {
|
||||
mLazyTimer->Cancel();
|
||||
mLazyTimer = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Finalize all statements.
|
||||
rv = FinalizeInternalStatements();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
observerService->RemoveObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC);
|
||||
observerService->RemoveObserver(this, gIdleDaily);
|
||||
observerService->RemoveObserver(this, gXpcomShutdown);
|
||||
observerService->RemoveObserver(this, gQuitApplicationGrantedMessage);
|
||||
|
||||
// Remove categories.
|
||||
nsCOMPtr<nsICategoryManager> catMan =
|
||||
do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
||||
if (catMan) {
|
||||
(void)catMan->DeleteCategory("bookmark-observers");
|
||||
(void)catMan->DeleteCategory("history-observers");
|
||||
}
|
||||
|
||||
// NOTE: We don't close the connection because the sync service could still
|
||||
// need it for a final flush.
|
||||
}
|
||||
#ifdef MOZ_XUL
|
||||
else if (strcmp(aTopic, gAutoCompleteFeedback) == 0) {
|
||||
@ -5927,8 +5919,8 @@ nsNavHistory::LazyTimerCallback(nsITimer* aTimer, void* aClosure)
|
||||
|
||||
// nsNavHistory::CommitLazyMessages
|
||||
|
||||
void
|
||||
nsNavHistory::CommitLazyMessages()
|
||||
NS_HIDDEN_(void)
|
||||
nsNavHistory::CommitLazyMessages(PRBool aIsShutdown)
|
||||
{
|
||||
mozStorageTransaction transaction(mDBConn, PR_TRUE);
|
||||
for (PRUint32 i = 0; i < mLazyMessages.Length(); i ++) {
|
||||
@ -5942,6 +5934,9 @@ nsNavHistory::CommitLazyMessages()
|
||||
SetPageTitleInternal(message.uri, message.title);
|
||||
break;
|
||||
case LazyMessage::Type_Favicon: {
|
||||
// Favicons cannot use async channels after xpcom-shutdown.
|
||||
if (aIsShutdown)
|
||||
continue;
|
||||
nsFaviconService* faviconService = nsFaviconService::GetFaviconService();
|
||||
if (faviconService) {
|
||||
faviconService->DoSetAndLoadFaviconForPage(message.uri,
|
||||
@ -8082,7 +8077,7 @@ nsNavHistory::GetDBBookmarkToUrlResult()
|
||||
return mDBBookmarkToUrlResult;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_HIDDEN_(nsresult)
|
||||
nsNavHistory::FinalizeStatements() {
|
||||
mozIStorageStatement* stmts[] = {
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -433,7 +433,7 @@ protected:
|
||||
/**
|
||||
* Finalize all internal statements.
|
||||
*/
|
||||
nsresult FinalizeStatements();
|
||||
NS_HIDDEN_(nsresult) FinalizeStatements();
|
||||
|
||||
/**
|
||||
* Analyzes the database and VACUUM it, if needed.
|
||||
@ -444,6 +444,12 @@ protected:
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) VacuumDatabase();
|
||||
|
||||
/**
|
||||
* Finalizes all Places internal statements, allowing to safely close the
|
||||
* database connection.
|
||||
*/
|
||||
NS_HIDDEN_(nsresult) FinalizeInternalStatements();
|
||||
|
||||
// nsICharsetResolver
|
||||
NS_DECL_NSICHARSETRESOLVER
|
||||
|
||||
@ -580,7 +586,7 @@ protected:
|
||||
nsresult StartLazyTimer();
|
||||
nsresult AddLazyMessage(const LazyMessage& aMessage);
|
||||
static void LazyTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||
void CommitLazyMessages();
|
||||
NS_HIDDEN_(void) CommitLazyMessages(PRBool aIsShutdown = PR_FALSE);
|
||||
#endif
|
||||
|
||||
nsresult ConstructQueryString(const nsCOMArray<nsNavHistoryQuery>& aQueries,
|
||||
|
@ -72,7 +72,7 @@ const kBookTagSQLFragment =
|
||||
book_tag_sql_fragment("tags", "GROUP_CONCAT(t.title, ',')", true);
|
||||
|
||||
// observer topics
|
||||
const kQuitApplication = "quit-application";
|
||||
const kXPComShutdown = "xpcom-shutdown";
|
||||
const kPrefChanged = "nsPref:changed";
|
||||
|
||||
// Match type constants. These indicate what type of search function we should
|
||||
@ -364,7 +364,7 @@ function nsPlacesAutoComplete()
|
||||
// register observers
|
||||
this._os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
this._os.addObserver(this, kQuitApplication, false);
|
||||
this._os.addObserver(this, kXPComShutdown, false);
|
||||
|
||||
}
|
||||
|
||||
@ -504,8 +504,8 @@ nsPlacesAutoComplete.prototype = {
|
||||
|
||||
observe: function PAC_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == kQuitApplication) {
|
||||
this._os.removeObserver(this, kQuitApplication);
|
||||
if (aTopic == kXPComShutdown) {
|
||||
this._os.removeObserver(this, kXPComShutdown);
|
||||
|
||||
// Remove our preference observer.
|
||||
this._prefs.removeObserver("", this);
|
||||
|
@ -48,7 +48,7 @@ const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const kQuitApplication = "quit-application";
|
||||
const kXPComShutdown = "xpcom-shutdown";
|
||||
const kSyncFinished = "places-sync-finished";
|
||||
const kDebugStopSync = "places-debug-stop-sync";
|
||||
const kDebugStartSync = "places-debug-start-sync";
|
||||
@ -109,7 +109,7 @@ function nsPlacesDBFlush()
|
||||
// Register observers
|
||||
this._os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
this._os.addObserver(this, kQuitApplication, false);
|
||||
this._os.addObserver(this, kXPComShutdown, false);
|
||||
this._os.addObserver(this, kDebugStopSync, false);
|
||||
this._os.addObserver(this, kDebugStartSync, false);
|
||||
|
||||
@ -149,8 +149,8 @@ nsPlacesDBFlush.prototype = {
|
||||
|
||||
observe: function DBFlush_observe(aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == kQuitApplication) {
|
||||
this._os.removeObserver(this, kQuitApplication);
|
||||
if (aTopic == kXPComShutdown) {
|
||||
this._os.removeObserver(this, kXPComShutdown);
|
||||
this._os.removeObserver(this, kDebugStopSync);
|
||||
this._os.removeObserver(this, kDebugStartSync);
|
||||
|
||||
@ -158,29 +158,41 @@ nsPlacesDBFlush.prototype = {
|
||||
pb2.removeObserver(kSyncPrefName, this);
|
||||
pb2.removeObserver(kExpireDaysPrefName, this);
|
||||
}
|
||||
this._timer.cancel();
|
||||
this._timer = null;
|
||||
|
||||
if (this._timer) {
|
||||
this._timer.cancel();
|
||||
this._timer = null;
|
||||
}
|
||||
|
||||
// Other components could still make changes to history at this point,
|
||||
// for example to clear private data on shutdown, so here we dispatch
|
||||
// an event to the main thread so that we will sync after
|
||||
// quit-application ensuring all data have been saved.
|
||||
// xpcom-shutdown ensuring all data have been saved.
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].
|
||||
getService(Ci.nsIThreadManager);
|
||||
tm.mainThread.dispatch({
|
||||
_self: this,
|
||||
run: function() {
|
||||
let pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase);
|
||||
pip.commitPendingChanges();
|
||||
// Flush any remaining change to disk tables.
|
||||
this._self._flushWithQueries([kQuerySyncPlacesId, kQuerySyncHistoryVisitsId]);
|
||||
|
||||
// Ensure we won't act anymore as a category observer, so we stop
|
||||
// being notified.
|
||||
let catMan = Cc["@mozilla.org/categorymanager;1"].
|
||||
getService(Ci.nsICategoryManager);
|
||||
catMan.deleteCategoryEntry("bookmark-observers",
|
||||
this._self.classDescription,
|
||||
true);
|
||||
catMan.deleteCategoryEntry("history-observers",
|
||||
this._self.classDescription,
|
||||
true);
|
||||
|
||||
// Close the database connection, this was the last sync and we can't
|
||||
// ensure database coherence from now on.
|
||||
pip.finalizeInternalStatements();
|
||||
this._self._finalizeInternalStatements();
|
||||
this._self._db.close();
|
||||
}
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
|
||||
}
|
||||
else if (aTopic == "nsPref:changed" && aData == kSyncPrefName) {
|
||||
// Get the new pref value, and then update our timer
|
||||
|
@ -1,65 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// put cleanup of the bookmarks test here.
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
flush_main_thread_events();
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
var os = Cc['@mozilla.org/observer-service;1'].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop, since we enqueue some statement finalization.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
if (pip.DBConnection.connectionReady) {
|
||||
pip.commitPendingChanges();
|
||||
pip.finalizeInternalStatements();
|
||||
pip.DBConnection.close();
|
||||
do_check_false(pip.DBConnection.connectionReady);
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dietrich Ayala <dietrich@mozilla.com>
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// put cleanup of the bookmarks test here.
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
flush_main_thread_events();
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
var os = Cc['@mozilla.org/observer-service;1'].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop, since we enqueue some statement finalization.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
if (pip.DBConnection.connectionReady) {
|
||||
pip.commitPendingChanges();
|
||||
pip.finalizeInternalStatements();
|
||||
pip.DBConnection.close();
|
||||
do_check_false(pip.DBConnection.connectionReady);
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// put cleanup of the bookmarks test here.
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
var os = Cc['@mozilla.org/observer-service;1'].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
if (pip.DBConnection.connectionReady) {
|
||||
pip.commitPendingChanges();
|
||||
pip.finalizeInternalStatements();
|
||||
pip.DBConnection.close();
|
||||
do_check_false(pip.DBConnection.connectionReady);
|
||||
}
|
@ -154,23 +154,10 @@ function dump_table(aName)
|
||||
stmt = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This dispatches the observer topic "quit-application" to clean up the sync
|
||||
* component.
|
||||
*/
|
||||
function finish_test()
|
||||
{
|
||||
// xpcshell doesn't dispatch shutdown-application
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function tests to see if the place associated with the bookmark with id
|
||||
* aBookmarkId has the uri aExpectedURI. The event will call finish_test() if
|
||||
* aFinish is true.
|
||||
* aBookmarkId has the uri aExpectedURI. The event will call do_test_finished()
|
||||
* if aFinish is true.
|
||||
*
|
||||
* @param aBookmarkId
|
||||
* The bookmark to check against.
|
||||
@ -204,12 +191,12 @@ function new_test_bookmark_uri_event(aBookmarkId, aExpectedURI, aExpected, aFini
|
||||
stmt = null;
|
||||
|
||||
if (aFinish)
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function tests to see if the place associated with the visit with id aVisitId
|
||||
* has the uri aExpectedURI. The event will call finish_test() if aFinish is
|
||||
* has the uri aExpectedURI. The event will call do_test_finished() if aFinish is
|
||||
* true.
|
||||
*
|
||||
* @param aVisitId
|
||||
@ -244,7 +231,7 @@ function new_test_visit_uri_event(aVisitId, aExpectedURI, aExpected, aFinish)
|
||||
stmt = null;
|
||||
|
||||
if (aFinish)
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,3 +268,14 @@ function flush_main_thread_events()
|
||||
while (tm.mainThread.hasPendingEvents())
|
||||
tm.mainThread.processNextEvent(false);
|
||||
}
|
||||
|
||||
// Simulates a Places shutdown.
|
||||
function shutdownPlaces()
|
||||
{
|
||||
const TOPIC_XPCOM_SHUTDOWN = "xpcom-shutdown";
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsIObserver);
|
||||
hs.observe(null, TOPIC_XPCOM_SHUTDOWN, null);
|
||||
let sync = Cc["@mozilla.org/places/sync;1"].getService(Ci.nsIObserver);
|
||||
sync.observe(null, TOPIC_XPCOM_SHUTDOWN, null);
|
||||
}
|
||||
|
@ -1,65 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2009
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// put cleanup of the bookmarks test here.
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
flush_main_thread_events();
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
var os = Cc['@mozilla.org/observer-service;1'].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop, since we enqueue some statement finalization.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
if (pip.DBConnection.connectionReady) {
|
||||
pip.commitPendingChanges();
|
||||
pip.finalizeInternalStatements();
|
||||
pip.DBConnection.close();
|
||||
do_check_false(pip.DBConnection.connectionReady);
|
||||
}
|
@ -87,7 +87,7 @@ var observer = {
|
||||
|
||||
// Cleanup.
|
||||
bs.removeFolderChildren(bs.toolbarFolder);
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ var historyObserver = {
|
||||
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
|
||||
aTransitionType, aAdded) {
|
||||
observer.visitId = aVisitId;
|
||||
hs.removeObserver(this);
|
||||
}
|
||||
}
|
||||
hs.addObserver(historyObserver, false);
|
||||
@ -64,11 +65,11 @@ var observer = {
|
||||
visitId: -1,
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == kSyncFinished) {
|
||||
// visit id must be valid
|
||||
do_check_neq(this.visitId, -1);
|
||||
// remove the observer, we don't need to observe sync on quit
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
hs.removeObserver(historyObserver);
|
||||
|
||||
// visit id must be valid
|
||||
do_check_neq(this.visitId, -1);
|
||||
// Check that tables have been correctly synced
|
||||
new_test_visit_uri_event(this.visitId, TEST_URI, true, true);
|
||||
}
|
||||
@ -87,7 +88,8 @@ function run_test()
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
|
||||
// Notify that we are quitting the app - we should sync!
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
shutdownPlaces();
|
||||
|
||||
// Test will continue on sync notification.
|
||||
do_test_pending();
|
||||
}
|
@ -45,90 +45,113 @@ var prefs = Cc["@mozilla.org/preferences-service;1"].
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var bh = hs.QueryInterface(Ci.nsIBrowserHistory);
|
||||
var mDBConn = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
|
||||
let bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
var bs = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
|
||||
const TEST_URI = "http://test.com/";
|
||||
|
||||
const kSyncPrefName = "syncDBTableIntervalInSecs";
|
||||
const PREF_SYNC_INTERVAL = "syncDBTableIntervalInSecs";
|
||||
const SYNC_INTERVAL = 600; // ten minutes
|
||||
const kSyncFinished = "places-sync-finished";
|
||||
const kQuitApplication = "quit-application";
|
||||
const TOPIC_SYNC_FINISHED = "places-sync-finished";
|
||||
|
||||
// Polling constants to check the connection closed status.
|
||||
const POLLING_TIMEOUT_MS = 100;
|
||||
const POLLING_MAX_PASSES = 20;
|
||||
|
||||
var historyObserver = {
|
||||
visitId: -1,
|
||||
cleared: false,
|
||||
onVisit: function(aURI, aVisitId, aTime, aSessionId, aReferringId,
|
||||
aTransitionType, aAdded) {
|
||||
observer.visitId = aVisitId;
|
||||
this.visitId = aVisitId;
|
||||
},
|
||||
onClearHistory: function() {
|
||||
// check browserHistory returns no entries
|
||||
do_check_eq(0, bh.count);
|
||||
this.cleared = true;
|
||||
hs.removeObserver(this);
|
||||
}
|
||||
}
|
||||
hs.addObserver(historyObserver, false);
|
||||
|
||||
var observer = {
|
||||
visitId: -1,
|
||||
_runCount: 0,
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == kSyncFinished) {
|
||||
// the first sync is due to the insert bookmark, timings here are really
|
||||
// constraint, so it's better adding the observer immediately and discard
|
||||
// first notification. Adding the observer later could result in random
|
||||
// test failures due to the first sync being delayed.
|
||||
if (++this._runCount < 2)
|
||||
if (aTopic == TOPIC_SYNC_FINISHED) {
|
||||
if (++this._runCount == 1) {
|
||||
// The first sync is due to the insert bookmark.
|
||||
// Simulate a clear private data just before shutdown.
|
||||
bh.removeAllPages();
|
||||
// Immediately notify shutdown.
|
||||
shutdownPlaces();
|
||||
return;
|
||||
// visit id must be valid
|
||||
do_check_neq(this.visitId, -1);
|
||||
// remove the observer, we don't need to observe sync on quit
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
hs.removeObserver(historyObserver);
|
||||
// Check that tables have been correctly synced
|
||||
// Check that frecency for not cleared items (bookmarks) has been converted
|
||||
// to -MAX(visit_count, 1), so we will be able to recalculate frecency
|
||||
// starting from most frecent bookmarks.
|
||||
dump_table("moz_places_temp");
|
||||
dump_table("moz_places");
|
||||
stmt = mDBConn.createStatement(
|
||||
"SELECT id FROM moz_places WHERE frecency > 0 LIMIT 1");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
}
|
||||
|
||||
stmt = mDBConn.createStatement(
|
||||
"SELECT h.id FROM moz_places h WHERE h.frecency = -2 " +
|
||||
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
|
||||
do_check_true(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
// Remove the observer, we don't need it anymore.
|
||||
os.removeObserver(this, TOPIC_SYNC_FINISHED);
|
||||
|
||||
// Check that all visit_counts have been brought to 0
|
||||
stmt = mDBConn.createStatement(
|
||||
"SELECT id FROM moz_places WHERE visit_count <> 0 LIMIT 1");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
// Visit id must be valid.
|
||||
do_check_neq(historyObserver.visitId, -1);
|
||||
// History must have been cleared.
|
||||
do_check_true(historyObserver.cleared);
|
||||
|
||||
finish_test();
|
||||
}
|
||||
else if (aTopic == kQuitApplication) {
|
||||
// simulate a clear private data on shutdown
|
||||
bh.removeAllPages();
|
||||
// The database connection will be closed after this sync, but we can't
|
||||
// know how much time it will take, so we use a polling strategy.
|
||||
do_timeout(POLLING_TIMEOUT_MS, "check_results();");
|
||||
}
|
||||
}
|
||||
}
|
||||
os.addObserver(observer, kSyncFinished, false);
|
||||
os.addObserver(observer, kQuitApplication, false);
|
||||
os.addObserver(observer, TOPIC_SYNC_FINISHED, false);
|
||||
|
||||
var gPasses = 0;
|
||||
function check_results() {
|
||||
if (++gPasses >= POLLING_MAX_PASSES) {
|
||||
do_throw("Maximum time elapsdes waiting for Places database connection to close");
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
if (hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection.connectionReady) {
|
||||
do_timeout(POLLING_TIMEOUT_MS, "check_results();");
|
||||
return;
|
||||
}
|
||||
|
||||
dbConn = DBConn();
|
||||
do_check_neq(dbConn, null);
|
||||
do_check_true(dbConn.connectionReady);
|
||||
|
||||
// Check that frecency for not cleared items (bookmarks) has been
|
||||
// converted to -MAX(visit_count, 1), so we will be able to
|
||||
// recalculate frecency starting from most frecent bookmarks.
|
||||
let stmt = dbConn.createStatement(
|
||||
"SELECT id FROM moz_places WHERE frecency > 0 LIMIT 1");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
stmt = DBConn().createStatement(
|
||||
"SELECT h.id FROM moz_places h WHERE h.frecency = -2 " +
|
||||
"AND EXISTS (SELECT id FROM moz_bookmarks WHERE fk = h.id) LIMIT 1");
|
||||
do_check_true(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
// Check that all visit_counts have been brought to 0
|
||||
stmt = DBConn().createStatement(
|
||||
"SELECT id FROM moz_places WHERE visit_count <> 0 LIMIT 1");
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
dbConn.close();
|
||||
do_check_false(dbConn.connectionReady);
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
|
||||
while (tm.mainThread.hasPendingEvents())
|
||||
tm.mainThread.processNextEvent(false);
|
||||
do_test_pending();
|
||||
|
||||
// Set the preference for the timer to a really large value, so it won't
|
||||
// run before the test finishes.
|
||||
prefs.setIntPref(kSyncPrefName, SYNC_INTERVAL);
|
||||
prefs.setIntPref(PREF_SYNC_INTERVAL, SYNC_INTERVAL);
|
||||
|
||||
// Now add a visit before creating bookmark, and one later
|
||||
hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
@ -137,9 +160,4 @@ function run_test()
|
||||
bs.DEFAULT_INDEX, "bookmark");
|
||||
hs.addVisit(uri(TEST_URI), Date.now() * 1000, null,
|
||||
hs.TRANSITION_TYPED, false, 0);
|
||||
|
||||
// Notify that we are quitting the app - we should sync!
|
||||
os.notifyObservers(null, kQuitApplication, null);
|
||||
|
||||
do_test_pending();
|
||||
}
|
@ -132,7 +132,7 @@ var observer = {
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ var observer = {
|
||||
|
||||
stmt.finalize();
|
||||
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ var syncObserver = {
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
bs.removeObserver(bookmarksObserver, false);
|
||||
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ var observer = {
|
||||
root.containerOpen = false;
|
||||
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ var observer = {
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
bs.removeObserver(bookmarksObserver);
|
||||
// test ends here
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
else
|
||||
do_throw("Too many places sync calls");
|
||||
|
@ -110,7 +110,7 @@ var observer = {
|
||||
// remove the observers
|
||||
os.removeObserver(this, kSyncFinished);
|
||||
hs.removeObserver(historyObserver, false);
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
else
|
||||
do_throw("bad runCount!");
|
||||
|
@ -177,26 +177,6 @@ function check_no_bookmarks() {
|
||||
root.containerOpen = false;
|
||||
}
|
||||
|
||||
var syncSvc = null;
|
||||
function start_sync() {
|
||||
// profile-after-change doesn't create components in xpcshell, so we have to do
|
||||
// it ourselves
|
||||
syncSvc = Cc["@mozilla.org/places/sync;1"].getService(Ci.nsISupports);
|
||||
}
|
||||
|
||||
/**
|
||||
* This dispatches the observer topic "quit-application" to clean up the sync
|
||||
* component.
|
||||
*/
|
||||
function finish_test()
|
||||
{
|
||||
// xpcshell doesn't dispatch shutdown-application
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes any events in the event loop of the main thread.
|
||||
*/
|
||||
|
@ -1,66 +0,0 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla.org
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dietrich Ayala <dietrich@mozilla.com>
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// put cleanup of the bookmarks test here.
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
flush_main_thread_events();
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
var os = Cc['@mozilla.org/observer-service;1'].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop, since we enqueue some statement finalization.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
if (pip.DBConnection.connectionReady) {
|
||||
pip.commitPendingChanges();
|
||||
pip.finalizeInternalStatements();
|
||||
pip.DBConnection.close();
|
||||
do_check_false(pip.DBConnection.connectionReady);
|
||||
}
|
@ -102,13 +102,13 @@ function get_PBSvc() {
|
||||
* @returns the place id for aURI.
|
||||
*/
|
||||
function add_visit(aURI, aType) {
|
||||
var placeID = histsvc.addVisit(uri(aURI),
|
||||
var visitId = histsvc.addVisit(uri(aURI),
|
||||
Date.now() * 1000,
|
||||
null, // no referrer
|
||||
aType,
|
||||
false, // not redirect
|
||||
0);
|
||||
return placeID;
|
||||
return visitId;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -266,13 +266,10 @@ function is_bookmark_A_altered(){
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
||||
// Fetch the private browsing service
|
||||
var pb = get_PBSvc();
|
||||
|
||||
if(pb) { // Private Browsing might not be available
|
||||
start_sync(); // enable syncing
|
||||
|
||||
if (pb) { // Private Browsing might not be available
|
||||
// need to catch places sync notifications
|
||||
var os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
@ -293,7 +290,7 @@ function run_test() {
|
||||
|
||||
// Bookmark-A should be bookmarked, data should be retrievable
|
||||
do_check_true(bmsvc.isBookmarked(bookmark_A_URI));
|
||||
do_check_eq("google",bmsvc.getKeywordForURI(bookmark_A_URI));
|
||||
do_check_eq("google", bmsvc.getKeywordForURI(bookmark_A_URI));
|
||||
|
||||
// Enter Private Browsing Mode
|
||||
pb.privateBrowsingEnabled = true;
|
||||
@ -355,7 +352,7 @@ function run_test() {
|
||||
}
|
||||
|
||||
prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -39,9 +39,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// execute this test while syncing, this will potentially show possible problems
|
||||
start_sync();
|
||||
|
||||
// Get services
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
@ -827,5 +824,5 @@ function checkExpireBadPrefs() {
|
||||
do_throw(ex);
|
||||
}
|
||||
dump("done incremental expiration test 6\n");
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
|
@ -37,9 +37,6 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Enable syncing for this test
|
||||
start_sync();
|
||||
|
||||
// Get services.
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
@ -224,7 +221,7 @@ let syncObserver = {
|
||||
do_check_false(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
|
||||
finish_test();
|
||||
do_test_finished();
|
||||
}
|
||||
}
|
||||
os.addObserver(syncObserver, kSyncFinished, false);
|
||||
|
@ -1,75 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places Unit Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77bonardo.net> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var pip = hs.QueryInterface(Ci.nsPIPlacesDatabase);
|
||||
var mDBConn = pip.DBConnection;
|
||||
var gh = hs.QueryInterface(Ci.nsIGlobalHistory2);
|
||||
var iconsvc = Cc["@mozilla.org/browser/favicon-service;1"].
|
||||
getService(Ci.nsIFaviconService);
|
||||
|
||||
const TEST_URI = "http://www.mozilla.org/";
|
||||
const TEST_TITLE = "testTitle";
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var testURI = uri(TEST_URI);
|
||||
var faviconURI = uri(TEST_URI + "favicon.ico");
|
||||
|
||||
// Add a uri lazy message
|
||||
gh.addURI(testURI, false, true, null);
|
||||
// Add a favicon lazy message
|
||||
iconsvc.setFaviconUrlForPage(testURI, faviconURI);
|
||||
// Add a title lazy message
|
||||
hs.setPageTitle(testURI, TEST_TITLE);
|
||||
|
||||
// Commit all pending changes (lazy messages)
|
||||
pip.commitPendingChanges();
|
||||
|
||||
// Check database values, we can't use APIs because them would check
|
||||
// lazy queue.
|
||||
let stmt = mDBConn.createStatement(
|
||||
"SELECT id FROM moz_places_temp WHERE url = :url AND title = :title " +
|
||||
"AND favicon_id = (SELECT id FROM moz_favicons WHERE url = :favicon_url)");
|
||||
stmt.params["url"] = testURI.spec;
|
||||
stmt.params["title"] = TEST_TITLE;
|
||||
stmt.params["favicon_url"] = faviconURI.spec;
|
||||
do_check_true(stmt.executeStep());
|
||||
stmt.finalize();
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Places Unit Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Corp.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Marco Bonardo <mak77bonardo.net> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// main
|
||||
function run_test() {
|
||||
var hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
|
||||
// Run the event loop to be more like the browser, which normally runs the
|
||||
// event loop long before code like this would run.
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
|
||||
while (tm.mainThread.hasPendingEvents())
|
||||
tm.mainThread.processNextEvent(false);
|
||||
|
||||
var mDBConn = hs.QueryInterface(Ci.nsPIPlacesDatabase).DBConnection;
|
||||
|
||||
hs.QueryInterface(Ci.nsPIPlacesDatabase).finalizeInternalStatements();
|
||||
mDBConn.close();
|
||||
do_check_false(mDBConn.connectionReady);
|
||||
}
|
Loading…
Reference in New Issue
Block a user