author | Ganesh Chaitanya Kale <ganesh2583@gmail.com> |
Tue, 20 Mar 2018 12:36:31 +0000 | |
changeset 409577 | 82e4db446286ad1a387bc7ee3feeeadbaa9d0887 |
parent 409576 | bcd284a1f312f79c4d3866975a6fcaaf17006664 |
child 409578 | 426e9698be8dd576382c04ffeed489ba3cf4e1df |
push id | 101247 |
push user | nerli@mozilla.com |
push date | Thu, 22 Mar 2018 23:00:51 +0000 |
treeherder | mozilla-inbound@02e384bdf97d [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mak |
bugs | 1282770 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/components/migration/AutoMigrate.jsm +++ b/browser/components/migration/AutoMigrate.jsm @@ -605,27 +605,29 @@ const AutoMigrate = { this._errorMap.logins++; } } } } }, async _removeSomeVisits(visits) { + // It is necessary to recreate URL and date objects because the data + // can be serialized through JSON that destroys those objects. for (let urlVisits of visits) { let urlObj; try { urlObj = new URL(urlVisits.url); } catch (ex) { continue; } let visitData = { url: urlObj, - beginDate: PlacesUtils.toDate(urlVisits.first), - endDate: PlacesUtils.toDate(urlVisits.last), + beginDate: new Date(urlVisits.first), + endDate: new Date(urlVisits.last), limit: urlVisits.visitCount, }; try { await PlacesUtils.history.removeVisitsByFilter(visitData); } catch (ex) { this._errorMap.visits++; try { visitData.url = visitData.url.href;
--- a/browser/components/migration/ChromeProfileMigrator.js +++ b/browser/components/migration/ChromeProfileMigrator.js @@ -268,53 +268,39 @@ async function GetHistoryResource(aProfi query += " AND last_visit_time > " + maxAge; } if (LIMIT) { query += " ORDER BY last_visit_time DESC LIMIT " + LIMIT; } let rows = await MigrationUtils.getRowsFromDBWithoutLocks(historyPath, "Chrome history", query); - let places = []; + let pageInfos = []; for (let row of rows) { try { // if having typed_count, we changes transition type to typed. - let transType = PlacesUtils.history.TRANSITION_LINK; + let transition = PlacesUtils.history.TRANSITIONS.LINK; if (row.getResultByName("typed_count") > 0) - transType = PlacesUtils.history.TRANSITION_TYPED; + transition = PlacesUtils.history.TRANSITIONS.TYPED; - places.push({ - uri: NetUtil.newURI(row.getResultByName("url")), + pageInfos.push({ title: row.getResultByName("title"), + url: new URL(row.getResultByName("url")), visits: [{ - transitionType: transType, - visitDate: chromeTimeToDate( - row.getResultByName( - "last_visit_time")) * 1000, + transition, + date: chromeTimeToDate(row.getResultByName("last_visit_time")), }], }); } catch (e) { Cu.reportError(e); } } - if (places.length > 0) { - await new Promise((resolve, reject) => { - MigrationUtils.insertVisitsWrapper(places, { - ignoreErrors: true, - ignoreResults: true, - handleCompletion(updatedCount) { - if (updatedCount > 0) { - resolve(); - } else { - reject(new Error("Couldn't add visits")); - } - }, - }); - }); + if (pageInfos.length > 0) { + await MigrationUtils.insertVisitsWrapper(pageInfos); } })().then(() => { aCallback(true); }, ex => { Cu.reportError(ex); aCallback(false); }); }, };
--- a/browser/components/migration/EdgeProfileMigrator.js +++ b/browser/components/migration/EdgeProfileMigrator.js @@ -104,52 +104,46 @@ EdgeTypedURLMigrator.prototype = { }, get exists() { return this._typedURLs.size > 0; }, migrate(aCallback) { let typedURLs = this._typedURLs; - let places = []; + let pageInfos = []; for (let [urlString, time] of typedURLs) { - let uri; + let url; try { - uri = Services.io.newURI(urlString); - if (!["http", "https", "ftp"].includes(uri.scheme)) { + url = new URL(urlString); + if (!["http", "https", "ftp"].includes(url.scheme)) { continue; } } catch (ex) { Cu.reportError(ex); continue; } - // Note that the time will be in microseconds (PRTime), - // and Date.now() returns milliseconds. Places expects PRTime, - // so we multiply the Date.now return value to make up the difference. - let visitDate = time || (Date.now() * 1000); - places.push({ - uri, - visits: [{ transitionType: Ci.nsINavHistoryService.TRANSITION_TYPED, - visitDate}], + pageInfos.push({ + url, + visits: [{ + transition: PlacesUtils.history.TRANSITIONS.TYPED, + date: time ? PlacesUtils.toDate(time) : new Date(), + }], }); } - if (places.length == 0) { + if (pageInfos.length == 0) { aCallback(typedURLs.size == 0); return; } - MigrationUtils.insertVisitsWrapper(places, { - ignoreErrors: true, - ignoreResults: true, - handleCompletion(updatedCount) { - aCallback(updatedCount > 0); - }, - }); + MigrationUtils.insertVisitsWrapper(pageInfos).then( + () => aCallback(true), + () => aCallback(false)); }, }; function EdgeReadingListMigrator(dbOverride) { this.dbOverride = dbOverride; } EdgeReadingListMigrator.prototype = {
--- a/browser/components/migration/IEProfileMigrator.js +++ b/browser/components/migration/IEProfileMigrator.js @@ -33,68 +33,62 @@ function History() { History.prototype = { type: MigrationUtils.resourceTypes.HISTORY, get exists() { return true; }, migrate: function H_migrate(aCallback) { - let places = []; + let pageInfos = []; let typedURLs = MSMigrationUtils.getTypedURLs("Software\\Microsoft\\Internet Explorer"); let historyEnumerator = Cc["@mozilla.org/profile/migrator/iehistoryenumerator;1"]. createInstance(Ci.nsISimpleEnumerator); while (historyEnumerator.hasMoreElements()) { let entry = historyEnumerator.getNext().QueryInterface(Ci.nsIPropertyBag2); - let uri = entry.get("uri").QueryInterface(Ci.nsIURI); + let url = entry.get("uri").QueryInterface(Ci.nsIURI); // MSIE stores some types of URLs in its history that we don't handle, // like HTMLHelp and others. Since we don't properly map handling for // all of them we just avoid importing them. - if (!["http", "https", "ftp", "file"].includes(uri.scheme)) { + if (!["http", "https", "ftp", "file"].includes(url.scheme)) { continue; } let title = entry.get("title"); // Embed visits have no title and don't need to be imported. if (title.length == 0) { continue; } // The typed urls are already fixed-up, so we can use them for comparison. - let transitionType = typedURLs.has(uri.spec) ? - Ci.nsINavHistoryService.TRANSITION_TYPED : - Ci.nsINavHistoryService.TRANSITION_LINK; + let transition = typedURLs.has(url.spec) ? + PlacesUtils.history.TRANSITIONS.LINK : + PlacesUtils.history.TRANSITIONS.TYPED; // use the current date if we have no visits for this entry. - // Note that the entry will have a time in microseconds (PRTime), - // and Date.now() returns milliseconds. Places expects PRTime, - // so we multiply the Date.now return value to make up the difference. - let lastVisitTime = entry.get("time") || (Date.now() * 1000); + let time = entry.get("time"); - places.push( - { uri, - title, - visits: [{ transitionType, - visitDate: lastVisitTime }], - } - ); + pageInfos.push({ + url, + title, + visits: [{ + transition, + date: time ? PlacesUtils.toDate(entry.get("time")) : new Date(), + }], + }); } // Check whether there is any history to import. - if (places.length == 0) { + if (pageInfos.length == 0) { aCallback(true); return; } - MigrationUtils.insertVisitsWrapper(places, { - ignoreErrors: true, - ignoreResults: true, - handleCompletion(updatedCount) { - aCallback(updatedCount > 0); - }, - }); + MigrationUtils.insertVisitsWrapper(pageInfos).then( + () => aCallback(true), + () => aCallback(false)); }, }; // IE form password migrator supporting windows from XP until 7 and IE from 7 until 11 function IE7FormPasswords() { // used to distinguish between this migrator and other passwords migrators in tests. this.name = "IE7FormPasswords"; }
--- a/browser/components/migration/MigrationUtils.jsm +++ b/browser/components/migration/MigrationUtils.jsm @@ -1037,22 +1037,22 @@ var MigrationUtils = Object.freeze({ for (let bm of insertedItems) { let {parentGuid, guid, lastModified, type} = bm; bmData.push({parentGuid, guid, lastModified, type}); } } }, ex => Cu.reportError(ex)); }, - insertVisitsWrapper(places, options) { - this._importQuantities.history += places.length; + insertVisitsWrapper(pageInfos) { + this._importQuantities.history += pageInfos.length; if (gKeepUndoData) { - this._updateHistoryUndo(places); + this._updateHistoryUndo(pageInfos); } - return PlacesUtils.asyncHistory.updatePlaces(places, options, true); + return PlacesUtils.history.insertMany(pageInfos); }, async insertLoginsWrapper(logins) { this._importQuantities.logins += logins.length; let inserted = await LoginHelper.maybeImportLogins(logins); // Note that this means that if we import a login that has a newer password // than we know about, we will update the login, and an undo of the import // will not revert this. This seems preferable over removing the login @@ -1096,30 +1096,36 @@ var MigrationUtils = Object.freeze({ stopAndRetrieveUndoData() { let undoData = gUndoData; gUndoData = null; gKeepUndoData = false; return this._postProcessUndoData(undoData); }, - _updateHistoryUndo(places) { + _updateHistoryUndo(pageInfos) { let visits = gUndoData.get("visits"); let visitMap = new Map(visits.map(v => [v.url, v])); - for (let place of places) { - let visitCount = place.visits.length; + for (let pageInfo of pageInfos) { + let visitCount = pageInfo.visits.length; let first, last; if (visitCount > 1) { - let visitDates = place.visits.map(v => v.visitDate); - first = Math.min.apply(Math, visitDates); - last = Math.max.apply(Math, visitDates); + let dates = pageInfo.visits.map(v => v.date); + first = Math.min.apply(Math, dates); + last = Math.max.apply(Math, dates); } else { - first = last = place.visits[0].visitDate; + first = last = pageInfo.visits[0].date; } - let url = place.uri.spec; + let url = pageInfo.url; + if (url instanceof Ci.nsIURI) { + url = pageInfo.url.spec; + } else if (typeof url != "string") { + pageInfo.url.href; + } + try { new URL(url); } catch (ex) { // This won't save and we won't need to 'undo' it, so ignore this URL. continue; } if (!visitMap.has(url)) { visitMap.set(url, {url, visitCount, first, last});
--- a/browser/components/migration/SafariProfileMigrator.js +++ b/browser/components/migration/SafariProfileMigrator.js @@ -12,18 +12,16 @@ ChromeUtils.import("resource://gre/modul ChromeUtils.import("resource:///modules/MigrationUtils.jsm"); ChromeUtils.defineModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm"); ChromeUtils.defineModuleGetter(this, "PropertyListUtils", "resource://gre/modules/PropertyListUtils.jsm"); ChromeUtils.defineModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm"); -ChromeUtils.defineModuleGetter(this, "NetUtil", - "resource://gre/modules/NetUtil.jsm"); ChromeUtils.defineModuleGetter(this, "FormHistory", "resource://gre/modules/FormHistory.jsm"); Cu.importGlobalProperties(["URL"]); function Bookmarks(aBookmarksFile) { this._file = aBookmarksFile; } @@ -188,61 +186,65 @@ History.prototype = { // The visit date is stored as a string, so it's not read as a Date // object by PropertyListUtils. _parseCocoaDate: function H___parseCocoaDate(aCocoaDateStr) { let asDouble = parseFloat(aCocoaDateStr); if (!isNaN(asDouble)) { // reference date of NSDate. let date = new Date("1 January 2001, GMT"); date.setMilliseconds(asDouble * 1000); - return date * 1000; + return date; } - return 0; + return new Date(); }, migrate: function H_migrate(aCallback) { PropertyListUtils.read(this._file, aDict => { try { if (!aDict) throw new Error("Could not read history property list"); if (!aDict.has("WebHistoryDates")) throw new Error("Unexpected history-property list format"); - // Safari's History file contains only top-level urls. It does not - // distinguish between typed urls and linked urls. - let transType = PlacesUtils.history.TRANSITION_LINK; - - let places = []; + let pageInfos = []; let entries = aDict.get("WebHistoryDates"); + let failedOnce = false; for (let entry of entries) { if (entry.has("lastVisitedDate")) { - let visitDate = this._parseCocoaDate(entry.get("lastVisitedDate")); + let date = this._parseCocoaDate(entry.get("lastVisitedDate")); try { - places.push({ uri: NetUtil.newURI(entry.get("")), - title: entry.get("title"), - visits: [{ transitionType: transType, - visitDate }] }); + pageInfos.push({ + url: new URL(entry.get("")), + title: entry.get("title"), + visits: [{ + // Safari's History file contains only top-level urls. It does not + // distinguish between typed urls and linked urls. + transition: PlacesUtils.history.TRANSITIONS.LINK, + date, + }], + }); } catch (ex) { // Safari's History file may contain malformed URIs which // will be ignored. Cu.reportError(ex); + failedOnce = true; } } } - if (places.length > 0) { - MigrationUtils.insertVisitsWrapper(places, { - ignoreErrors: true, - ignoreResults: true, - handleCompletion(updatedCount) { - aCallback(updatedCount > 0); - }, - }); - } else { - aCallback(false); + if (pageInfos.length == 0) { + // If we failed at least once, then we didn't succeed in importing, + // otherwise we didn't actually have anything to import, so we'll + // report it as a success. + aCallback(!failedOnce); + return; } + + MigrationUtils.insertVisitsWrapper(pageInfos).then( + () => aCallback(true), + () => aCallback(false)); } catch (ex) { Cu.reportError(ex); aCallback(false); } }); }, };
--- a/browser/components/migration/tests/unit/test_automigration.js +++ b/browser/components/migration/tests/unit/test_automigration.js @@ -1,16 +1,16 @@ "use strict"; ChromeUtils.import("resource:///modules/AutoMigrate.jsm", this); let gShimmedMigratorKeyPicker = null; let gShimmedMigrator = null; -const kUsecPerMin = 60 * 1000000; +const kMsecPerMin = 60 * 1000; // This is really a proxy on MigrationUtils, but if we specify that directly, // we get in trouble because the object itself is frozen, and Proxies can't // return a different value to an object when directly proxying a frozen // object. let AutoMigrateBackstage = ChromeUtils.import("resource:///modules/AutoMigrate.jsm", {}); AutoMigrateBackstage.MigrationUtils = new Proxy({}, { @@ -256,37 +256,37 @@ add_task(async function checkUndoRemoval title: "Some example bookmark", }); let bookmark = await PlacesUtils.bookmarks.fetch({url: "http://www.example.org/"}); Assert.ok(bookmark, "Should have a bookmark before undo"); Assert.equal(bookmark.title, "Some example bookmark", "Should have correct bookmark before undo."); // Insert 2 history visits - let now_uSec = Date.now() * 1000; + let now = new Date(); let visitedURI = Services.io.newURI("http://www.example.com/"); let frecencyUpdatePromise = new Promise(resolve => { let observer = { onManyFrecenciesChanged() { PlacesUtils.history.removeObserver(observer); resolve(); }, }; PlacesUtils.history.addObserver(observer); }); await MigrationUtils.insertVisitsWrapper([{ - uri: visitedURI, + url: visitedURI, visits: [ { - transitionType: PlacesUtils.history.TRANSITION_LINK, - visitDate: now_uSec, + transition: PlacesUtils.history.TRANSITION_LINK, + date: now, }, { - transitionType: PlacesUtils.history.TRANSITION_LINK, - visitDate: now_uSec - 100 * kUsecPerMin, + transition: PlacesUtils.history.TRANSITION_LINK, + date: new Date(now - 100 * kMsecPerMin), }, ], }]); await frecencyUpdatePromise; // Verify that both visits get reported. let opts = PlacesUtils.history.getNewQueryOptions(); opts.resultType = opts.RESULTS_AS_VISIT; @@ -491,103 +491,103 @@ add_task(async function testLoginsRemova Assert.equal(1, LoginHelper.searchLoginsWithObject({hostname: "https://example.org", formSubmitURL: "https://example.org/"}).length, "changed example.org entry should have persisted."); Services.logins.removeAllLogins(); }); add_task(async function checkUndoVisitsState() { MigrationUtils.initializeUndoData(); await MigrationUtils.insertVisitsWrapper([{ - uri: NetUtil.newURI("http://www.example.com/"), + url: NetUtil.newURI("http://www.example.com/"), title: "Example", visits: [{ - visitDate: new Date("2015-07-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-07-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }, { - visitDate: new Date("2015-09-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-09-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }, { - visitDate: new Date("2015-08-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-08-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }, { - uri: NetUtil.newURI("http://www.example.org/"), + url: Services.io.newURI("http://www.example.org/"), title: "Example", visits: [{ - visitDate: new Date("2016-04-03").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2016-04-03"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }, { - visitDate: new Date("2015-08-03").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-08-03"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }, { - uri: NetUtil.newURI("http://www.example.com/"), + url: "http://www.example.com/", title: "Example", visits: [{ - visitDate: new Date("2015-10-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-10-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }]); let undoVisitData = (await MigrationUtils.stopAndRetrieveUndoData()).get("visits"); Assert.deepEqual(Array.from(undoVisitData.map(v => v.url)).sort(), ["http://www.example.com/", "http://www.example.org/"]); Assert.deepEqual(undoVisitData.find(v => v.url == "http://www.example.com/"), { url: "http://www.example.com/", visitCount: 4, - first: new Date("2015-07-10").getTime() * 1000, - last: new Date("2015-10-10").getTime() * 1000, + first: new Date("2015-07-10").getTime(), + last: new Date("2015-10-10").getTime(), }); Assert.deepEqual(undoVisitData.find(v => v.url == "http://www.example.org/"), { url: "http://www.example.org/", visitCount: 2, - first: new Date("2015-08-03").getTime() * 1000, - last: new Date("2016-04-03").getTime() * 1000, + first: new Date("2015-08-03").getTime(), + last: new Date("2016-04-03").getTime(), }); await PlacesUtils.history.clear(); }); add_task(async function checkUndoVisitsState() { MigrationUtils.initializeUndoData(); await MigrationUtils.insertVisitsWrapper([{ - uri: NetUtil.newURI("http://www.example.com/"), + url: NetUtil.newURI("http://www.example.com/"), title: "Example", visits: [{ - visitDate: new Date("2015-07-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-07-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }, { - visitDate: new Date("2015-09-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-09-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }, { - visitDate: new Date("2015-08-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-08-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }, { - uri: NetUtil.newURI("http://www.example.org/"), + url: NetUtil.newURI("http://www.example.org/"), title: "Example", visits: [{ - visitDate: new Date("2016-04-03").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2016-04-03"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }, { - visitDate: new Date("2015-08-03").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-08-03"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }, { - uri: NetUtil.newURI("http://www.example.com/"), + url: NetUtil.newURI("http://www.example.com/"), title: "Example", visits: [{ - visitDate: new Date("2015-10-10").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-10-10"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }, { - uri: NetUtil.newURI("http://www.mozilla.org/"), + url: NetUtil.newURI("http://www.mozilla.org/"), title: "Example", visits: [{ - visitDate: new Date("2015-01-01").getTime() * 1000, - transitionType: Ci.nsINavHistoryService.TRANSITION_LINK, + date: new Date("2015-01-01"), + transition: Ci.nsINavHistoryService.TRANSITION_LINK, }], }]); // We have to wait until frecency updates have been handled in order // to accurately determine whether we're doing the right thing. let frecencyUpdatesHandled = new Promise(resolve => { PlacesUtils.history.addObserver({ onManyFrecenciesChanged() {