Bug 1372694 - Stop making the default theme a heavyweight theme. r=Gijs, kmag draft
authorTim Nguyen <ntim.bugs@gmail.com>
Sun, 01 Apr 2018 13:53:31 +0200
changeset 775893 ef7d7d1a22fd372f72a8781d884b72ccf14d1748
parent 775892 2ad47d44c723f02d4e9d9973de61df98856751b2
push id104740
push userbmo:ntim.bugs@gmail.com
push dateSun, 01 Apr 2018 11:54:49 +0000
reviewersGijs, kmag
bugs1372694
milestone61.0a1
Bug 1372694 - Stop making the default theme a heavyweight theme. r=Gijs, kmag MozReview-Commit-ID: 30wMauuc9oo
browser/app/moz.build
browser/app/profile/extensions/moz.build
browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
browser/app/profile/firefox.js
browser/base/content/default-theme-icon.svg
browser/base/jar.mn
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
browser/installer/allowed-dupes.mn
browser/installer/package-manifest.in
browser/locales/en-US/chrome/browser/browser.properties
browser/themes/linux/jar.mn
browser/themes/osx/jar.mn
browser/themes/windows/jar.mn
toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
toolkit/mozapps/extensions/LightweightThemeManager.jsm
toolkit/mozapps/extensions/content/default-theme-icon.svg
toolkit/mozapps/extensions/internal/XPIInstall.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
toolkit/mozapps/extensions/internal/XPIProviderUtils.js
toolkit/mozapps/extensions/jar.mn
toolkit/mozapps/extensions/test/xpcshell/test_addonStartup.js
toolkit/themes/linux/mozapps/jar.mn
toolkit/themes/osx/global/jar.mn
toolkit/themes/osx/mozapps/jar.mn
toolkit/themes/shared/non-mac.jar.inc.mn
toolkit/themes/windows/global/jar.mn
toolkit/themes/windows/mozapps/jar.mn
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -19,26 +19,21 @@ with Files("macversion.py"):
 with Files("macbuild/**"):
     BUG_COMPONENT = ("Core", "Widget: Cocoa")
 
 with Files("moz.build"):
     BUG_COMPONENT = ("Firefox Build System", "General")
 with Files("Makefile.in"):
     BUG_COMPONENT = ("Firefox Build System", "General")
 
-with Files("profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/**"):
-    BUG_COMPONENT = ("Firefox", "Theme")
 with Files("profile/channel-prefs.js"):
     BUG_COMPONENT = ("Firefox", "Installer")
 with Files("profile/firefox.js"):
     BUG_COMPONENT = ("Firefox", "General")
 
-
-DIRS += ['profile/extensions']
-
 GeckoProgram(CONFIG['MOZ_APP_NAME'])
 
 SOURCES += [
     'nsBrowserApp.cpp',
 ]
 
 # Neither channel-prefs.js nor firefox.exe want to end up in dist/bin/browser.
 DIST_SUBDIR = ""
