Bug 1338800 - Wait for frecency updates before moving off bookmarks r?mak draft
authorDoug Thayer <dothayer@mozilla.com>
Thu, 02 Nov 2017 10:30:05 -0700
changeset 692182 fd8835c71a57a2c61ae4d2a5e8bf26b1d3f362fe
parent 692181 c434a4518a034bce2a4a878bbc976db729480cbc
child 738692 335bdeb50db739879c3fb334a98c0ee1a5d78ab8
push id87428
push userbmo:dothayer@mozilla.com
push dateThu, 02 Nov 2017 17:30:36 +0000
reviewersmak
bugs1338800
milestone58.0a1
Bug 1338800 - Wait for frecency updates before moving off bookmarks r?mak Because Bookmarks come before History in the resource lists of the Chrome migrator and other migrators, we'd like to ensure that the frecency updates from the Bookmarks migration aren't creating any contention with the History migration. Ensuring that we await the frecency updates should be enough to avoid this. MozReview-Commit-ID: 3iKGeVpEQMH
browser/components/migration/MigrationUtils.jsm
toolkit/components/places/Bookmarks.jsm
--- a/browser/components/migration/MigrationUtils.jsm
+++ b/browser/components/migration/MigrationUtils.jsm
@@ -996,17 +996,21 @@ this.MigrationUtils = Object.freeze({
       gUndoData.get("bookmarks").push({
         parentGuid, guid, lastModified, type
       });
       return bm;
     });
   },
 
   insertManyBookmarksWrapper(bookmarks, parent) {
-    let insertionPromise = PlacesUtils.bookmarks.insertTree({guid: parent, children: bookmarks});
+    let insertionPromise = PlacesUtils.bookmarks.insertTree({
+      guid: parent,
+      children: bookmarks,
+      waitForFrecenciesChanged: true,
+    });
     return insertionPromise.then(insertedItems => {
       this._importQuantities.bookmarks += insertedItems.length;
       if (gKeepUndoData) {
         let bmData = gUndoData.get("bookmarks");
         for (let bm of insertedItems) {
           let {parentGuid, guid, lastModified, type} = bm;
           bmData.push({parentGuid, guid, lastModified, type});
         }
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -304,16 +304,17 @@ var Bookmarks = Object.freeze({
     if (tree.hasOwnProperty("source") &&
         !Object.values(this.SOURCES).includes(tree.source)) {
       throw new Error("Can't use source value " + tree.source);
     }
     if (options && typeof options != "object") {
       throw new Error("Options should be a valid object");
     }
     let fixupOrSkipInvalidEntries = options && !!options.fixupOrSkipInvalidEntries;
+    let waitForFrecenciesChanged = options && !!options.waitForFrecenciesChanged;
 
     // Serialize the tree into an array of items to insert into the db.
     let insertInfos = [];
     let insertLivemarkInfos = [];
     let urlsThatMightNeedPlaces = [];
 
     // We want to use the same 'last added' time for all the entries
     // we import (so they won't differ by a few ms based on where
@@ -448,16 +449,38 @@ var Bookmarks = Object.freeze({
       if (!treeParent) {
         throw new Error("The parent you specified doesn't exist.");
       }
 
       if (treeParent._parentId == PlacesUtils.tagsFolderId) {
         throw new Error("Can't use insertTree to insert tags.");
       }
 
+      let frecenciesChangedPromise;
+      if (waitForFrecenciesChanged) {
+        frecenciesChangedPromise = new Promise((resolve, reject) => {
+          let onManyFrecenciesObserver = {
+            onDeleteURI() {},
+            onVisit() {},
+            onBeginUpdateBatch() {},
+            onEndUpdateBatch() {},
+            onTitleChanged() {},
+            onClearHistory() {},
+            onPageChanged() {},
+            onFrecencyChanged() {},
+            onDeleteVisits() {},
+            onManyFrecenciesChanged() {
+              PlacesUtils.history.removeObserver(this);
+              resolve();
+            },
+          };
+          PlacesUtils.history.addObserver(onManyFrecenciesObserver);
+        });
+      }
+
       await insertBookmarkTree(insertInfos, source, treeParent,
                                urlsThatMightNeedPlaces, lastAddedForParent);
 
       for (let info of insertLivemarkInfos) {
         try {
           await insertLivemarkData(info);
         } catch (ex) {
           // This can arguably fail, if some of the livemarks data is invalid.
@@ -523,16 +546,20 @@ var Bookmarks = Object.freeze({
           Cu.reportError(`An error occured while handling special bookmark data: ${ex}`);
         }
 
         // Remove non-enumerable properties.
         delete item.source;
 
         insertInfos[i] = Object.assign({}, item);
       }
+
+      if (waitForFrecenciesChanged) {
+        await frecenciesChangedPromise;
+      }
       return insertInfos;
     })();
   },
 
   /**
    * Updates a bookmark-item.
    *
    * Only set the properties which should be changed (undefined properties