Bug 699844 - Remove the live bookmark migrator as it is not needed now. r=mak,markh
authorMark Banner <standard8@mozilla.com>
Mon, 26 Oct 2020 12:32:52 +0000
changeset 554491 413a70305cc689eb203f9bfb461a15415aea075c
parent 554490 2c2fd8e25f290228865dda20a9c020c7d157809a
child 554492 61283442e9fe37fa0595c4b9f17f00182d69a421
push id37894
push userdluca@mozilla.com
push dateTue, 27 Oct 2020 04:41:26 +0000
treeherdermozilla-central@46a0e993f8bb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak, markh
bugs699844
milestone84.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
Bug 699844 - Remove the live bookmark migrator as it is not needed now. r=mak,markh Differential Revision: https://phabricator.services.mozilla.com/D93314
.eslintrc.js
browser/components/BrowserGlue.jsm
browser/locales/en-US/chrome/browser/browser.properties
browser/modules/LiveBookmarkMigrator.jsm
browser/modules/moz.build
browser/modules/test/browser/browser.ini
browser/modules/test/browser/browser_LiveBookmarkMigrator.js
browser/modules/test/unit/test_LiveBookmarkMigrator.js
browser/modules/test/unit/xpcshell.ini
services/sync/modules/engines/bookmarks.js
toolkit/components/places/tests/sync/test_bookmark_kinds.js
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -642,17 +642,16 @@ module.exports = {
         "browser/extensions/formautofill/test/unit/test_creditCardRecords.js",
         "browser/extensions/formautofill/test/unit/test_migrateRecords.js",
         "browser/extensions/formautofill/test/unit/test_storage_remove.js",
         "browser/extensions/formautofill/test/unit/test_storage_tombstones.js",
         "browser/extensions/formautofill/test/unit/test_sync.js",
         "browser/extensions/formautofill/test/unit/test_transformFields.js",
         "browser/extensions/report-site-issue/experimentalAPIs/pageActionExtras.js",
         "browser/extensions/report-site-issue/test/browser/head.js",
-        "browser/modules/test/unit/test_LiveBookmarkMigrator.js",
         "devtools/client/aboutdebugging/test/browser/browser_aboutdebugging_addons_debug_popup.js",
         "dom/ipc/tests/browser_memory_distribution_telemetry.js",
         "dom/push/test/xpcshell/head.js",
         "dom/push/test/xpcshell/test_broadcast_success.js",
         "dom/push/test/xpcshell/test_crypto.js",
         "gfx/layers/apz/test/mochitest/browser_test_select_zoom.js",
         "security/manager/ssl/RemoteSecuritySettings.jsm",
         "security/manager/ssl/tests/unit/test_der.js",
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -813,17 +813,16 @@ XPCOMUtils.defineLazyModuleGetters(this,
   DownloadsViewableInternally:
     "resource:///modules/DownloadsViewableInternally.jsm",
   ExtensionsUI: "resource:///modules/ExtensionsUI.jsm",
   FirefoxMonitor: "resource:///modules/FirefoxMonitor.jsm",
   FxAccounts: "resource://gre/modules/FxAccounts.jsm",
   HomePage: "resource:///modules/HomePage.jsm",
   Integration: "resource://gre/modules/Integration.jsm",
   LoginBreaches: "resource:///modules/LoginBreaches.jsm",
-  LiveBookmarkMigrator: "resource:///modules/LiveBookmarkMigrator.jsm",
   NewTabUtils: "resource://gre/modules/NewTabUtils.jsm",
   Normandy: "resource://normandy/Normandy.jsm",
   ObjectUtils: "resource://gre/modules/ObjectUtils.jsm",
   OS: "resource://gre/modules/osfile.jsm",
   OsEnvironment: "resource://gre/modules/OsEnvironment.jsm",
   PageActions: "resource:///modules/PageActions.jsm",
   PageThumbs: "resource://gre/modules/PageThumbs.jsm",
   PdfJs: "resource://pdf.js/PdfJs.jsm",
@@ -2593,27 +2592,16 @@ BrowserGlue.prototype = {
 
       {
         task: () => {
           Blocklist.loadBlocklistAsync();
         },
       },
 
       {
-        condition:
-          Services.prefs.getIntPref(
-            "browser.livebookmarks.migrationAttemptsLeft",
-            0
-          ) > 0,
-        task: () => {
-          LiveBookmarkMigrator.migrate().catch(Cu.reportError);
-        },
-      },
-
-      {
         task: () => {
           TabUnloader.init();
         },
       },
 
       // request startup of Chromium remote debugging protocol
       // (observer will only be notified when --remote-debugging-port is passed)
       {
@@ -3321,17 +3309,17 @@ BrowserGlue.prototype = {
       );
     });
   },
 
   // eslint-disable-next-line complexity
   _migrateUI: function BG__migrateUI() {
     // Use an increasing number to keep track of the current migration state.
     // Completely unrelated to the current Firefox release number.
-    const UI_VERSION = 100;
+    const UI_VERSION = 101;
     const BROWSER_DOCURL = AppConstants.BROWSER_CHROME_URL;
 
     if (!Services.prefs.prefHasUserValue("browser.migration.version")) {
       // This is a new profile, nothing to migrate.
       Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
       this._isNewProfile = true;
       return;
     }
@@ -3591,26 +3579,16 @@ BrowserGlue.prototype = {
         const path = OS.Path.join(
           OS.Constants.Path.profileDir,
           `blocklists-${filename}`
         );
         OS.File.remove(path, { ignoreAbsent: true });
       }
     }
 
-    if (currentUIVersion < 75) {
-      // Ensure we try to migrate any live bookmarks the user might have, trying up to
-      // 5 times. We set this early, and here, to avoid running the migration on
-      // new profile (or, indeed, ever creating the pref there).
-      Services.prefs.setIntPref(
-        "browser.livebookmarks.migrationAttemptsLeft",
-        5
-      );
-    }
-
     if (currentUIVersion < 76) {
       // Clear old onboarding prefs from profile (bug 1462415)
       let onboardingPrefs = Services.prefs.getBranch("browser.onboarding.");
       if (onboardingPrefs) {
         let onboardingPrefsArray = onboardingPrefs.getChildList("");
         for (let item of onboardingPrefsArray) {
           Services.prefs.clearUserPref("browser.onboarding." + item);
         }
@@ -3981,16 +3959,22 @@ BrowserGlue.prototype = {
       }
       Services.xulStore.removeValue(
         BROWSER_DOCURL,
         "PersonalToolbar",
         "collapsed"
       );
     }
 
+    if (currentUIVersion < 101) {
+      Services.prefs.clearUserPref(
+        "browser.livebookmarks.migrationAttemptsLeft"
+      );
+    }
+
     // Update the migration version.
     Services.prefs.setIntPref("browser.migration.version", UI_VERSION);
   },
 
   _maybeShowDefaultBrowserPrompt() {
     DefaultBrowserCheck.willCheckDefaultBrowser(/* isStartupCheck */ true).then(
       async willPrompt => {
         let { DefaultBrowserNotification } = ChromeUtils.import(
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -1031,16 +1031,11 @@ confirmationHint.copyURL.label = Copied 
 confirmationHint.pageBookmarked.label = Saved to Library!
 confirmationHint.addSearchEngine.label = Search engine added!
 confirmationHint.pinTab.label = Pinned!
 confirmationHint.pinTab.description = Right-click the tab to unpin it.
 confirmationHint.passwordSaved.label = Password saved!
 confirmationHint.loginRemoved.label = Login removed!
 confirmationHint.breakageReport.label = Report sent. Thank you!
 
-# LOCALIZATION NOTE (livebookmarkMigration.title):
-# Used by the export of user's live bookmarks to an OPML file as a title for the file.
-# %S will be replaced with brandShortName
-livebookmarkMigration.title                      = %S Live Bookmarks
-
 # LOCALIZATION NOTE (gnomeSearchProviderSearch):
 # Used for search by Gnome Shell activity screen, %S is a searched string.
 gnomeSearchProviderSearch=Search the web for %S
deleted file mode 100644
--- a/browser/modules/LiveBookmarkMigrator.jsm
+++ /dev/null
@@ -1,263 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-"use strict";
-
-const { AppConstants } = ChromeUtils.import(
-  "resource://gre/modules/AppConstants.jsm"
-);
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-
-XPCOMUtils.defineLazyModuleGetters(this, {
-  BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
-  OS: "resource://gre/modules/osfile.jsm",
-  PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
-});
-
-XPCOMUtils.defineLazyGlobalGetters(this, ["URL", "XMLSerializer"]);
-
-XPCOMUtils.defineLazyGetter(this, "gBrowserBundle", function() {
-  return Services.strings.createBundle(
-    "chrome://browser/locale/browser.properties"
-  );
-});
-
-const kMigrationPref = "browser.livebookmarks.migrationAttemptsLeft";
-
-function migrationSucceeded() {
-  Services.prefs.clearUserPref(kMigrationPref);
-}
-
-function migrationError() {
-  // Decrement the number of remaining attempts.
-  let remainingAttempts = Math.max(
-    0,
-    Services.prefs.getIntPref(kMigrationPref, 1) - 1
-  );
-  Services.prefs.setIntPref(kMigrationPref, remainingAttempts);
-}
-
-var LiveBookmarkMigrator = {
-  _isOldDefaultBookmark(liveBookmark) {
-    if (!liveBookmark.feedURI || !liveBookmark.feedURI.host) {
-      return false;
-    }
-    let { host } = liveBookmark.feedURI;
-    return (
-      host.endsWith("fxfeeds.mozilla.com") ||
-      host.endsWith("fxfeeds.mozilla.org")
-    );
-  },
-
-  async _fetch() {
-    function getAnnoSQLFragment(aAnnoParam) {
-      return `SELECT a.content
-              FROM moz_items_annos a
-              JOIN moz_anno_attributes n ON n.id = a.anno_attribute_id
-              WHERE a.item_id = b.id
-                AND n.name = ${aAnnoParam}`;
-    }
-
-    // Copied and modified from nsLivemarkService.js, which we'll want to remove even when
-    // we keep this migration for a while.
-    const LB_SQL = `SELECT b.title, b.guid, b.dateAdded, b.position as 'index', p.guid AS parentGuid,
-              ( ${getAnnoSQLFragment(":feedURI_anno")} ) AS feedURI,
-              ( ${getAnnoSQLFragment(":siteURI_anno")} ) AS siteURI
-            FROM moz_bookmarks b
-            JOIN moz_bookmarks p ON b.parent = p.id
-            JOIN moz_items_annos a ON a.item_id = b.id
-            JOIN moz_anno_attributes n ON a.anno_attribute_id = n.id
-            WHERE b.type = :folder_type
-              AND n.name = :feedURI_anno
-      ORDER BY b.position DESC`;
-    // We sort by position so we go over items last-to-first. This way, we can insert a
-    // duplicate "normal" bookmark for each livemark, without causing future insertions
-    // to be off-by-N in their positioning because of the insertions.
-
-    let conn = await PlacesUtils.promiseDBConnection();
-    let rows = await conn.execute(LB_SQL, {
-      folder_type: Ci.nsINavBookmarksService.TYPE_FOLDER,
-      feedURI_anno: PlacesUtils.LMANNO_FEEDURI,
-      siteURI_anno: PlacesUtils.LMANNO_SITEURI,
-    });
-    // Create a JS object out of the sqlite result:
-    let liveBookmarks = [];
-    for (let row of rows) {
-      let siteURI = row.getResultByName("siteURI");
-      let feedURI = row.getResultByName("feedURI");
-      try {
-        feedURI = new URL(feedURI);
-        siteURI = siteURI ? new URL(siteURI) : null;
-      } catch (ex) {
-        // Skip items with broken URLs:
-        Cu.reportError(ex);
-        continue;
-      }
-      liveBookmarks.push({
-        guid: row.getResultByName("guid"),
-        index: row.getResultByName("index"),
-        dateAdded: PlacesUtils.toDate(row.getResultByName("dateAdded")),
-        parentGuid: row.getResultByName("parentGuid"),
-        title: row.getResultByName("title"),
-        siteURI,
-        feedURI,
-      });
-    }
-    return liveBookmarks;
-  },
-
-  async _writeOPML(liveBookmarks) {
-    const appName = Services.appinfo.name;
-    let hiddenBrowser = Services.appShell.createWindowlessBrowser();
-    let opmlString = "";
-    try {
-      let hiddenDOMDoc = hiddenBrowser.document;
-      // Create head:
-      let doc = hiddenDOMDoc.implementation.createDocument("", "opml", null);
-      let root = doc.documentElement;
-      root.setAttribute("version", "1.0");
-      let head = doc.createElement("head");
-      root.appendChild(head);
-      let title = doc.createElement("title");
-      title.textContent = gBrowserBundle.formatStringFromName(
-        "livebookmarkMigration.title",
-        [appName]
-      );
-      head.appendChild(title);
-
-      let body = doc.createElement("body");
-      root.appendChild(body);
-      // Make things vaguely readable:
-      body.textContent = "\n";
-
-      for (let lb of liveBookmarks) {
-        if (this._isOldDefaultBookmark(lb)) {
-          // Ignore the old default bookmarks and don't back them up.
-          continue;
-        }
-        let outline = doc.createElement("outline");
-        outline.setAttribute("type", "rss");
-        outline.setAttribute("title", lb.title);
-        outline.setAttribute("text", lb.title);
-        outline.setAttribute("xmlUrl", lb.feedURI.href);
-        if (lb.siteURI) {
-          outline.setAttribute("htmlUrl", lb.siteURI.href);
-        }
-        body.appendChild(outline);
-        body.appendChild(doc.createTextNode("\n"));
-      }
-
-      let serializer = new XMLSerializer();
-      // The serializer doesn't add an XML declaration (bug 318086), so we add it manually.
-      opmlString =
-        '<?xml version="1.0"?>\n' + serializer.serializeToString(doc);
-    } finally {
-      hiddenBrowser.close();
-    }
-
-    let { path: basePath } = Services.dirsvc.get("Desk", Ci.nsIFile);
-    let feedFileName = appName + " feeds backup.opml";
-    basePath = OS.Path.join(basePath, feedFileName);
-    let { file, path } = await OS.File.openUnique(basePath, {
-      humanReadable: true,
-    });
-    await file.close();
-    return OS.File.writeAtomic(path, opmlString, { encoding: "utf-8" });
-  },
-
-  async _transformBookmarks(liveBookmarks) {
-    let itemsToReplace = liveBookmarks.filter(
-      lb => !this._isOldDefaultBookmark(lb)
-    );
-    let itemsToInsert = itemsToReplace.map(item => ({
-      url: item.siteURI || item.feedURI,
-      parentGuid: item.parentGuid,
-      index: item.index,
-      title: item.title,
-      dateAdded: item.dateAdded,
-    }));
-    // Insert new bookmarks at the same index. The list is sorted by position
-    // in reverse order, so we'll insert later items before the earlier ones.
-    // This avoids the indices getting outdated for later insertions.
-    for (let item of itemsToInsert) {
-      await PlacesUtils.bookmarks.insert(item).catch(Cu.reportError);
-    }
-    // Now remove all of the actual live bookmarks. Avoid mismatches due to the
-    // bookmarks having been moved or altered in the meantime, just remove
-    // anything with a matching guid:
-    let itemsToRemove = liveBookmarks.map(lb => ({ guid: lb.guid }));
-    await PlacesUtils.bookmarks.remove(itemsToRemove).catch(Cu.reportError);
-  },
-
-  _openSUMOPage() {
-    let sumoURL =
-      Services.urlFormatter.formatURLPref("app.support.baseURL") +
-      "live-bookmarks-migration";
-    let topWin = BrowserWindowTracker.getTopWindow({ private: false });
-    if (!topWin) {
-      let args = PlacesUtils.toISupportsString(sumoURL);
-      Services.ww.openWindow(
-        null,
-        AppConstants.BROWSER_CHROME_URL,
-        "_blank",
-        "chrome,dialog=no,all",
-        args
-      );
-    } else {
-      topWin.openTrustedLinkIn(sumoURL, "tab");
-    }
-  },
-
-  async migrate() {
-    try {
-      // First fetch all live bookmark folders:
-      let liveBookmarks = await this._fetch();
-      if (!liveBookmarks || !liveBookmarks.length) {
-        migrationSucceeded();
-        return;
-      }
-
-      let haveNonDefaultBookmarks = liveBookmarks.some(
-        lb => !this._isOldDefaultBookmark(lb)
-      );
-      // Then generate OPML file content, write to disk, if we've got anything to back up:
-      if (haveNonDefaultBookmarks) {
-        await this._writeOPML(liveBookmarks);
-      }
-      // Replace all live bookmarks with normal bookmarks.
-      await this._transformBookmarks(liveBookmarks).catch(ex => {
-        // Don't stop migrating at this point, because we've written the exported OPML file.
-        // We shouldn't ever hit this - transformLiveBookmarks is supposed to take
-        // care of its own failures.
-        Cu.reportError(ex);
-      });
-
-      try {
-        if (haveNonDefaultBookmarks) {
-          this._openSUMOPage();
-        }
-      } catch (ex) {
-        // Note that if we get here, we've removed any extant livemarks, so there's no point
-        // re-running the migration - there won't be any livemarks left and we won't re-show the SUMO
-        // page. So just report the error, but mark migration as successful.
-        Cu.reportError(
-          new Error(
-            "Live bookmarks migration didn't manage to show the support page: " +
-              ex
-          )
-        );
-      }
-    } catch (ex) {
-      migrationError();
-      throw ex;
-    }
-
-    migrationSucceeded();
-  },
-};
-
-var EXPORTED_SYMBOLS = ["LiveBookmarkMigrator"];
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -132,17 +132,16 @@ EXTRA_JS_MODULES += [
     'BrowserWindowTracker.jsm',
     'ContentCrashHandlers.jsm',
     'Discovery.jsm',
     'EveryWindow.jsm',
     'ExtensionsUI.jsm',
     'FaviconLoader.jsm',
     'HomePage.jsm',
     'LaterRun.jsm',
-    'LiveBookmarkMigrator.jsm',
     'NewTabPagePreloading.jsm',
     'OpenInTabsUtils.jsm',
     'PageActions.jsm',
     'PartnerLinkAttribution.jsm',
     'PermissionUI.jsm',
     'PingCentre.jsm',
     'ProcessHangMonitor.jsm',
     'Sanitizer.jsm',
--- a/browser/modules/test/browser/browser.ini
+++ b/browser/modules/test/browser/browser.ini
@@ -12,17 +12,16 @@ support-files =
   contentSearchSuggestions.sjs
   contentSearchSuggestions.xml
   !/browser/components/search/test/browser/head.js
   !/browser/components/search/test/browser/testEngine.xml
   !/browser/components/search/test/browser/testEngine_diacritics.xml
   testEngine_chromeicon.xml
 skip-if = (debug && os == "linux" && bits == 64 && os_version == "18.04") # Bug 1649755
 [browser_EveryWindow.js]
-[browser_LiveBookmarkMigrator.js]
 [browser_PageActions.js]
 [browser_PageActions_contextMenus.js]
 [browser_PageActions_newWindow.js]
 [browser_PartnerLinkAttribution.js]
 support-files =
   search-engines/basic/manifest.json
   search-engines/simple/manifest.json
   search-engines/engines.json
deleted file mode 100644
--- a/browser/modules/test/browser/browser_LiveBookmarkMigrator.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-"use strict";
-
-// Check migrator can open the SUMO page.
-add_task(async function() {
-  let expectedURL =
-    Services.prefs.getCharPref("app.support.baseURL") +
-    "live-bookmarks-migration";
-  let newTabExpected = BrowserTestUtils.waitForNewTab(
-    gBrowser,
-    expectedURL,
-    true
-  );
-  let { LiveBookmarkMigrator } = ChromeUtils.import(
-    "resource:///modules/LiveBookmarkMigrator.jsm"
-  );
-  LiveBookmarkMigrator._openSUMOPage();
-  await newTabExpected;
-  // If we get here, this is guaranteed to pass, but otherwise mochitest complains that
-  // the test has no assertions.
-  is(
-    gBrowser.selectedBrowser.currentURI.spec,
-    expectedURL,
-    "Should have opened the right page"
-  );
-  gBrowser.removeCurrentTab();
-});
deleted file mode 100644
--- a/browser/modules/test/unit/test_LiveBookmarkMigrator.js
+++ /dev/null
@@ -1,271 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/
- */
-
-/* globals ChromeUtils, Assert, add_task */
-"use strict";
-
-// Ensure we initialize places:
-do_get_profile();
-
-ChromeUtils.defineModuleGetter(
-  this,
-  "PlacesUIUtils",
-  "resource:///modules/PlacesUIUtils.jsm"
-);
-
-// Needed because we rely on the app name for the OPML file name and title.
-ChromeUtils.import("resource://testing-common/AppInfo.jsm", this);
-updateAppInfo({
-  name: "LiveBookmarkMigratorTest",
-  ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
-  version: "1",
-  platformVersion: "",
-});
-
-const { PlacesUtils } = ChromeUtils.import(
-  "resource://gre/modules/PlacesUtils.jsm"
-);
-const { LiveBookmarkMigrator } = ChromeUtils.import(
-  "resource:///modules/LiveBookmarkMigrator.jsm"
-);
-
-const kTestData = {
-  guid: PlacesUtils.bookmarks.toolbarGuid,
-  children: [
-    {
-      type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-      title: "BM 1",
-      url: new URL("https://example.com/1"),
-    },
-    { type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB 1" },
-    {
-      type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-      title: "BM 2",
-      url: new URL("https://example.com/2"),
-    },
-    {
-      type: PlacesUtils.bookmarks.TYPE_FOLDER,
-      title: "Regular old folder",
-      children: [
-        { type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB child 1" },
-        {
-          type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-          title: "BM child 1",
-          url: new URL("https://example.com/1/1"),
-        },
-        { type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB child 2" },
-        {
-          type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-          title: "BM child 2",
-          url: new URL("https://example.com/1/2"),
-        },
-      ],
-    },
-    { type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB 2" },
-    {
-      type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
-      title: "BM 3",
-      url: new URL("https://example.com/3"),
-    },
-    { type: PlacesUtils.bookmarks.TYPE_FOLDER, title: "LB 3" },
-    // The next two will be skipped because we ignore the feeds we used to ship by default:
-    {
-      type: PlacesUtils.bookmarks.TYPE_FOLDER,
-      title: "Default live bookmark 4",
-    },
-    {
-      type: PlacesUtils.bookmarks.TYPE_FOLDER,
-      title: "Default live bookmark 5",
-    },
-  ],
-};
-
-const kDefaultFeedURLsToTest = [
-  "http://en-US.fxfeeds.mozilla.com/",
-  "http://fxfeeds.mozilla.org/",
-];
-
-registerCleanupFunction(async () => {
-  await PlacesUtils.bookmarks.eraseEverything();
-});
-
-add_task(async function setup() {
-  let insertedItems = await PlacesUtils.bookmarks.insertTree(kTestData);
-  for (let item of insertedItems) {
-    if (item.title.includes("LB")) {
-      let id = await PlacesUtils.promiseItemId(item.guid);
-      let feedID = item.title.replace(/[^0-9]/g, "");
-      PlacesUtils.annotations.setItemAnnotation(
-        id,
-        PlacesUtils.LMANNO_FEEDURI,
-        "https://example.com/feed/" + feedID,
-        0,
-        PlacesUtils.annotations.EXPIRE_NEVER,
-        PlacesUtils.bookmarks.SOURCES.DEFAULT,
-        true
-      );
-      // For half the feeds, set a site URI as well.
-      if (parseInt(feedID) % 2) {
-        PlacesUtils.annotations.setItemAnnotation(
-          id,
-          PlacesUtils.LMANNO_SITEURI,
-          "https://example.com/feedpage/" + feedID,
-          0,
-          PlacesUtils.annotations.EXPIRE_NEVER,
-          PlacesUtils.bookmarks.SOURCES.DEFAULT,
-          true
-        );
-      }
-    } else if (item.title.includes("Default live bookmark")) {
-      let id = await PlacesUtils.promiseItemId(item.guid);
-      PlacesUtils.annotations.setItemAnnotation(
-        id,
-        PlacesUtils.LMANNO_FEEDURI,
-        kDefaultFeedURLsToTest.pop(),
-        0,
-        PlacesUtils.annotations.EXPIRE_NEVER,
-        PlacesUtils.bookmarks.SOURCES.DEFAULT,
-        true
-      );
-    }
-  }
-});
-
-// Test fetching LB with and without siteURIs works. Check ordering is last-positioned-first.
-add_task(async function check_fetches_livemarks_correctly() {
-  let detectedLiveBookmarks = await LiveBookmarkMigrator._fetch();
-  Assert.equal(detectedLiveBookmarks.length, 7, "Should have 7 live bookmarks");
-  Assert.notEqual(
-    detectedLiveBookmarks.filter(lb => lb.siteURI).length,
-    0,
-    "Should have more than 0 items with a siteURI"
-  );
-  Assert.notEqual(
-    detectedLiveBookmarks.filter(lb => !lb.siteURI).length,
-    0,
-    "Should have more than 0 items without a siteURI"
-  );
-  Assert.equal(
-    detectedLiveBookmarks.filter(lb => lb.feedURI).length,
-    7,
-    "All of them should have a feed URI"
-  );
-  info(JSON.stringify(detectedLiveBookmarks));
-  Assert.deepEqual(
-    detectedLiveBookmarks.map(bm => bm.index),
-    [8, 7, 6, 4, 2, 1, 0],
-    "Should have sorted the items correctly."
-  );
-});
-
-// Test that we write sane OPML for some live bookmarks.
-add_task(async function check_opml_writing() {
-  let bsPass = ChromeUtils.import(
-    "resource:///modules/LiveBookmarkMigrator.jsm",
-    null
-  );
-  let oldFile = bsPass.OS.File;
-  registerCleanupFunction(() => {
-    bsPass.OS.File = oldFile;
-  });
-
-  let lastWriteArgs = null;
-  bsPass.OS.File = {
-    writeAtomic() {
-      lastWriteArgs = Array.from(arguments);
-    },
-    openUnique() {
-      return { file: { close() {} }, path: "foopy.opml" };
-    },
-  };
-  let livemarks = [
-    {
-      feedURI: new URL("https://example.com/feed"),
-      siteURI: new URL("https://example.com/"),
-      title: "My funky feed",
-    },
-    {
-      feedURI: new URL("https://example.com/otherfeed"),
-      title: "My other feed",
-    },
-  ];
-  await LiveBookmarkMigrator._writeOPML(livemarks);
-  let expectedOPML = `<?xml version="1.0"?>
-<opml version="1.0"><head><title>LiveBookmarkMigratorTest Live Bookmarks</title></head><body>
-<outline type="rss" title="My funky feed" text="My funky feed" xmlUrl="https://example.com/feed" htmlUrl="https://example.com/"/>
-<outline type="rss" title="My other feed" text="My other feed" xmlUrl="https://example.com/otherfeed"/>
-</body></opml>`;
-  Assert.deepEqual(
-    lastWriteArgs,
-    ["foopy.opml", expectedOPML, { encoding: "utf-8" }],
-    "Should have tried to write the right thing."
-  );
-});
-
-// Check all the live bookmarks have been removed, and where they have site URIs, replaced:
-add_task(async function check_replace_bookmarks_correctly() {
-  let oldLiveBookmarks = await LiveBookmarkMigrator._fetch();
-  await LiveBookmarkMigrator._transformBookmarks(oldLiveBookmarks);
-
-  // Check all the remaining bookmarks are not live bookmarks anymore:
-  let newBookmarkState = await PlacesUtils.promiseBookmarksTree(
-    PlacesUtils.bookmarks.toolbarGuid
-  );
-  function checkNotALiveBookmark(bm) {
-    Assert.ok(
-      !bm.annos,
-      "Bookmark " + bm.title + " shouldn't be a live bookmark"
-    );
-  }
-  function iterate(node, fn) {
-    fn(node);
-    if (node.children) {
-      node.children.forEach(fn);
-    }
-  }
-  iterate(newBookmarkState, checkNotALiveBookmark);
-  Assert.equal(
-    (await LiveBookmarkMigrator._fetch()).length,
-    0,
-    "Migrator should no longer find live bookmarks"
-  );
-
-  info(JSON.stringify(newBookmarkState));
-  // Check that all the old live bookmarks have been removed, and where appropriate, replaced:
-  for (let bm of oldLiveBookmarks) {
-    let replacements = await PlacesUtils.bookmarks.search({ title: bm.title });
-    let replacement = replacements && replacements[0];
-    if (!bm.title.includes("Default live bookmark")) {
-      if (replacement) {
-        Assert.equal(
-          bm.title,
-          replacement.title,
-          "Found item should have same title"
-        );
-        Assert.equal(
-          bm.siteURI || bm.feedURI,
-          replacement.url.href,
-          "Found item should have matching URL"
-        );
-        Assert.equal(
-          bm.index,
-          replacement.index,
-          "Found item should have same position"
-        );
-        Assert.equal(
-          bm.parentGuid,
-          replacement.parentGuid,
-          "Found item should have same parent"
-        );
-      } else {
-        Assert.ok(
-          false,
-          "Oy! No replacement for `" + bm.title + "` but we expected one!"
-        );
-      }
-    } else {
-      Assert.ok(!replacement, "Shouldn't have kept the default bookmark items");
-    }
-  }
-});
--- a/browser/modules/test/unit/xpcshell.ini
+++ b/browser/modules/test/unit/xpcshell.ini
@@ -1,17 +1,16 @@
 [DEFAULT]
 head =
 firefox-appdir = browser
 skip-if = toolkit == 'android'
 
 [test_E10SUtils_nested_URIs.js]
 [test_HomePage.js]
 [test_HomePage_ignore.js]
-[test_LiveBookmarkMigrator.js]
 [test_Sanitizer_interrupted.js]
 [test_SitePermissions.js]
 [test_SiteDataManager.js]
 [test_LaterRun.js]
 [test_discovery.js]
 [test_PingCentre.js]
 [test_ProfileCounter.js]
 skip-if = os != 'win' # Test of a Windows-specific feature
--- a/services/sync/modules/engines/bookmarks.js
+++ b/services/sync/modules/engines/bookmarks.js
@@ -25,17 +25,16 @@ const { Changeset, Store, SyncEngine, Tr
 );
 const { CryptoWrapper } = ChromeUtils.import(
   "resource://services-sync/record.js"
 );
 const { Svc, Utils } = ChromeUtils.import("resource://services-sync/util.js");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   BookmarkValidator: "resource://services-sync/bookmark_validator.js",
-  LiveBookmarkMigrator: "resource:///modules/LiveBookmarkMigrator.jsm",
   Observers: "resource://services-common/observers.js",
   OS: "resource://gre/modules/osfile.jsm",
   PlacesBackups: "resource://gre/modules/PlacesBackups.jsm",
   PlacesDBUtils: "resource://gre/modules/PlacesDBUtils.jsm",
   PlacesSyncUtils: "resource://gre/modules/PlacesSyncUtils.jsm",
   PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
   Resource: "resource://services-sync/resource.js",
   SyncedBookmarksMirror: "resource://gre/modules/SyncedBookmarksMirror.jsm",
@@ -390,28 +389,22 @@ BookmarksEngine.prototype = {
     // bookmarks engine doesn't download records we've already applied.
     await PlacesSyncUtils.bookmarks.setLastSync(lastSync);
   },
 
   async _syncStartup() {
     await super._syncStartup();
 
     try {
-      // For first syncs, back up the user's bookmarks and livemarks. Livemarks
-      // are unsupported as of bug 1477671, and syncing deletes them locally and
-      // remotely.
+      // For first syncs, back up the user's bookmarks.
       let lastSync = await this.getLastSync();
       if (!lastSync) {
         this._log.debug("Bookmarks backup starting");
         await PlacesBackups.create(null, true);
         this._log.debug("Bookmarks backup done");
-
-        this._log.debug("Livemarks backup starting");
-        await LiveBookmarkMigrator.migrate();
-        this._log.debug("Livemarks backup done");
       }
     } catch (ex) {
       // Failure to create a backup is somewhat bad, but probably not bad
       // enough to prevent syncing of bookmarks - so just log the error and
       // continue.
       this._log.warn(
         "Error while backing up bookmarks, but continuing with sync",
         ex
--- a/toolkit/components/places/tests/sync/test_bookmark_kinds.js
+++ b/toolkit/components/places/tests/sync/test_bookmark_kinds.js
@@ -177,123 +177,16 @@ add_task(async function test_queries() {
     "Should rewrite legacy remote queries"
   );
 
   await buf.finalize();
   await PlacesUtils.bookmarks.eraseEverything();
   await PlacesSyncUtils.bookmarks.reset();
 });
 
-// Bug 632287.
-add_task(async function test_mismatched_folder_types() {
-  let buf = await openMirror("mismatched_types");
-
-  info("Set up mirror");
-  await PlacesUtils.bookmarks.insertTree({
-    guid: PlacesUtils.bookmarks.toolbarGuid,
-    children: [
-      {
-        guid: "l1nZZXfB8nC7",
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        title: "Innerst i Sneglehode",
-      },
-      {
-        guid: "livemarkBBBB",
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        title: "B",
-      },
-    ],
-  });
-  await PlacesTestUtils.markBookmarksAsSynced();
-
-  info("Make remote changes");
-  await storeRecords(buf, [
-    {
-      id: "toolbar",
-      parentid: "places",
-      type: "folder",
-      children: ["l1nZZXfB8nC7", "livemarkBBBB"],
-    },
-    {
-      id: "l1nZZXfB8nC7",
-      type: "livemark",
-      siteUri: "http://sneglehode.wordpress.com/",
-      feedUri: "http://sneglehode.wordpress.com/feed/",
-      parentName: "Bookmarks Toolbar",
-      title: "Innerst i Sneglehode",
-      description: null,
-      children: [
-        "HCRq40Rnxhrd",
-        "YeyWCV1RVsYw",
-        "GCceVZMhvMbP",
-        "sYi2hevdArlF",
-        "vjbZlPlSyGY8",
-        "UtjUhVyrpeG6",
-        "rVq8WMG2wfZI",
-        "Lx0tcy43ZKhZ",
-        "oT74WwV8_j4P",
-        "IztsItWVSo3-",
-      ],
-      parentid: "toolbar",
-    },
-    {
-      id: "livemarkBBBB",
-      parentid: "toolbar",
-      type: "folder",
-      title: "B",
-      children: [],
-    },
-  ]);
-
-  info("Apply remote");
-  let changesToUpload = await buf.apply();
-  // We leave livemarks unmerged because we're about to upload tombstones for
-  // them, anyway.
-  deepEqual(
-    await buf.fetchUnmergedGuids(),
-    ["l1nZZXfB8nC7", "livemarkBBBB", PlacesUtils.bookmarks.toolbarGuid],
-    "Should leave livemarks and toolbar with new remote structure unmerged"
-  );
-
-  let idsToUpload = inspectChangeRecords(changesToUpload);
-  deepEqual(
-    idsToUpload,
-    {
-      updated: ["toolbar"],
-      deleted: ["l1nZZXfB8nC7", "livemarkBBBB"],
-    },
-    "Should delete livemarks remotely"
-  );
-
-  await assertLocalTree(
-    PlacesUtils.bookmarks.toolbarGuid,
-    {
-      guid: PlacesUtils.bookmarks.toolbarGuid,
-      type: PlacesUtils.bookmarks.TYPE_FOLDER,
-      index: 1,
-      title: BookmarksToolbarTitle,
-    },
-    "Should delete livemarks locally"
-  );
-
-  let tombstones = await PlacesTestUtils.fetchSyncTombstones();
-  deepEqual(
-    tombstones.map(({ guid }) => guid),
-    ["l1nZZXfB8nC7", "livemarkBBBB"],
-    "Should store local tombstones for livemarks"
-  );
-
-  await storeChangesInMirror(buf, changesToUpload);
-  deepEqual(await buf.fetchUnmergedGuids(), [], "Should merge all items");
-
-  await buf.finalize();
-  await PlacesUtils.bookmarks.eraseEverything();
-  await PlacesSyncUtils.bookmarks.reset();
-});
-
 add_task(async function test_different_but_compatible_bookmark_types() {
   let buf = await openMirror("partial_queries");
   try {
     await PlacesUtils.bookmarks.insertTree({
       guid: PlacesUtils.bookmarks.menuGuid,
       children: [
         {
           guid: "bookmarkAAAA",