deleted file mode 100644
--- a/browser/app/profile/extensions/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-DIRS += ['{972ce4c6-7e08-4474-a285-3208198ce6fd}']
deleted file mode 100644
--- a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf.in
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.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/. -->
-
-
-#filter substitution
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>{972ce4c6-7e08-4474-a285-3208198ce6fd}</em:id>
-    <em:version>@FIREFOX_VERSION@</em:version>
-
-    <!-- Target Application this theme can install into,
-        with minimum and maximum supported versions. -->
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>@FIREFOX_VERSION@</em:minVersion>
-        <em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:name>Default</em:name>
-    <em:description>The default theme.</em:description>
-
-    <!-- Front End Integration Hooks (used by Theme Manager)-->
-    <em:creator>Mozilla</em:creator>
-    <em:contributor>Mozilla Contributors</em:contributor>
-
-    <!-- Allow lightweight themes to apply to this theme -->
-    <em:skinnable>true</em:skinnable>
-
-    <em:internalName>classic/1.0</em:internalName>
-
-    <em:iconURL>chrome://browser/content/default-theme-icon.svg</em:iconURL>
-  </Description>
-
-</RDF>
deleted file mode 100644
--- a/browser/app/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-FINAL_TARGET = 'dist/bin/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}'
-
-FINAL_TARGET_PP_FILES += [
-    'install.rdf.in',
-]
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -78,17 +78,17 @@ pref("extensions.webextensions.default-c
 
 #if defined(XP_WIN)
 pref("extensions.webextensions.remote", true);
 #elif defined(XP_MACOSX) && !defined(RELEASE_OR_BETA)
 pref("extensions.webextensions.remote", true);
 #endif
 
 // Extensions that should not be flagged as legacy in about:addons
-pref("extensions.legacy.exceptions", "{972ce4c6-7e08-4474-a285-3208198ce6fd},testpilot@cliqz.com,@testpilot-containers,jid1-NeEaf3sAHdKHPA@jetpack,@activity-streams,pulse@mozilla.com,@testpilot-addon,@min-vid,tabcentertest1@mozilla.com,snoozetabs@mozilla.com,speaktome@mozilla.com,hoverpad@mozilla.com");
+pref("extensions.legacy.exceptions", "testpilot@cliqz.com,@testpilot-containers,jid1-NeEaf3sAHdKHPA@jetpack,@activity-streams,pulse@mozilla.com,@testpilot-addon,@min-vid,tabcentertest1@mozilla.com,snoozetabs@mozilla.com,speaktome@mozilla.com,hoverpad@mozilla.com");
 
 // Require signed add-ons by default
 pref("xpinstall.signatures.required", true);
 pref("xpinstall.signatures.devInfoURL", "https://wiki.mozilla.org/Addons/Extension_Signing");
 
 // Dictionary download preference
 pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/");
 
@@ -186,19 +186,16 @@ pref("app.update.service.enabled", true)
 //  .. etc ..
 //
 pref("extensions.update.enabled", true);
 pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
 pref("extensions.update.background.url", "https://versioncheck-bg.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%&currentAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
 pref("extensions.update.interval", 86400);  // Check for updates to Extensions and
                                             // Themes every day
 
-pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name", "chrome://browser/locale/browser.properties");
-pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description", "chrome://browser/locale/browser.properties");
-
 pref("extensions.webextensions.themes.enabled", true);
 pref("extensions.webextensions.themes.icons.buttons", "back,forward,reload,stop,bookmark_star,bookmark_menu,downloads,home,app_menu,cut,copy,paste,new_window,new_private_window,save_page,print,history,full_screen,find,options,addons,developer,synced_tabs,open_file,sidebars,share_page,subscribe,text_encoding,email_link,forget,pocket");
 
 pref("lightweightThemes.update.enabled", true);
 pref("lightweightThemes.getMoreURL", "https://addons.mozilla.org/%LOCALE%/firefox/themes");
 pref("lightweightThemes.recommendedThemes", "[{\"id\":\"recommended-1\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/a-web-browser-renaissance/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.header.jpg\",\"textcolor\":\"#000000\",\"accentcolor\":\"#834d29\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/1.preview.jpg\",\"author\":\"Sean.Martell\",\"version\":\"0\"},{\"id\":\"recommended-2\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/space-fantasy/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.header.jpg\",\"textcolor\":\"#ffffff\",\"accentcolor\":\"#d9d9d9\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.icon.jpg\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/2.preview.jpg\",\"author\":\"fx5800p\",\"version\":\"1.0\"},{\"id\":\"recommended-4\",\"homepageURL\":\"https://addons.mozilla.org/firefox/addon/pastel-gradient/\",\"headerURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.header.png\",\"textcolor\":\"#000000\",\"accentcolor\":\"#000000\",\"iconURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.icon.png\",\"previewURL\":\"resource:///chrome/browser/content/browser/defaultthemes/4.preview.png\",\"author\":\"darrinhenein\",\"version\":\"1.0\"}]");
 
 #if defined(MOZ_WIDEVINE_EME)
@@ -1256,17 +1253,17 @@ pref("services.sync.prefs.sync.xpinstall
 // user's tabs and bookmarks. Note this pref is also synced.
 pref("services.sync.syncedTabs.showRemoteIcons", true);
 
 // Developer edition preferences
 #ifdef MOZ_DEV_EDITION
 pref("lightweightThemes.selectedThemeID", "firefox-compact-dark@mozilla.org",
      sticky);
 #else
-pref("lightweightThemes.selectedThemeID", "", sticky);
+pref("lightweightThemes.selectedThemeID", "default-theme@mozilla.org", sticky);
 #endif
 
 // Whether the character encoding menu is under the main Firefox button. This
 // preference is a string so that localizers can alter it.
 pref("browser.menu.showCharacterEncoding", "chrome://browser/locale/browser.properties");
 
 // Allow using tab-modal prompts when possible.
 pref("prompts.tab_modal.enabled", true);
--- a/browser/base/jar.mn
+++ b/browser/base/jar.mn
@@ -73,34 +73,33 @@ browser.jar:
 #else
         content/browser/browser-tabsintitlebar.js       (content/browser-tabsintitlebar-stub.js)
 #endif
         content/browser/browser-thumbnails.js         (content/browser-thumbnails.js)
         content/browser/browser-trackingprotection.js (content/browser-trackingprotection.js)
         content/browser/browser-webrender.js          (content/browser-webrender.js)
         content/browser/tab-content.js                (content/tab-content.js)
         content/browser/content.js                    (content/content.js)
-        content/browser/default-theme-icon.svg        (content/default-theme-icon.svg)
         content/browser/defaultthemes/1.header.jpg    (content/defaultthemes/1.header.jpg)
         content/browser/defaultthemes/1.icon.jpg      (content/defaultthemes/1.icon.jpg)
         content/browser/defaultthemes/1.preview.jpg   (content/defaultthemes/1.preview.jpg)
         content/browser/defaultthemes/2.header.jpg    (content/defaultthemes/2.header.jpg)
         content/browser/defaultthemes/2.icon.jpg      (content/defaultthemes/2.icon.jpg)
         content/browser/defaultthemes/2.preview.jpg   (content/defaultthemes/2.preview.jpg)
         content/browser/defaultthemes/3.header.png    (content/defaultthemes/3.header.png)
         content/browser/defaultthemes/3.icon.png      (content/defaultthemes/3.icon.png)
         content/browser/defaultthemes/3.preview.png   (content/defaultthemes/3.preview.png)
         content/browser/defaultthemes/4.header.png    (content/defaultthemes/4.header.png)
         content/browser/defaultthemes/4.icon.png      (content/defaultthemes/4.icon.png)
         content/browser/defaultthemes/4.preview.png   (content/defaultthemes/4.preview.png)
         content/browser/defaultthemes/5.header.png    (content/defaultthemes/5.header.png)
         content/browser/defaultthemes/5.icon.jpg      (content/defaultthemes/5.icon.jpg)
         content/browser/defaultthemes/5.preview.jpg   (content/defaultthemes/5.preview.jpg)
-        content/browser/defaultthemes/dark.icon.svg  (content/defaultthemes/dark.icon.svg)
-        content/browser/defaultthemes/light.icon.svg (content/defaultthemes/light.icon.svg)
+        content/browser/defaultthemes/dark.icon.svg   (content/defaultthemes/dark.icon.svg)
+        content/browser/defaultthemes/light.icon.svg  (content/defaultthemes/light.icon.svg)
 *       content/browser/pageinfo/pageInfo.xul         (content/pageinfo/pageInfo.xul)
         content/browser/pageinfo/pageInfo.js          (content/pageinfo/pageInfo.js)
         content/browser/pageinfo/pageInfo.css         (content/pageinfo/pageInfo.css)
         content/browser/pageinfo/feeds.js             (content/pageinfo/feeds.js)
         content/browser/pageinfo/permissions.js       (content/pageinfo/permissions.js)
         content/browser/pageinfo/security.js          (content/pageinfo/security.js)
         content/browser/robot.ico                     (content/robot.ico)
         content/browser/static-robot.png              (content/static-robot.png)
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -1326,17 +1326,17 @@ CustomizeMode.prototype = {
     Services.prefs.setBoolPref("browser.touchmode.auto", checked);
     // Re-render the menu items since the active mode might have
     // change because of this.
     this.onUIDensityMenuShowing();
     this._onUIChange();
   },
 
   onLWThemesMenuShowing(aEvent) {
-    const DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
+    const DEFAULT_THEME_ID = "default-theme@mozilla.org";
     const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
     const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
     const MAX_THEME_COUNT = 6;
 
     this._clearLWThemesMenu(aEvent.target);
 
     function previewTheme(aPreviewThemeEvent) {
       LightweightThemeManager.previewTheme(
@@ -1349,112 +1349,103 @@ CustomizeMode.prototype = {
     }
 
     let onThemeSelected = panel => {
       this._updateLWThemeButtonIcon();
       this._onUIChange();
       panel.hidePopup();
     };
 
-    AddonManager.getAddonByID(DEFAULT_THEME_ID, aDefaultTheme => {
-      let doc = this.window.document;
+    let doc = this.window.document;
 
-      function buildToolbarButton(aTheme) {
-        let tbb = doc.createElement("toolbarbutton");
-        tbb.theme = aTheme;
-        tbb.setAttribute("label", aTheme.name);
-        if (aDefaultTheme == aTheme) {
-          // The actual icon is set up so it looks nice in about:addons, but
-          // we'd like the version that's correct for the OS we're on, so we set
-          // an attribute that our styling will then use to display the icon.
-          tbb.setAttribute("defaulttheme", "true");
-        } else {
-          tbb.setAttribute("image", aTheme.iconURL);
-        }
-        if (aTheme.description)
-          tbb.setAttribute("tooltiptext", aTheme.description);
-        tbb.setAttribute("tabindex", "0");
-        tbb.classList.add("customization-lwtheme-menu-theme");
-        let isActive = activeThemeID == aTheme.id;
-        tbb.setAttribute("aria-checked", isActive);
-        tbb.setAttribute("role", "menuitemradio");
-        if (isActive) {
-          tbb.setAttribute("active", "true");
-        }
-        tbb.addEventListener("focus", previewTheme);
-        tbb.addEventListener("mouseover", previewTheme);
-        tbb.addEventListener("blur", resetPreview);
-        tbb.addEventListener("mouseout", resetPreview);
+    function buildToolbarButton(aTheme) {
+      let tbb = doc.createElement("toolbarbutton");
+      tbb.theme = aTheme;
+      tbb.setAttribute("label", aTheme.name);
+      tbb.setAttribute("image", aTheme.iconURL);
+      if (aTheme.description)
+        tbb.setAttribute("tooltiptext", aTheme.description);
+      tbb.setAttribute("tabindex", "0");
+      tbb.classList.add("customization-lwtheme-menu-theme");
+      let isActive = activeThemeID == aTheme.id;
+      tbb.setAttribute("aria-checked", isActive);
+      tbb.setAttribute("role", "menuitemradio");
+      if (isActive) {
+        tbb.setAttribute("active", "true");
+      }
+      tbb.addEventListener("focus", previewTheme);
+      tbb.addEventListener("mouseover", previewTheme);
+      tbb.addEventListener("blur", resetPreview);
+      tbb.addEventListener("mouseout", resetPreview);
 
-        return tbb;
-      }
+      return tbb;
+    }
 
-      let themes = [aDefaultTheme];
-      let lwts = LightweightThemeManager.usedThemes;
-      let currentLwt = LightweightThemeManager.currentTheme;
+    let themes = [];
+    let lwts = LightweightThemeManager.usedThemes;
+    let currentLwt = LightweightThemeManager.currentTheme;
+
+    let activeThemeID = currentLwt ? currentLwt.id : DEFAULT_THEME_ID;
 
-      let activeThemeID = currentLwt ? currentLwt.id : DEFAULT_THEME_ID;
-
-      // Move the current theme (if any) and the light/dark themes to the start:
-      let importantThemes = [LIGHT_THEME_ID, DARK_THEME_ID];
-      if (currentLwt && !importantThemes.includes(currentLwt.id)) {
-        importantThemes.push(currentLwt.id);
+    // Move the current theme (if any) and the light/dark themes to the start:
+    let importantThemes = [DEFAULT_THEME_ID, LIGHT_THEME_ID, DARK_THEME_ID];
+    if (currentLwt && !importantThemes.includes(currentLwt.id)) {
+      importantThemes.push(currentLwt.id);
+    }
+    for (let importantTheme of importantThemes) {
+      let themeIndex = lwts.findIndex(theme => theme.id == importantTheme);
+      if (themeIndex > -1) {
+        themes.push(...lwts.splice(themeIndex, 1));
       }
-      for (let importantTheme of importantThemes) {
-        let themeIndex = lwts.findIndex(theme => theme.id == importantTheme);
-        if (themeIndex > -1) {
-          themes.push(...lwts.splice(themeIndex, 1));
-        }
-      }
-      themes = themes.concat(lwts);
-      if (themes.length > MAX_THEME_COUNT)
-        themes.length = MAX_THEME_COUNT;
+    }
+    themes = themes.concat(lwts);
+    if (themes.length > MAX_THEME_COUNT)
+      themes.length = MAX_THEME_COUNT;
 
-      let footer = doc.getElementById("customization-lwtheme-menu-footer");
-      let panel = footer.parentNode;
-      let recommendedLabel = doc.getElementById("customization-lwtheme-menu-recommended");
-      for (let theme of themes) {
-        let button = buildToolbarButton(theme);
-        button.addEventListener("command", () => {
-          if ("userDisabled" in button.theme)
-            button.theme.userDisabled = false;
-          else
-            LightweightThemeManager.currentTheme = button.theme;
-          onThemeSelected(panel);
-        });
-        panel.insertBefore(button, recommendedLabel);
-      }
+    let footer = doc.getElementById("customization-lwtheme-menu-footer");
+    let panel = footer.parentNode;
+    let recommendedLabel = doc.getElementById("customization-lwtheme-menu-recommended");
+    for (let theme of themes) {
+      let button = buildToolbarButton(theme);
+      button.addEventListener("command", () => {
+        if ("userDisabled" in button.theme)
+          button.theme.userDisabled = false;
+        else
+          LightweightThemeManager.currentTheme = button.theme;
+        onThemeSelected(panel);
+      });
+      panel.insertBefore(button, recommendedLabel);
+    }
 
-      let lwthemePrefs = Services.prefs.getBranch("lightweightThemes.");
-      let recommendedThemes = lwthemePrefs.getStringPref("recommendedThemes");
-      recommendedThemes = JSON.parse(recommendedThemes);
-      let sb = Services.strings.createBundle("chrome://browser/locale/lightweightThemes.properties");
-      for (let theme of recommendedThemes) {
-        try {
-          theme.name = sb.GetStringFromName("lightweightThemes." + theme.id + ".name");
-          theme.description = sb.GetStringFromName("lightweightThemes." + theme.id + ".description");
-        } catch (ex) {
-          // If finding strings for this failed, just don't build it. This can
-          // happen for users with 'older' recommended themes lists, some of which
-          // have since been removed from Firefox.
-          continue;
-        }
-        let button = buildToolbarButton(theme);
-        button.addEventListener("command", () => {
-          LightweightThemeManager.setLocalTheme(button.theme);
-          recommendedThemes = recommendedThemes.filter((aTheme) => { return aTheme.id != button.theme.id; });
-          lwthemePrefs.setStringPref("recommendedThemes",
-                                     JSON.stringify(recommendedThemes));
-          onThemeSelected(panel);
-        });
-        panel.insertBefore(button, footer);
+    let lwthemePrefs = Services.prefs.getBranch("lightweightThemes.");
+    let recommendedThemes = lwthemePrefs.getStringPref("recommendedThemes");
+    recommendedThemes = JSON.parse(recommendedThemes);
+    let sb = Services.strings.createBundle("chrome://browser/locale/lightweightThemes.properties");
+    for (let theme of recommendedThemes) {
+      try {
+        theme.name = sb.GetStringFromName("lightweightThemes." + theme.id + ".name");
+        theme.description = sb.GetStringFromName("lightweightThemes." + theme.id + ".description");
+      } catch (ex) {
+        // If finding strings for this failed, just don't build it. This can
+        // happen for users with 'older' recommended themes lists, some of which
+        // have since been removed from Firefox.
+        continue;
       }
-      let hideRecommendedLabel = (footer.previousSibling == recommendedLabel);
-      recommendedLabel.hidden = hideRecommendedLabel;
-    });
+      let button = buildToolbarButton(theme);
+      button.addEventListener("command", () => {
+        LightweightThemeManager.setLocalTheme(button.theme);
+        recommendedThemes = recommendedThemes.filter((aTheme) => { return aTheme.id != button.theme.id; });
+        lwthemePrefs.setStringPref("recommendedThemes",
+                                   JSON.stringify(recommendedThemes));
+        onThemeSelected(panel);
+      });
+      panel.insertBefore(button, footer);
+    }
+    let hideRecommendedLabel = (footer.previousSibling == recommendedLabel);
+    recommendedLabel.hidden = hideRecommendedLabel;
   },
 
   _clearLWThemesMenu(panel) {
     let footer = this.document.getElementById("customization-lwtheme-menu-footer");
     let recommendedLabel = this.document.getElementById("customization-lwtheme-menu-recommended");
     for (let element of [footer, recommendedLabel]) {
       while (element.previousSibling &&
              element.previousSibling.localName == "toolbarbutton") {
--- a/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
+++ b/browser/components/customizableui/test/browser_1007336_lwthemes_in_customize_mode.js
@@ -1,15 +1,15 @@
 /* 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 DEFAULT_THEME_ID = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
+const DEFAULT_THEME_ID = "default-theme@mozilla.org";
 const LIGHT_THEME_ID = "firefox-compact-light@mozilla.org";
 const DARK_THEME_ID = "firefox-compact-dark@mozilla.org";
 const {LightweightThemeManager} = ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm", {});
 
 add_task(async function() {
   Services.prefs.clearUserPref("lightweightThemes.usedThemes");
   Services.prefs.clearUserPref("lightweightThemes.recommendedThemes");
 
@@ -90,17 +90,18 @@ add_task(async function() {
     themeCount++;
     iterNode = iterNode.nextSibling;
   }
   is(themeCount, 4,
      "There should be four themes in the 'My Themes' section");
 
   let defaultTheme = header.nextSibling;
   defaultTheme.doCommand();
-  is(Services.prefs.getCharPref("lightweightThemes.selectedThemeID"), "", "No lwtheme should be selected");
+  is(Services.prefs.getCharPref("lightweightThemes.selectedThemeID"),
+     DEFAULT_THEME_ID, "Default theme should be selected");
 
   // ensure current theme isn't set to "Default"
   popupShownPromise = popupShown(popup);
   EventUtils.synthesizeMouseAtCenter(themesButton, {});
   info("Clicked on themes button a fourth time");
   await popupShownPromise;
 
   firstLWTheme = recommendedHeader.nextSibling;
--- a/browser/installer/allowed-dupes.mn
+++ b/browser/installer/allowed-dupes.mn
@@ -78,17 +78,16 @@ browser/chrome/icons/default/default128.
 browser/chrome/pdfjs/content/web/images/findbarButton-next-rtl.png
 browser/chrome/pdfjs/content/web/images/findbarButton-next-rtl@2x.png
 browser/chrome/pdfjs/content/web/images/findbarButton-next.png
 browser/chrome/pdfjs/content/web/images/findbarButton-next@2x.png
 browser/chrome/pdfjs/content/web/images/findbarButton-previous-rtl.png
 browser/chrome/pdfjs/content/web/images/findbarButton-previous-rtl@2x.png
 browser/chrome/pdfjs/content/web/images/findbarButton-previous.png
 browser/chrome/pdfjs/content/web/images/findbarButton-previous@2x.png
-browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
 browser/features/firefox@getpocket.com/chrome/skin/linux/menuPanel.png
 browser/features/firefox@getpocket.com/chrome/skin/linux/menuPanel@2x.png
 browser/features/firefox@getpocket.com/chrome/skin/windows/menuPanel.png
 browser/features/firefox@getpocket.com/chrome/skin/windows/menuPanel@2x.png
 chrome.manifest
 chrome/toolkit/skin/classic/global/autocomplete.css
 chrome/toolkit/skin/classic/global/button.css
 chrome/toolkit/skin/classic/global/checkbox.css
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -585,18 +585,16 @@
 #endif
 
 ; [Browser Chrome Files]
 @RESPATH@/browser/chrome.manifest
 @RESPATH@/browser/chrome/browser@JAREXT@
 @RESPATH@/browser/chrome/browser.manifest
 @RESPATH@/browser/chrome/pdfjs.manifest
 @RESPATH@/browser/chrome/pdfjs/*
-@RESPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/chrome.manifest
-@RESPATH@/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
 @RESPATH@/chrome/toolkit@JAREXT@
 @RESPATH@/chrome/toolkit.manifest
 @RESPATH@/chrome/recording.manifest
 @RESPATH@/chrome/recording/*
 #ifdef MOZ_GTK
 @RESPATH@/browser/chrome/icons/default/default16.png
 @RESPATH@/browser/chrome/icons/default/default32.png
 @RESPATH@/browser/chrome/icons/default/default48.png
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -620,19 +620,16 @@ safebrowsing.reportedHarmfulSite=Reporte
 # of tabs in the current browser window. It will always be 2 at least.
 # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
 ctrlTab.listAllTabs.label=;List All #1 Tabs
 
 # LOCALIZATION NOTE (addKeywordTitleAutoFill): %S will be replaced by the page's title
 # Used as the bookmark name when saving a keyword for a search field.
 addKeywordTitleAutoFill=Search %S
 
-extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name=Default
-extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description=The default theme.
-
 # safeModeRestart
 safeModeRestartPromptTitle=Restart with Add-ons Disabled
 safeModeRestartPromptMessage=Are you sure you want to disable all add-ons and restart?
 safeModeRestartButton=Restart
 
 # LOCALIZATION NOTE (browser.menu.showCharacterEncoding): Set to the string
 # "true" (spelled and capitalized exactly that way) to show the "Text
 # Encoding" menu in the main Firefox button on Windows. Any other value will
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -49,13 +49,12 @@ browser.jar:
 * skin/classic/browser/preferences/in-content/dialog.css      (preferences/in-content/dialog.css)
   skin/classic/browser/preferences/applications.css   (preferences/applications.css)
   skin/classic/browser/tabbrowser/tabDragIndicator.png      (tabbrowser/tabDragIndicator.png)
 
   skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png)
 
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 % override chrome://browser/skin/feeds/audioFeedIcon.png              chrome://browser/skin/feeds/feedIcon.png
 % override chrome://browser/skin/feeds/audioFeedIcon16.png            chrome://browser/skin/feeds/feedIcon16.png
 % override chrome://browser/skin/feeds/videoFeedIcon.png              chrome://browser/skin/feeds/feedIcon.png
 % override chrome://browser/skin/feeds/videoFeedIcon16.png            chrome://browser/skin/feeds/feedIcon16.png
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -58,14 +58,13 @@ browser.jar:
 * skin/classic/browser/preferences/in-content/dialog.css      (preferences/in-content/dialog.css)
   skin/classic/browser/preferences/applications.css         (preferences/applications.css)
   skin/classic/browser/tabbrowser/tabDragIndicator.png                   (tabbrowser/tabDragIndicator.png)
   skin/classic/browser/tabbrowser/tabDragIndicator@2x.png                (tabbrowser/tabDragIndicator@2x.png)
   skin/classic/browser/sync-desktopIcon.svg  (../shared/sync-desktopIcon.svg)
   skin/classic/browser/sync-mobileIcon.svg  (../shared/sync-mobileIcon.svg)
   skin/classic/browser/e10s-64@2x.png                                  (../shared/e10s-64@2x.png)
 
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 % override chrome://browser/skin/feeds/audioFeedIcon.png                   chrome://browser/skin/feeds/feedIcon.png
 % override chrome://browser/skin/feeds/audioFeedIcon16.png                 chrome://browser/skin/feeds/feedIcon16.png
 % override chrome://browser/skin/feeds/videoFeedIcon.png                   chrome://browser/skin/feeds/feedIcon.png
 % override chrome://browser/skin/feeds/videoFeedIcon16.png                 chrome://browser/skin/feeds/feedIcon16.png
 % override chrome://browser/skin/notification-icons/geo-detailed.svg       chrome://browser/skin/notification-icons/geo.svg
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -60,14 +60,13 @@ browser.jar:
   skin/classic/browser/window-controls/minimize.svg              (window-controls/minimize.svg)
   skin/classic/browser/window-controls/minimize-highcontrast.svg (window-controls/minimize-highcontrast.svg)
   skin/classic/browser/window-controls/minimize-themes.svg       (window-controls/minimize-themes.svg)
   skin/classic/browser/window-controls/restore.svg               (window-controls/restore.svg)
   skin/classic/browser/window-controls/restore-highcontrast.svg  (window-controls/restore-highcontrast.svg)
   skin/classic/browser/window-controls/restore-themes.svg        (window-controls/restore-themes.svg)
   skin/classic/browser/e10s-64@2x.png                            (../shared/e10s-64@2x.png)
 
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
 % override chrome://browser/skin/page-livemarks.png                   chrome://browser/skin/feeds/feedIcon16.png
 % override chrome://browser/skin/feeds/audioFeedIcon.png              chrome://browser/skin/feeds/feedIcon.png
 % override chrome://browser/skin/feeds/audioFeedIcon16.png            chrome://browser/skin/feeds/feedIcon16.png
 % override chrome://browser/skin/feeds/videoFeedIcon.png              chrome://browser/skin/feeds/feedIcon.png
 % override chrome://browser/skin/feeds/videoFeedIcon16.png            chrome://browser/skin/feeds/feedIcon16.png
--- a/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
+++ b/toolkit/locales/en-US/chrome/mozapps/extensions/extensions.properties
@@ -145,12 +145,16 @@ type.themes.name=Themes
 type.locale.name=Languages
 type.plugin.name=Plugins
 type.dictionary.name=Dictionaries
 type.service.name=Services
 type.experiment.name=Experiments
 type.legacy.name=Legacy Extensions
 type.unsupported.name=Unsupported
 
+# LOCALIZATION NOTE (defaultTheme.name): This is displayed in about:addons -> Appearance
+defaultTheme.name=Default
+defaultTheme.description=The default theme.
+
 #LOCALIZATION NOTE(legacyWarning.description) %S is the brandShortName
 legacyWarning.description=Missing something? Some extensions are no longer supported by %S.
 #LOCALIZATION NOTE(legacyThemeWarning.description) %S is the brandShortName
 legacyThemeWarning.description=Missing something? Some themes are no longer supported by %S.
--- a/toolkit/mozapps/extensions/LightweightThemeManager.jsm
+++ b/toolkit/mozapps/extensions/LightweightThemeManager.jsm
@@ -13,16 +13,17 @@ ChromeUtils.import("resource://gre/modul
 
 const ID_SUFFIX              = "@personas.mozilla.org";
 const PREF_LWTHEME_TO_SELECT = "extensions.lwThemeToSelect";
 const ADDON_TYPE             = "theme";
 const ADDON_TYPE_WEBEXT      = "webextension-theme";
 
 const URI_EXTENSION_STRINGS  = "chrome://mozapps/locale/extensions/extensions.properties";
 
+const DEFAULT_THEME_ID = "default-theme@mozilla.org";
 const DEFAULT_MAX_USED_THEMES_COUNT = 30;
 
 const MAX_PREVIEW_SECONDS = 30;
 
 const MANDATORY = ["id", "name"];
 const OPTIONAL = ["headerURL", "footerURL", "textcolor", "accentcolor",
                   "iconURL", "previewURL", "author", "description",
                   "homepageURL", "updateURL", "version"];
@@ -524,17 +525,17 @@ AddonWrapper.prototype = {
   get permissions() {
     let permissions = 0;
 
     // Do not allow uninstall of builtIn themes.
     if (!LightweightThemeManager._builtInThemes.has(themeFor(this).id))
       permissions = AddonManager.PERM_CAN_UNINSTALL;
     if (this.userDisabled)
       permissions |= AddonManager.PERM_CAN_ENABLE;
-    else
+    else if (themeFor(this).id != DEFAULT_THEME_ID)
       permissions |= AddonManager.PERM_CAN_DISABLE;
     return permissions;
   },
 
   get userDisabled() {
     let id = themeFor(this).id;
     if (_themeIDBeingEnabled == id)
       return false;
@@ -607,16 +608,28 @@ AddonWrapper.prototype = {
   },
 
   // Lightweight themes are never blocklisted
   get blocklistState() {
     return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
   }
 };
 
+let brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+let extensionsBundle = Services.strings.createBundle(
+  "chrome://mozapps/locale/extensions/extensions.properties"
+);
+LightweightThemeManager.addBuiltInTheme({
+  id: DEFAULT_THEME_ID,
+  name: extensionsBundle.GetStringFromName("defaultTheme.name"),
+  description: extensionsBundle.GetStringFromName("defaultTheme.description"),
+  iconURL: "chrome://mozapps/content/extensions/default-theme-icon.svg",
+  author: brandBundle.GetStringFromName("vendorShortName"),
+});
+
 ["description", "homepageURL", "iconURL"].forEach(function(prop) {
   Object.defineProperty(AddonWrapper.prototype, prop, {
     get() {
       let theme = themeFor(this);
       return prop in theme ? theme[prop] : null;
     },
     enumarable: true,
   });
rename from browser/base/content/default-theme-icon.svg
rename to toolkit/mozapps/extensions/content/default-theme-icon.svg
--- a/toolkit/mozapps/extensions/internal/XPIInstall.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIInstall.jsm
@@ -56,18 +56,16 @@ XPCOMUtils.defineLazyServiceGetter(this,
 
 ChromeUtils.defineModuleGetter(this, "XPIInternal",
                                "resource://gre/modules/addons/XPIProvider.jsm");
 ChromeUtils.defineModuleGetter(this, "XPIProvider",
                                "resource://gre/modules/addons/XPIProvider.jsm");
 
 const PREF_ALLOW_NON_RESTARTLESS      = "extensions.legacy.non-restartless.enabled";
 
-const DEFAULT_SKIN = "classic/1.0";
-
 /* globals AddonInternal, BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, KEY_APP_TEMPORARY, TEMPORARY_ADDON_SUFFIX, SIGNED_TYPES, TOOLKIT_ID, XPIDatabase, XPIStates, getExternalType, isTheme, isUsableAddon, isWebExtension, mustSign, recordAddonTelemetry */
 const XPI_INTERNAL_SYMBOLS = [
   "AddonInternal",
   "BOOTSTRAP_REASONS",
   "KEY_APP_SYSTEM_ADDONS",
   "KEY_APP_SYSTEM_DEFAULTS",
   "KEY_APP_TEMPORARY",
   "SIGNED_TYPES",
@@ -630,22 +628,20 @@ async function loadManifestFromRDF(aUri,
       platform.abi = targetPlatform.substring(pos + 1);
     } else {
       platform.os = targetPlatform;
     }
 
     addon.targetPlatforms.push(platform);
   }
 
-  // A theme's userDisabled value is true if the theme is not the selected skin
-  // or if there is an active lightweight theme. We ignore whether softblocking
-  // is in effect since it would change the active theme.
+  // A theme's userDisabled value is true if there is an active lightweight theme.
+  // We ignore whether softblocking is in effect since it would change the active theme.
   if (isTheme(addon.type)) {
-    addon.userDisabled = !!LightweightThemeManager.currentTheme ||
-                         addon.internalName != DEFAULT_SKIN;
+    addon.userDisabled = !!LightweightThemeManager.currentTheme;
   } else if (addon.type == "experiment") {
     // Experiments are disabled by default. It is up to the Experiments Manager
     // to enable them (it drives installation).
     addon.userDisabled = true;
   } else {
     addon.userDisabled = false;
   }
 
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -82,18 +82,16 @@ const PREF_SYSTEM_ADDON_SET           = 
 const PREF_SYSTEM_ADDON_UPDATE_URL    = "extensions.systemAddon.update.url";
 const PREF_ALLOW_LEGACY               = "extensions.legacy.enabled";
 
 const PREF_EM_MIN_COMPAT_APP_VERSION      = "extensions.minCompatibleAppVersion";
 const PREF_EM_MIN_COMPAT_PLATFORM_VERSION = "extensions.minCompatiblePlatformVersion";
 
 const PREF_EM_LAST_APP_BUILD_ID       = "extensions.lastAppBuildId";
 
-const DEFAULT_SKIN = "classic/1.0";
-
 // Specify a list of valid built-in add-ons to load.
 const BUILT_IN_ADDONS_URI             = "chrome://browser/content/built_in_addons.json";
 
 const OBSOLETE_PREFERENCES = [
   "extensions.bootstrappedAddons",
   "extensions.enabledAddons",
   "extensions.xpiState",
   "extensions.installCache",
@@ -107,18 +105,16 @@ const DIR_STAGE                       = 
 const DIR_TRASH                       = "trash";
 
 const FILE_XPI_STATES                 = "addonStartup.json.lz4";
 const FILE_DATABASE                   = "extensions.json";
 const FILE_RDF_MANIFEST               = "install.rdf";
 const FILE_WEB_MANIFEST               = "manifest.json";
 const FILE_XPI_ADDONS_LIST            = "extensions.ini";
 
-const ADDON_ID_DEFAULT_THEME          = "{972ce4c6-7e08-4474-a285-3208198ce6fd}";
-
 const KEY_PROFILEDIR                  = "ProfD";
 const KEY_ADDON_APP_DIR               = "XREAddonAppDir";
 const KEY_APP_DISTRIBUTION            = "XREAppDist";
 const KEY_APP_FEATURES                = "XREAppFeat";
 
 const KEY_APP_PROFILE                 = "app-profile";
 const KEY_APP_SYSTEM_ADDONS           = "app-system-addons";
 const KEY_APP_SYSTEM_DEFAULTS         = "app-system-defaults";
@@ -137,17 +133,17 @@ const STARTUP_MTIME_SCOPES = [KEY_APP_GL
 
 const NOTIFICATION_FLUSH_PERMISSIONS  = "flush-pending-permissions";
 const XPI_PERMISSION                  = "install";
 
 const TOOLKIT_ID                      = "toolkit@mozilla.org";
 
 const XPI_SIGNATURE_CHECK_PERIOD      = 24 * 60 * 60;
 
-XPCOMUtils.defineConstant(this, "DB_SCHEMA", 24);
+XPCOMUtils.defineConstant(this, "DB_SCHEMA", 25);
 
 const NOTIFICATION_TOOLBOX_CONNECTION_CHANGE      = "toolbox-connection-change";
 
 // Properties that exist in the install manifest
 const PROP_LOCALE_SINGLE = ["name", "description", "creator", "homepageURL"];
 const PROP_LOCALE_MULTI  = ["developers", "translators", "contributors"];
 
 // Properties to cache and reload when an addon installation is pending
@@ -211,17 +207,16 @@ const SIGNED_TYPES = new Set([
   "webextension",
   "webextension-langpack",
   "webextension-theme",
 ]);
 
 const LEGACY_TYPES = new Set([
   "apiextension",
   "extension",
-  "theme",
 ]);
 
 const ALL_EXTERNAL_TYPES = new Set([
   "dictionary",
   "extension",
   "experiment",
   "locale",
   "theme",
@@ -293,17 +288,16 @@ function loadLazyObjects() {
     wantGlobalProperties: ["ChromeUtils", "TextDecoder"],
   });
 
   Object.assign(scope, {
     ADDON_SIGNING: AddonSettings.ADDON_SIGNING,
     SIGNED_TYPES,
     BOOTSTRAP_REASONS,
     DB_SCHEMA,
-    DEFAULT_SKIN,
     AddonInternal,
     XPIProvider,
     XPIStates,
     syncLoadManifestFromFile,
     isUsableAddon,
     recordAddonTelemetry,
     flushChromeCaches,
     descriptorToPath,
@@ -793,19 +787,16 @@ function isDisabledLegacy(addon) {
 /**
  * Calculates whether an add-on should be appDisabled or not.
  *
  * @param  aAddon
  *         The add-on to check
  * @return true if the add-on should not be appDisabled
  */
 function isUsableAddon(aAddon) {
-  if (aAddon.type == "theme")
-    return aAddon.internalName == DEFAULT_SKIN;
-
   if (mustSign(aAddon.type) && !aAddon.isCorrectlySigned) {
     logger.warn(`Add-on ${aAddon.id} is not correctly signed.`);
     if (Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)) {
       logger.warn(`Preference ${PREF_XPI_SIGNATURES_DEV_ROOT} is set.`);
     }
     return false;
   }
 
@@ -1279,24 +1270,17 @@ class XPIState {
   syncWithDB(aDBAddon, aUpdated = false) {
     logger.debug("Updating XPIState for " + JSON.stringify(aDBAddon));
     // If the add-on changes from disabled to enabled, we should re-check the modified time.
     // If this is a newly found add-on, it won't have an 'enabled' field but we
     // did a full recursive scan in that case, so we don't need to do it again.
     // We don't use aDBAddon.active here because it's not updated until after restart.
     let mustGetMod = (aDBAddon.visible && !aDBAddon.disabled && !this.enabled);
 
-    // We need to treat XUL themes specially here, since lightweight
-    // themes require the default theme's chrome to be registered even
-    // though we report it as disabled for UI purposes.
-    if (aDBAddon.type == "theme") {
-      this.enabled = aDBAddon.internalName == DEFAULT_SKIN;
-    } else {
-      this.enabled = aDBAddon.visible && !aDBAddon.disabled;
-    }
+    this.enabled = aDBAddon.visible && !aDBAddon.disabled;
 
     this.version = aDBAddon.version;
     this.type = aDBAddon.type;
     this.startupData = aDBAddon.startupData;
 
     this.bootstrapped = !!aDBAddon.bootstrap;
     if (this.bootstrapped) {
       this.hasEmbeddedWebExtension = aDBAddon.hasEmbeddedWebExtension;
@@ -2138,19 +2122,16 @@ var XPIProvider = {
         // effect
         Services.obs.notifyObservers(null, "chrome-flush-skin-caches");
         Services.obs.notifyObservers(null, "chrome-flush-caches");
       }
 
       if (AppConstants.MOZ_CRASHREPORTER) {
         // Annotate the crash report with relevant add-on information.
         try {
-          Services.appinfo.annotateCrashReport("Theme", DEFAULT_SKIN);
-        } catch (e) { }
-        try {
           Services.appinfo.annotateCrashReport("EMCheckCompatibility",
                                                AddonManager.checkCompatibility);
         } catch (e) { }
         this.addAddonsToCrashReporter();
       }
 
       try {
         AddonManagerPrivate.recordTimestamp("XPI_bootstrap_addons_begin");
@@ -2967,40 +2948,16 @@ var XPIProvider = {
   },
 
   getDependentAddons(aAddon) {
     return Array.from(XPIDatabase.getAddons())
                 .filter(addon => addon.dependencies.includes(aAddon.id));
   },
 
   /**
-   * Returns the add-on state data for the restartful extensions which
-   * should be available in safe mode. In particular, this means the
-   * default theme, and only the default theme.
-   *
-   * @returns {object}
-   */
-  getSafeModeExtensions() {
-    let loc = XPIStates.getLocation(KEY_APP_GLOBAL);
-    let state = loc.get(ADDON_ID_DEFAULT_THEME);
-
-    // Use the default state data for the default theme, but always mark
-    // it enabled, in case another theme is enabled in normal mode.
-    let addonData = state.toJSON();
-    addonData.enabled = true;
-
-    return {
-      [KEY_APP_GLOBAL]: {
-        path: loc.path,
-        addons: { [ADDON_ID_DEFAULT_THEME]: addonData },
-      },
-    };
-  },
-
-  /**
    * Checks for any changes that have occurred since the last time the
    * application was launched.
    *
    * @param  aAppChanged
    *         A tri-state value. Undefined means the current profile was created
    *         for this session, true means the profile already existed but was
    *         last used with an application with a different version number,
    *         false means that the profile was last used by this version of the
@@ -3089,22 +3046,16 @@ var XPIProvider = {
                                                                          aOldAppVersion,
                                                                          aOldPlatformVersion,
                                                                          updateReasons.includes("schemaChanged"));
         } catch (e) {
           logger.error("Failed to process extension changes at startup", e);
         }
       }
 
-      if (Services.appinfo.inSafeMode) {
-        aomStartup.initializeExtensions(this.getSafeModeExtensions());
-        logger.debug("Initialized safe mode add-ons");
-        return false;
-      }
-
       // If the application crashed before completing any pending operations then
       // we should perform them now.
       if (extensionListChanged || hasPendingChanges) {
         this._updateActiveAddons();
 
         // Serialize and deserialize so we get the expected JSON data.
         let state = JSON.parse(JSON.stringify(XPIStates));
         aomStartup.initializeExtensions(state);
@@ -3639,19 +3590,16 @@ var XPIProvider = {
     if (!isTheme(aType))
       return;
 
     let addons = XPIDatabase.getAddonsByType("theme", "webextension-theme");
     for (let theme of addons) {
       if (isWebExtension(theme.type) && theme.visible && theme.id != aId)
         this.updateAddonDisabledState(theme, true, undefined);
     }
-
-    let defaultTheme = XPIDatabase.getVisibleAddonForInternalName(DEFAULT_SKIN);
-    this.updateAddonDisabledState(defaultTheme, aId && aId != defaultTheme.id);
   },
 
   /**
    * Update the appDisabled property for all add-ons.
    */
   updateAddonAppDisabledStates() {
     let addons = XPIDatabase.getAddons();
     for (let addon of addons) {
@@ -4858,18 +4806,17 @@ AddonWrapper.prototype = {
       if (this.hasResource("icon.png")) {
         icons[32] = icons[48] = this.getResourceURI("icon.png").spec;
       }
       if (this.hasResource("icon64.png")) {
         icons[64] = this.getResourceURI("icon64.png").spec;
       }
     }
 
-    let canUseIconURLs = this.isActive ||
-      (addon.type == "theme" && addon.internalName == DEFAULT_SKIN);
+    let canUseIconURLs = this.isActive;
     if (canUseIconURLs && addon.iconURL) {
       icons[32] = addon.iconURL;
       icons[48] = addon.iconURL;
     }
 
     if (canUseIconURLs && addon.icon64URL) {
       icons[64] = addon.icon64URL;
     }
@@ -5026,26 +4973,18 @@ AddonWrapper.prototype = {
   },
   set userDisabled(val) {
     let addon = addonFor(this);
     if (val == this.userDisabled) {
       return val;
     }
 
     if (addon.inDatabase) {
-      let theme = isTheme(addon.type);
-      if (theme && val) {
-        if (addon.internalName == DEFAULT_SKIN)
-          throw new Error("Cannot disable the default theme");
-
-        let defaultTheme = XPIDatabase.getVisibleAddonForInternalName(DEFAULT_SKIN);
-        XPIProvider.updateAddonDisabledState(defaultTheme, false);
-      }
-      if (!(theme && val) || isWebExtension(addon.type)) {
-        // hidden and system add-ons should not be user disasbled,
+      if (!(isTheme(addon.type) && val) || isWebExtension(addon.type)) {
+        // hidden and system add-ons should not be user disabled,
         // as there is no UI to re-enable them.
         if (this.hidden) {
           throw new Error(`Cannot disable hidden add-on ${addon.id}`);
         }
         XPIProvider.updateAddonDisabledState(addon, val);
       }
     } else {
       addon.userDisabled = val;
@@ -5060,18 +4999,16 @@ AddonWrapper.prototype = {
   set softDisabled(val) {
     let addon = addonFor(this);
     if (val == addon.softDisabled)
       return val;
 
     if (addon.inDatabase) {
       // When softDisabling a theme just enable the active theme
       if (isTheme(addon.type) && val && !addon.userDisabled) {
-        if (addon.internalName == DEFAULT_SKIN)
-          throw new Error("Cannot disable the default theme");
         if (isWebExtension(addon.type))
           XPIProvider.updateAddonDisabledState(addon, undefined, val);
       } else {
         XPIProvider.updateAddonDisabledState(addon, undefined, val);
       }
     } else if (!addon.userDisabled) {
       // Only set softDisabled if not already disabled
       addon.softDisabled = val;
--- a/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
+++ b/toolkit/mozapps/extensions/internal/XPIProviderUtils.js
@@ -3,17 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 // These are injected from XPIProvider.jsm
 /* globals ADDON_SIGNING, SIGNED_TYPES, BOOTSTRAP_REASONS, DB_SCHEMA,
           AddonInternal, XPIProvider, XPIStates, syncLoadManifestFromFile,
           isUsableAddon, recordAddonTelemetry,
-          flushChromeCaches, descriptorToPath, DEFAULT_SKIN */
+          flushChromeCaches, descriptorToPath */
 
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   AddonManager: "resource://gre/modules/AddonManager.jsm",
   AddonManagerPrivate: "resource://gre/modules/AddonManager.jsm",
   AddonRepository: "resource://gre/modules/addons/AddonRepository.jsm",
   DeferredTask: "resource://gre/modules/DeferredTask.jsm",
@@ -781,38 +781,16 @@ this.XPIDatabase = {
       AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_byType", XPIProvider.runPhase);
       this.syncLoadDB(true);
     }
 
     return _filterDB(this.addonDB, aAddon => aTypes.includes(aAddon.type));
   },
 
   /**
-   * Synchronously gets an add-on with a particular internalName.
-   *
-   * @param  aInternalName
-   *         The internalName of the add-on to retrieve
-   * @return a DBAddonInternal
-   */
-  getVisibleAddonForInternalName(aInternalName) {
-    if (!this.addonDB) {
-      // This may be called when the DB hasn't otherwise been loaded
-      logger.warn(`Synchronous load of XPI database due to ` +
-                  `getVisibleAddonForInternalName. Stack: ${Error().stack}`);
-      AddonManagerPrivate.recordSimpleMeasure("XPIDB_lateOpen_forInternalName",
-          XPIProvider.runPhase);
-      this.syncLoadDB(true);
-    }
-
-    return _findAddon(this.addonDB,
-                      aAddon => aAddon.visible &&
-                                (aAddon.internalName == aInternalName));
-  },
-
-  /**
    * Asynchronously gets all add-ons with pending operations.
    *
    * @param  aTypes
    *         The types of add-ons to retrieve or null to get all types
    * @param  aCallback
    *         A callback to pass the array of DBAddonInternal to
    */
   getVisibleAddonsWithPendingOperations(aTypes, aCallback) {
@@ -1172,20 +1150,16 @@ this.XPIDatabaseReconcile = {
     // foreign and should default to enabled.
     aNewAddon.foreignInstall = isDetectedInstall &&
                                aInstallLocation.name != KEY_APP_SYSTEM_ADDONS &&
                                aInstallLocation.name != KEY_APP_SYSTEM_DEFAULTS;
 
     // appDisabled depends on whether the add-on is a foreignInstall so update
     aNewAddon.appDisabled = !isUsableAddon(aNewAddon);
 
-    // The default theme is never a foreign install
-    if (aNewAddon.type == "theme" && aNewAddon.internalName == DEFAULT_SKIN)
-      aNewAddon.foreignInstall = false;
-
     if (isDetectedInstall && aNewAddon.foreignInstall) {
       // If the add-on is a foreign install and is in a scope where add-ons
       // that were dropped in should default to disabled then disable it
       let disablingScopes = Services.prefs.getIntPref(PREF_EM_AUTO_DISABLED_SCOPES, 0);
       if (aInstallLocation.scope & disablingScopes) {
         logger.warn("Disabling foreign installed add-on " + aNewAddon.id + " in "
             + aInstallLocation.name);
         aNewAddon.userDisabled = true;
@@ -1540,21 +1514,17 @@ this.XPIDatabaseReconcile = {
       if (!previousAddon) {
         // If we had a manifest for this add-on it was a staged install and
         // so wasn't something recovered from a corrupt database
         let wasStaged = !!loadedManifest(currentAddon._installLocation, id);
 
         // We might be recovering from a corrupt database, if so use the
         // list of known active add-ons to update the new add-on
         if (!wasStaged && XPIDatabase.activeBundles) {
-          // For themes we know which is active by the current skin setting
-          if (currentAddon.type == "theme")
-            isActive = currentAddon.internalName == DEFAULT_SKIN;
-          else
-            isActive = XPIDatabase.activeBundles.includes(currentAddon.path);
+          isActive = XPIDatabase.activeBundles.includes(currentAddon.path);
 
           if (currentAddon.type == "webextension-theme")
             currentAddon.userDisabled = !isActive;
 
           // If the add-on wasn't active and it isn't already disabled in some way
           // then it was probably either softDisabled or userDisabled
           if (!isActive && !currentAddon.disabled) {
             // If the add-on is softblocked then assume it is softDisabled
--- a/toolkit/mozapps/extensions/jar.mn
+++ b/toolkit/mozapps/extensions/jar.mn
@@ -21,13 +21,14 @@ toolkit.jar:
   content/mozapps/extensions/update.css                         (content/update.css)
   content/mozapps/extensions/eula.xul                           (content/eula.xul)
   content/mozapps/extensions/eula.js                            (content/eula.js)
   content/mozapps/extensions/newaddon.xul                       (content/newaddon.xul)
   content/mozapps/extensions/newaddon.js                        (content/newaddon.js)
   content/mozapps/extensions/pluginPrefs.xul                    (content/pluginPrefs.xul)
   content/mozapps/extensions/pluginPrefs.js                     (content/pluginPrefs.js)
   content/mozapps/extensions/OpenH264-license.txt               (content/OpenH264-license.txt)
+  content/mozapps/extensions/default-theme-icon.svg             (content/default-theme-icon.svg)
 #endif
   content/mozapps/xpinstall/xpinstallConfirm.xul                (content/xpinstallConfirm.xul)
   content/mozapps/xpinstall/xpinstallConfirm.js                 (content/xpinstallConfirm.js)
   content/mozapps/xpinstall/xpinstallConfirm.css                (content/xpinstallConfirm.css)
   content/mozapps/xpinstall/xpinstallItem.xml                   (content/xpinstallItem.xml)
--- a/toolkit/mozapps/extensions/test/xpcshell/test_addonStartup.js
+++ b/toolkit/mozapps/extensions/test/xpcshell/test_addonStartup.js
@@ -1,28 +1,15 @@
 "use strict";
 
 add_task(async function test_XPIStates_invalid_paths() {
   let {path} = gAddonStartup;
 
   let startupDatasets = [
     {
-      "app-global": {
-        "addons": {
-          "{972ce4c6-7e08-4474-a285-3208198ce6fd}": {
-            "enabled": true,
-            "lastModifiedTime": 1,
-            "path": "{972ce4c6-7e08-4474-a285-3208198ce6fd}",
-            "type": "theme",
-            "version": "55.0a1",
-          }
-        },
-        "checkStartupModifications": true,
-        "path": "c:\\Program Files\\Mozilla Firefox\\extensions",
-      },
       "app-profile": {
         "addons": {
           "xpcshell-something-or-other@mozilla.org": {
             "bootstrapped": true,
             "dependencies": [],
             "enabled": true,
             "hasEmbeddedWebExtension": false,
             "lastModifiedTime": 1,
@@ -30,29 +17,16 @@ add_task(async function test_XPIStates_i
             "version": "0.0.0",
           },
         },
         "checkStartupModifications": true,
         "path": "/home/xpcshell/.mozilla/firefox/default/extensions",
       },
     },
     {
-      "app-global": {
-        "addons": {
-          "{972ce4c6-7e08-4474-a285-3208198ce6fd}": {
-            "enabled": true,
-            "lastModifiedTime": 1,
-            "path": "{972ce4c6-7e08-4474-a285-3208198ce6fd}",
-            "type": "theme",
-            "version": "55.0a1",
-          }
-        },
-        "checkStartupModifications": true,
-        "path": "c:\\Program Files\\Mozilla Firefox\\extensions",
-      },
       "app-profile": {
         "addons": {
           "xpcshell-something-or-other@mozilla.org": {
             "bootstrapped": true,
             "dependencies": [],
             "enabled": true,
             "hasEmbeddedWebExtension": false,
             "lastModifiedTime": 1,
--- a/toolkit/themes/linux/mozapps/jar.mn
+++ b/toolkit/themes/linux/mozapps/jar.mn
@@ -4,14 +4,8 @@
 
 toolkit.jar:
 #include ../../shared/mozapps.inc.mn
 * skin/classic/mozapps/extensions/extensions.css           (extensions/extensions.css)
 * skin/classic/mozapps/extensions/newaddon.css             (extensions/newaddon.css)
   skin/classic/mozapps/extensions/heart.png                (extensions/heart.png)
   skin/classic/mozapps/profile/profileicon.png             (profile/profileicon.png)
   skin/classic/mozapps/update/updates.css                  (update/updates.css)
-
-#if MOZ_BUILD_APP == browser
-[browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#endif
--- a/toolkit/themes/osx/global/jar.mn
+++ b/toolkit/themes/osx/global/jar.mn
@@ -85,14 +85,8 @@ toolkit.jar:
 * skin/classic/global/in-content/info-pages.css                      (in-content/info-pages.css)
   skin/classic/global/splitter/dimple.png                            (splitter/dimple.png)
   skin/classic/global/toolbar/spring.png                             (toolbar/spring.png)
   skin/classic/global/toolbar/toolbar-separator.png                  (toolbar/toolbar-separator.png)
   skin/classic/global/tree/arrow-disclosure.svg                      (tree/arrow-disclosure.svg)
   skin/classic/global/tree/columnpicker.gif                          (tree/columnpicker.gif)
   skin/classic/global/tree/folder.png                                (tree/folder.png)
   skin/classic/global/tree/folder@2x.png                             (tree/folder@2x.png)
-
-#if MOZ_BUILD_APP == browser
-[browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#endif
--- a/toolkit/themes/osx/mozapps/jar.mn
+++ b/toolkit/themes/osx/mozapps/jar.mn
@@ -20,14 +20,8 @@ toolkit.jar:
   skin/classic/mozapps/plugins/pluginHelp-16.png                  (plugins/pluginHelp-16.png)
   skin/classic/mozapps/profile/profileicon.png                    (profile/profileicon.png)
   skin/classic/mozapps/profile/profileSelection.css               (profile/profileSelection.css)
   skin/classic/mozapps/profile/profileicon-selected.png           (profile/profileicon-selected.png)
   skin/classic/mozapps/update/buttons.png                         (update/buttons.png)
 * skin/classic/mozapps/update/updates.css                         (update/updates.css)
   skin/classic/mozapps/xpinstall/xpinstallConfirm.css             (extensions/xpinstallConfirm.css)
   skin/classic/mozapps/handling/handling.css                      (handling/handling.css)
-
-#if MOZ_BUILD_APP == browser
-[browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#endif
\ No newline at end of file
--- a/toolkit/themes/shared/non-mac.jar.inc.mn
+++ b/toolkit/themes/shared/non-mac.jar.inc.mn
@@ -49,14 +49,9 @@
   skin/classic/mozapps/extensions/cancel.png                 (../../windows/mozapps/extensions/cancel.png)
   skin/classic/mozapps/extensions/eula.css                   (../../windows/mozapps/extensions/eula.css)
   skin/classic/mozapps/handling/handling.css                 (../../windows/mozapps/handling/handling.css)
   skin/classic/mozapps/plugins/pluginHelp-16.png             (../../windows/mozapps/plugins/pluginHelp-16.png)
   skin/classic/mozapps/profile/profileSelection.css          (../../windows/mozapps/profile/profileSelection.css)
   skin/classic/mozapps/update/downloadButtons.png            (../../windows/mozapps/update/downloadButtons.png)
 * skin/classic/mozapps/xpinstall/xpinstallConfirm.css        (../../windows/mozapps/extensions/xpinstallConfirm.css)
 
-#if MOZ_BUILD_APP == browser
-[browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#endif
 % override chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png       chrome://mozapps/skin/extensions/extensionGeneric.svg
--- a/toolkit/themes/windows/global/jar.mn
+++ b/toolkit/themes/windows/global/jar.mn
@@ -58,22 +58,16 @@ toolkit.jar:
   skin/classic/global/icons/warning-large.png              (icons/warning-large.png)
   skin/classic/global/icons/windowControls.png             (icons/windowControls.png)
 * skin/classic/global/in-content/common.css                (in-content/common.css)
 * skin/classic/global/in-content/info-pages.css            (in-content/info-pages.css)
   skin/classic/global/toolbar/spring.png                   (toolbar/spring.png)
   skin/classic/global/tree/twisty.svg                      (tree/twisty.svg)
   skin/classic/global/tree/twisty-preWin10.svg             (tree/twisty-preWin10.svg)
 
-#if MOZ_BUILD_APP == browser
-[browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#endif
-
 % override chrome://global/skin/tree/twisty.svg#clsd              chrome://global/skin/tree/twisty-preWin10.svg#clsd           osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#clsd-rtl          chrome://global/skin/tree/twisty-preWin10.svg#clsd-rtl       osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#clsd-hover        chrome://global/skin/tree/twisty-preWin10.svg#clsd-hover     osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#clsd-hover-rtl    chrome://global/skin/tree/twisty-preWin10.svg#clsd-hover-rtl osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#open              chrome://global/skin/tree/twisty-preWin10.svg#open           osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#open-rtl          chrome://global/skin/tree/twisty-preWin10.svg#open-rtl       osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#open-hover        chrome://global/skin/tree/twisty-preWin10.svg#open-hover     osversion<=6.3
 % override chrome://global/skin/tree/twisty.svg#open-hover-rtl    chrome://global/skin/tree/twisty-preWin10.svg#open-hover-rtl osversion<=6.3
--- a/toolkit/themes/windows/mozapps/jar.mn
+++ b/toolkit/themes/windows/mozapps/jar.mn
@@ -4,14 +4,8 @@
 
 toolkit.jar:
 #include ../../shared/mozapps.inc.mn
 * skin/classic/mozapps/extensions/extensions.css             (extensions/extensions.css)
   skin/classic/mozapps/extensions/heart.png                  (extensions/heart.png)
 * skin/classic/mozapps/extensions/newaddon.css               (extensions/newaddon.css)
   skin/classic/mozapps/profile/profileicon.png               (profile/profileicon.png)
   skin/classic/mozapps/update/updates.css                    (update/updates.css)
-
-#if MOZ_BUILD_APP == browser
-[browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#elif MOZ_SEPARATE_MANIFEST_FOR_THEME_OVERRIDES
-[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
-#endif