Backed out changeset 8390be8eb18e (bug 1768695) for causing browser-chrome failures in browser/components/firefoxview/tests/browser/browser_tab_pickup_list.js CLOSED TREE
authorSandor Molnar <smolnar@mozilla.com>
Tue, 02 Aug 2022 18:58:22 +0300
changeset 625768 5cfb0a8308a8add2af14fd7dd3335d6bcaa09b2f
parent 625767 8859d60015d0a334ace4b9739887e92e963e3b77
child 625769 32689459fc627339fe17cbf6228c7309d3ad89c1
push id167186
push usersmolnar@mozilla.com
push dateTue, 02 Aug 2022 15:58:58 +0000
treeherderautoland@5cfb0a8308a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1768695
milestone105.0a1
backs out8390be8eb18ec14eaad664396b7c7f802e5ca03f
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
Backed out changeset 8390be8eb18e (bug 1768695) for causing browser-chrome failures in browser/components/firefoxview/tests/browser/browser_tab_pickup_list.js CLOSED TREE
browser/components/firefoxview/firefox-view-tabs-setup-manager.sys.mjs
browser/components/firefoxview/firefoxView.ftl
browser/components/firefoxview/firefoxview.css
browser/components/firefoxview/firefoxview.html
browser/components/firefoxview/tab-pickup-container.mjs
browser/components/firefoxview/tests/browser/browser_setup_state.js
toolkit/themes/shared/desktop-jar.inc.mn
toolkit/themes/shared/icons/loading-dial.svg
--- a/browser/components/firefoxview/firefox-view-tabs-setup-manager.sys.mjs
+++ b/browser/components/firefoxview/firefox-view-tabs-setup-manager.sys.mjs
@@ -14,119 +14,89 @@ const { XPCOMUtils } = ChromeUtils.impor
 );
 
 const lazy = {};
 XPCOMUtils.defineLazyModuleGetters(lazy, {
   Log: "resource://gre/modules/Log.jsm",
   UIState: "resource://services-sync/UIState.jsm",
   SyncedTabs: "resource://services-sync/SyncedTabs.jsm",
 });
-
 XPCOMUtils.defineLazyGetter(lazy, "fxAccounts", () => {
   return ChromeUtils.import(
     "resource://gre/modules/FxAccounts.jsm"
   ).getFxAccountsSingleton();
 });
 
-XPCOMUtils.defineLazyServiceGetter(
-  lazy,
-  "gNetworkLinkService",
-  "@mozilla.org/network/network-link-service;1",
-  "nsINetworkLinkService"
-);
-
 const SYNC_TABS_PREF = "services.sync.engine.tabs";
 const RECENT_TABS_SYNC = "services.sync.lastTabFetch";
 const MOBILE_PROMO_DISMISSED_PREF =
   "browser.tabs.firefox-view.mobilePromo.dismissed";
 const LOGGING_PREF = "browser.tabs.firefox-view.logLevel";
 const TOPIC_SETUPSTATE_CHANGED = "firefox-view.setupstate.changed";
 const TOPIC_DEVICELIST_UPDATED = "fxaccounts:devicelist_updated";
-const NETWORK_STATUS_CHANGED = "network:offline-status-changed";
-const SYNC_SERVICE_ERROR = "weave:service:sync:error";
-const FXA_ENABLED = "identity.fxaccounts.enabled";
-const SYNC_SERVICE_FINISHED = "weave:service:sync:finished";
 
 function openTabInWindow(window, url) {
   const {
     switchToTabHavingURI,
   } = window.docShell.chromeEventHandler.ownerGlobal;
   switchToTabHavingURI(url, true, {});
 }
 
 export const TabsSetupFlowManager = new (class {
   constructor() {
     this.QueryInterface = ChromeUtils.generateQI(["nsIObserver"]);
 
     this.setupState = new Map();
     this.resetInternalState();
-    this._currentSetupStateName = "";
-    this.networkIsOnline =
-      lazy.gNetworkLinkService.linkStatusKnown &&
-      lazy.gNetworkLinkService.isLinkUp;
-    this.syncIsWorking = true;
 
     this.registerSetupState({
       uiStateIndex: 0,
-      name: "error-state",
-      exitConditions: () => {
-        return (
-          this.networkIsOnline &&
-          this.syncIsWorking &&
-          !Services.prefs.prefIsLocked(FXA_ENABLED)
-        );
-      },
-    });
-    this.registerSetupState({
-      uiStateIndex: 1,
       name: "not-signed-in",
       exitConditions: () => {
         return this.fxaSignedIn;
       },
     });
+    // TODO: handle offline, sync service not ready or available
     this.registerSetupState({
-      uiStateIndex: 2,
+      uiStateIndex: 1,
       name: "connect-secondary-device",
       exitConditions: () => {
         return this.secondaryDeviceConnected;
       },
     });
     this.registerSetupState({
-      uiStateIndex: 3,
+      uiStateIndex: 2,
       name: "disabled-tab-sync",
       exitConditions: () => {
         return this.syncTabsPrefEnabled;
       },
     });
     this.registerSetupState({
-      uiStateIndex: 4,
+      uiStateIndex: 3,
       name: "synced-tabs-not-ready",
       enter: () => {
         if (!this.didRecentTabSync) {
           lazy.SyncedTabs.syncTabs();
         }
       },
       exitConditions: () => {
         return this.didRecentTabSync;
       },
     });
     this.registerSetupState({
-      uiStateIndex: 5,
+      uiStateIndex: 4,
       name: "synced-tabs-loaded",
       exitConditions: () => {
         // This is the end state
         return false;
       },
     });
 
     Services.obs.addObserver(this, lazy.UIState.ON_UPDATE);
     Services.obs.addObserver(this, TOPIC_DEVICELIST_UPDATED);
-    Services.obs.addObserver(this, NETWORK_STATUS_CHANGED);
-    Services.obs.addObserver(this, SYNC_SERVICE_ERROR);
-    Services.obs.addObserver(this, SYNC_SERVICE_FINISHED);
 
     // this.syncTabsPrefEnabled will track the value of the tabs pref
     XPCOMUtils.defineLazyPreferenceGetter(
       this,
       "syncTabsPrefEnabled",
       SYNC_TABS_PREF,
       false,
       () => {
@@ -170,39 +140,19 @@ export const TabsSetupFlowManager = new 
     this._uiUpdateNeeded = true;
 
     // keep track of what is connected so we can respond to changes
     this._deviceStateSnapshot = {
       mobileDeviceConnected: this.mobileDeviceConnected,
       secondaryDeviceConnected: this.secondaryDeviceConnected,
     };
   }
-
-  getErrorType() {
-    // this ordering is important for dealing with multiple errors at once
-    const errorStates = {
-      "network-offline": !this.networkIsOnline,
-      "sync-error": !this.syncIsWorking,
-      "fxa-admin-disabled": Services.prefs.prefIsLocked(FXA_ENABLED),
-    };
-
-    for (let [type, value] of Object.entries(errorStates)) {
-      if (value) {
-        return type;
-      }
-    }
-    return null;
-  }
-
   uninit() {
     Services.obs.removeObserver(this, lazy.UIState.ON_UPDATE);
     Services.obs.removeObserver(this, TOPIC_DEVICELIST_UPDATED);
-    Services.obs.removeObserver(this, NETWORK_STATUS_CHANGED);
-    Services.obs.removeObserver(this, SYNC_SERVICE_ERROR);
-    Services.obs.removeObserver(this, SYNC_SERVICE_FINISHED);
   }
   get currentSetupState() {
     return this.setupState.get(this._currentSetupStateName);
   }
   get uiStateIndex() {
     return this.currentSetupState.uiStateIndex;
   }
   get fxaSignedIn() {
@@ -270,34 +220,16 @@ export const TabsSetupFlowManager = new 
         this.logger.debug("Handling UIState update");
         this.maybeUpdateUI();
         break;
       case TOPIC_DEVICELIST_UPDATED:
         this.logger.debug("Handling observer notification:", topic, data);
         this.refreshDevices();
         this.maybeUpdateUI();
         break;
-      case "fxaccounts:device_connected":
-      case "fxaccounts:device_disconnected":
-        await lazy.fxAccounts.device.refreshDeviceList();
-        this.maybeUpdateUI();
-        break;
-      case SYNC_SERVICE_ERROR:
-        this.syncIsWorking = false;
-        this.maybeUpdateUI();
-        break;
-      case NETWORK_STATUS_CHANGED:
-        this.networkIsOnline = data == "online";
-        this.maybeUpdateUI();
-        break;
-      case SYNC_SERVICE_FINISHED:
-        if (!this.syncIsWorking) {
-          this.syncIsWorking = true;
-          this.maybeUpdateUI();
-        }
     }
   }
 
   refreshDevices() {
     // compare new values to the previous values
     const mobileDeviceConnected = this.mobileDeviceConnected;
     const secondaryDeviceConnected = this.secondaryDeviceConnected;
 
@@ -336,48 +268,38 @@ export const TabsSetupFlowManager = new 
       this._uiUpdateNeeded = true;
     } else {
       this.logger.debug("refreshDevices: no device state change");
     }
   }
 
   maybeUpdateUI() {
     let nextSetupStateName = this._currentSetupStateName;
-    let errorState = null;
 
     // state transition conditions
     for (let state of this.setupState.values()) {
       nextSetupStateName = state.name;
       if (!state.exitConditions()) {
         break;
       }
     }
 
     let setupState = this.currentSetupState;
-    const state = this.setupState.get(nextSetupStateName);
-    const uiStateIndex = state.uiStateIndex;
-
-    if (
-      uiStateIndex == 0 ||
-      nextSetupStateName != this._currentSetupStateName
-    ) {
-      setupState = state;
+    if (nextSetupStateName != this._currentSetupStateName) {
+      setupState = this.setupState.get(nextSetupStateName);
       this._currentSetupStateName = nextSetupStateName;
       this._uiUpdateNeeded = true;
     }
     this.logger.debug("maybeUpdateUI, _uiUpdateNeeded:", this._uiUpdateNeeded);
     if (this._uiUpdateNeeded) {
       this._uiUpdateNeeded = false;
       if (this.shouldShowMobilePromo) {
         this._didShowMobilePromo = true;
       }
-      if (uiStateIndex == 0) {
-        errorState = this.getErrorType();
-      }
-      Services.obs.notifyObservers(null, TOPIC_SETUPSTATE_CHANGED, errorState);
+      Services.obs.notifyObservers(null, TOPIC_SETUPSTATE_CHANGED);
     }
     if ("function" == typeof setupState.enter) {
       setupState.enter();
     }
   }
 
   dismissMobilePromo() {
     Services.prefs.setBoolPref(MOBILE_PROMO_DISMISSED_PREF, true);
--- a/browser/components/firefoxview/firefoxView.ftl
+++ b/browser/components/firefoxview/firefoxView.ftl
@@ -40,27 +40,16 @@ firefoxview-tabpickup-adddevice-descript
 firefoxview-tabpickup-adddevice-learn-how = Learn how
 firefoxview-tabpickup-adddevice-primarybutton = Get { -brand-product-name } for mobile
 
 firefoxview-tabpickup-synctabs-header = Turn on tab syncing
 firefoxview-tabpickup-synctabs-description = Allow { -brand-short-name } to share tabs between devices.
 firefoxview-tabpickup-synctabs-learn-how = Learn how
 firefoxview-tabpickup-synctabs-primarybutton = Sync open tabs
 
-firefoxview-tabpickup-fxa-admin-disabled-header = Your organization has disabled sync
-firefoxview-tabpickup-fxa-admin-disabled-description = { -brand-short-name } is not able to sync tabs between devices because your administrator has disabled syncing.
-
-firefoxview-tabpickup-network-offline-header = Check your internet connection
-firefoxview-tabpickup-network-offline-description = If you’re using a firewall or proxy, check that { -brand-short-name } has permission to access the web.
-firefoxview-tabpickup-network-offline-primarybutton = Try again
-
-firefoxview-tabpickup-sync-error-header = We’re having trouble syncing
-firefoxview-tabpickup-sync-error-description = { -brand-short-name } can’t reach the service right now. Try again in a few moments.
-firefoxview-tabpickup-sync-error-primarybutton = Try again
-
 firefoxview-tabpickup-syncing = Sit tight while your tabs sync. It’ll be just a moment.
 
 firefoxview-mobile-promo-header = Grab tabs from your phone or tablet
 firefoxview-mobile-promo-description = To view your latest mobile tabs, sign in to { -brand-product-name } on iOS or Android.
 firefoxview-mobile-promo-primarybutton = Get { -brand-product-name } for mobile
 
 firefoxview-mobile-confirmation-header = 🎉 Good to go!
 firefoxview-mobile-confirmation-description = Now you can grab your { -brand-product-name } tabs from your tablet or phone.
--- a/browser/components/firefoxview/firefoxview.css
+++ b/browser/components/firefoxview/firefoxview.css
@@ -19,17 +19,17 @@
     "colorways-figure"
     "colorways-header"
     "colorways-description"
     "colorways-button";
   --colorways-grid-template-columns: auto auto;
   --colorways-grid-template-rows: auto auto auto;
   --colorways-figure-display: flex;
   --colorways-header-flex-direction: column;
-  --info-icon-background-color: #0090ED;
+
   --card-border-zap-gradient: linear-gradient(90deg, #9059FF 0%, #FF4AA2 52.08%, #FFBD4F 100%);
 }
 
 :root {
   /* align the base font-size on root element with that of <body>
      so rem-based layout widths and break-points behave predictably */
   font-size: 15px;
   /* override --in-content-page-background from common-shared.css */
@@ -277,29 +277,16 @@ button.close {
   background-color: var(--newtab-background-color-secondary);
   border: 1px solid var(--fxview-contrast-border);
 }
 
 .empty-container {
   border-radius: 4px;
 }
 
-.error-state {
-  text-align: center;
-  padding: 0 0 20px;
-  border: 1px solid var(--fxview-contrast-border);
-  border-radius: 4px;
-}
-
-.error-state > h3 {
-  font-weight: 600;
-  display: inline-block;
-  margin-bottom: 0;
-}
-
 .placeholder-content {
   text-align: center;
   padding: 24px 16px;
 }
 
 .page-section-header {
   display: grid;
   grid-template-columns: repeat(8, 1fr);
@@ -431,19 +418,22 @@ button.close {
 .synced-tabs-container.loading > tab-pickup-list,
 .synced-tabs-container.loading > .placeholder-content,
 .synced-tabs-container:not(.loading) > .loading-content {
   display: none;
 }
 
 .synced-tabs-container > .loading-content {
   text-align: center;
-  color: var(--fxview-text-secondary-color);
-  margin-top: 40px;
-  padding: 20px 16px 16px;
+  -moz-context-properties: fill;
+  fill: currentColor;
+  background: url(chrome://global/skin/icons/loading-dial.svg) no-repeat center top;
+  background-size: 32px;
+  margin-top: 32px;
+  padding: 48px 16px 16px;
 }
 
 .closed-tabs-list {
   padding-inline-start: 0;
 }
 
 .closed-tab-li {
   display: grid;
@@ -699,57 +689,27 @@ button.close {
 .tablet {
   background-image: url('chrome://browser/skin/device-tablet.svg');
 }
 
 .synced-tabs {
   background-image: url('chrome://browser/skin/synced-tabs.svg');
 }
 
-.info {
-  background-image: url('chrome://global/skin/icons/info-filled.svg');
-}
-
-.error-state > .info {
-  vertical-align: text-top;
-  margin-inline-end: 7px;
-  margin-top: 1px;
-  color: var(--info-icon-background-color);
-}
-
 .favicon {
   background-size: cover;
   -moz-context-properties: fill;
   fill: currentColor;
 }
 
 .favicon, .icon, .synced-tab-li-favicon {
   width: 16px;
   height: 16px;
 }
 
-.sync {
-  background-image: url(chrome://browser/skin/sync.svg);
-  background-size: cover;
-  height: 19px;
-  width: 19px;
-  color: var(--fxview-text-secondary-color);
-}
-
-@keyframes syncRotate {
-  from { transform: rotate(0); }
-  to { transform: rotate(360deg); }
-}
-
-@media (prefers-reduced-motion: no-preference) {
-  .sync {
-    animation: syncRotate 0.8s linear infinite;
-  }
-}
-
 .last-active-badge {
   height: 1.25em;
   width: 6em;
   background-color: #E3FFF3;
   grid-area: badge;
   border-radius: 2em;
   justify-self: end;
   text-align: center;
--- a/browser/components/firefoxview/firefoxview.html
+++ b/browser/components/firefoxview/firefoxview.html
@@ -28,90 +28,78 @@
       <div class="brand-logo">
         <span class="brand-icon"></span>
         <span class="brand-feature-name" data-l10n-id="firefoxview-page-title"></span>
       </div>
     </nav>
     <main>
       <template id="sync-setup-template">
         <named-deck class="sync-setup-container" data-prefix="id:">
-          <div name="sync-setup-view0" data-prefix="id:-view0" class="card error-state" data-prefix="aria-labelledby:-view0-header">
-            <icon class="icon info primary"></icon><h3 data-prefix="id:-view0-header" class="card-header"></h3>
-            <section>
-              <p>
-                <span id="error-state-description"></span>
-              </p>
-              <button id="error-state-button" class="primary"></button>
-            </section>
-          </div>
-          <div name="sync-setup-view1" data-prefix="id:-view1" class="card zap-card setup-step" data-prefix="aria-labelledby:-view1-header">
-            <h2 data-prefix="id:-view1-header" data-l10n-id="firefoxview-tabpickup-step-signin-header" class="card-header"></h2>
+          <div name="sync-setup-view0" data-prefix="id:-view0" class="card zap-card setup-step" data-prefix="aria-labelledby:-view0-header">
+            <h2 data-prefix="id:-view0-header" data-l10n-id="firefoxview-tabpickup-step-signin-header" class="card-header"></h2>
             <section class="step-body">
               <p class="step-content" data-l10n-id="firefoxview-tabpickup-step-signin-description"></p>
-              <button class="primary" data-action="view1-primary-action" data-l10n-id="firefoxview-tabpickup-step-signin-primarybutton"></button>
+              <button class="primary" data-action="view0-primary-action" data-l10n-id="firefoxview-tabpickup-step-signin-primarybutton"></button>
             </section>
             <footer>
-              <progress data-prefix="id:-view1-progress" class="step-progress" max="100" value="11"></progress>
+              <progress data-prefix="id:-view0-progress" class="step-progress" max="100" value="11"></progress>
               <label
-                data-prefix="for:-view1-progress"
+                data-prefix="for:-view0-progress"
                 data-l10n-id="firefoxview-tabpickup-progress-label"
                 data-l10n-args='{"percentValue":"11"}'></label>
             </footer>
           </div>
-          <div name="sync-setup-view2" data-prefix="id:-view2" class="card zap-card setup-step" data-prefix="aria-labelledby:-view2-header">
-            <h2 data-prefix="id:-view2-header" data-l10n-id="firefoxview-tabpickup-adddevice-header" class="card-header"></h2>
+          <div name="sync-setup-view1" data-prefix="id:-view1" class="card zap-card setup-step" data-prefix="aria-labelledby:-view1-header">
+            <h2 data-prefix="id:-view1-header" data-l10n-id="firefoxview-tabpickup-adddevice-header" class="card-header"></h2>
             <section class="step-body">
               <p class="step-content">
                 <span data-l10n-id="firefoxview-tabpickup-adddevice-description"></span>
                 <br/>
                 <a target="_blank" data-support-url="tab-pickup-firefox-view" data-l10n-id="firefoxview-tabpickup-adddevice-learn-how"></a>
               </p>
-              <button class="primary" data-action="view2-primary-action" data-l10n-id="firefoxview-tabpickup-adddevice-primarybutton"></button>
+              <button class="primary" data-action="view1-primary-action" data-l10n-id="firefoxview-tabpickup-adddevice-primarybutton"></button>
             </section>
             <footer>
-              <progress data-prefix="id:-view2-progress" class="step-progress" max="100" value="33"></progress>
+              <progress data-prefix="id:-view1-progress" class="step-progress" max="100" value="33"></progress>
               <label
-                data-prefix="for:-view2-progress"
+                data-prefix="for:-view1-progress"
                 data-l10n-id="firefoxview-tabpickup-progress-label"
                 data-l10n-args='{"percentValue":"33"}'></label>
             </footer>
           </div>
-          <div name="sync-setup-view3" data-prefix="id:-view3" class="card zap-card setup-step" data-prefix="aria-labelledby:-view3-header">
-            <h2 data-prefix="id:-view3-header" data-l10n-id="firefoxview-tabpickup-synctabs-header" class="card-header"></h2>
+          <div name="sync-setup-view2" data-prefix="id:-view2" class="card zap-card setup-step" data-prefix="aria-labelledby:-view2-header">
+            <h2 data-prefix="id:-view2-header" data-l10n-id="firefoxview-tabpickup-synctabs-header" class="card-header"></h2>
             <section class="step-body">
               <p class="step-content">
                 <span  data-l10n-id="firefoxview-tabpickup-synctabs-description"></span>
                 <br/>
                 <a target="_blank" data-support-url="tab-pickup-firefox-view" data-l10n-id="firefoxview-tabpickup-synctabs-learn-how"></a>
               </p>
-              <button class="primary" data-action="view3-primary-action" data-l10n-id="firefoxview-tabpickup-synctabs-primarybutton"></button>
+              <button class="primary" data-action="view2-primary-action" data-l10n-id="firefoxview-tabpickup-synctabs-primarybutton"></button>
             </section>
             <footer>
-              <progress data-prefix="id:-view3-progress" class="step-progress" max="100" value="66"></progress>
+              <progress data-prefix="id:-view2-progress" class="step-progress" max="100" value="66"></progress>
               <label
-                data-prefix="for:-view3-progress"
+                data-prefix="for:-view2-progress"
                 data-l10n-id="firefoxview-tabpickup-progress-label"
                 data-l10n-args='{"percentValue":"66"}'></label>
             </footer>
           </div>
         </named-deck>
       </template>
       <template id="synced-tabs-template">
         <div class="synced-tabs-container" data-prefix="id:" hidden>
           <tab-pickup-list>
             <ol hidden="true" class="synced-tabs-list"></ol>
           </tab-pickup-list>
           <div hidden id="synced-tabs-placeholder" class="placeholder-content">
             <icon class="icon synced-tabs"></icon>
             <p data-l10n-id="firefoxview-synced-tabs-placeholder" class="placeholder-text"></p>
           </div>
-          <div class="loading-content">
-            <icon class="icon sync"></icon>
-            <p data-l10n-id="firefoxview-tabpickup-syncing"></p>
-          </div>
+          <p class="loading-content" data-l10n-id="firefoxview-tabpickup-syncing"></p>
         </div>
       </template>
 
       <section class="content-container" is="tab-pickup-container" id="tab-pickup-container">
         <header class="page-section-header">
           <h1 data-l10n-id="firefoxview-tabpickup-header"></h1>
           <button id="collapsible-synced-tabs-button" class="ghost-button twisty icon arrow-up" hidden></button>
           <p class="section-description" data-l10n-id="firefoxview-tabpickup-description"></p>
--- a/browser/components/firefoxview/tab-pickup-container.mjs
+++ b/browser/components/firefoxview/tab-pickup-container.mjs
@@ -11,35 +11,29 @@ const { TabsSetupFlowManager } = ChromeU
 );
 const TOPIC_SETUPSTATE_CHANGED = "firefox-view.setupstate.changed";
 
 class TabPickupContainer extends HTMLElement {
   constructor() {
     super();
     this.boundObserve = (...args) => this.observe(...args);
     this._currentSetupStateIndex = -1;
-    this.errorState = null;
   }
   get setupContainerElem() {
     return this.querySelector(".sync-setup-container");
   }
 
   get tabsContainerElem() {
     return this.querySelector(".synced-tabs-container");
   }
 
   get collapsibleButton() {
     return this.querySelector("#collapsible-synced-tabs-button");
   }
 
-  getWindow() {
-    return this.ownerGlobal.browsingContext.embedderWindowGlobal.browsingContext
-      .window;
-  }
-
   connectedCallback() {
     this.addEventListener("click", this);
     this.addEventListener("visibilitychange", this);
     Services.obs.addObserver(this.boundObserve, TOPIC_SETUPSTATE_CHANGED);
     this.update();
   }
 
   cleanup() {
@@ -52,30 +46,25 @@ class TabPickupContainer extends HTMLEle
 
   handleEvent(event) {
     if (event.type == "click" && event.target == this.collapsibleButton) {
       toggleContainer(this.collapsibleButton, this.tabsContainerElem);
       return;
     }
     if (event.type == "click" && event.target.dataset.action) {
       switch (event.target.dataset.action) {
-        case "view0-sync-error-action":
-        case "view0-network-offline-action": {
-          this.getWindow().gBrowser.reload();
+        case "view0-primary-action": {
+          TabsSetupFlowManager.openFxASignup(event.target.ownerGlobal);
           break;
         }
         case "view1-primary-action": {
-          TabsSetupFlowManager.openFxASignup(event.target.ownerGlobal);
+          TabsSetupFlowManager.openSyncPreferences(event.target.ownerGlobal);
           break;
         }
         case "view2-primary-action": {
-          TabsSetupFlowManager.openSyncPreferences(event.target.ownerGlobal);
-          break;
-        }
-        case "view3-primary-action": {
           TabsSetupFlowManager.syncOpenTabs(event.target);
           break;
         }
         case "mobile-promo-dismiss": {
           TabsSetupFlowManager.dismissMobilePromo(event.target);
           break;
         }
         case "mobile-promo-primary-action": {
@@ -92,19 +81,19 @@ class TabPickupContainer extends HTMLEle
     if (
       event.type == "visibilitychange" &&
       document.visibilityState === "visible"
     ) {
       this.update();
     }
   }
 
-  async observe(subject, topic, errorState) {
+  async observe(subject, topic, data) {
     if (topic == TOPIC_SETUPSTATE_CHANGED) {
-      this.update({ errorState });
+      this.update();
     }
   }
 
   get mobilePromoElem() {
     return this.querySelector(".promo-box");
   }
   get mobileSuccessElem() {
     return this.querySelector(".confirmation-message-box");
@@ -138,99 +127,60 @@ class TabPickupContainer extends HTMLEle
       this.appendChild(cloned);
     }
   }
 
   update({
     stateIndex = TabsSetupFlowManager.uiStateIndex,
     showMobilePromo = TabsSetupFlowManager.shouldShowMobilePromo,
     showMobilePairSuccess = TabsSetupFlowManager.shouldShowMobileConnectedSuccess,
-    errorState = TabsSetupFlowManager.getErrorType(),
   } = {}) {
     let needsRender = false;
     if (showMobilePromo !== this._showMobilePromo) {
       this._showMobilePromo = showMobilePromo;
       needsRender = true;
     }
     if (showMobilePairSuccess !== this._showMobilePairSuccess) {
       this._showMobilePairSuccess = showMobilePairSuccess;
       needsRender = true;
     }
-    if (stateIndex !== this._currentSetupStateIndex || stateIndex == 0) {
+    if (stateIndex !== this._currentSetupStateIndex) {
       this._currentSetupStateIndex = stateIndex;
       needsRender = true;
-      this.errorState = errorState;
     }
     needsRender && this.render();
   }
-
-  generateErrorMessage() {
-    const errorStateHeader = this.querySelector(
-      "#tabpickup-steps-view0-header"
-    );
-    const errorStateDescription = this.querySelector(
-      "#error-state-description"
-    );
-    const errorStateButton = this.querySelector("#error-state-button");
-
-    document.l10n.setAttributes(
-      errorStateHeader,
-      `firefoxview-tabpickup-${this.errorState}-header`
-    );
-    document.l10n.setAttributes(
-      errorStateDescription,
-      `firefoxview-tabpickup-${this.errorState}-description`
-    );
-
-    errorStateButton.hidden = this.errorState == "fxa-admin-disabled";
-
-    if (this.errorState != "fxa-admin-disabled") {
-      document.l10n.setAttributes(
-        errorStateButton,
-        `firefoxview-tabpickup-${this.errorState}-primarybutton`
-      );
-      errorStateButton.setAttribute(
-        "data-action",
-        `view0-${this.errorState}-action`
-      );
-    }
-  }
-
   render() {
     if (!this.isConnected) {
       return;
     }
 
     let setupElem = this.setupContainerElem;
     let tabsElem = this.tabsContainerElem;
     let mobilePromoElem = this.mobilePromoElem;
     let mobileSuccessElem = this.mobileSuccessElem;
 
     const stateIndex = this._currentSetupStateIndex;
-    const isLoading = stateIndex == 4;
+    const isLoading = stateIndex == 3;
 
     // show/hide either the setup or tab list containers, creating each as necessary
-    if (stateIndex < 4) {
+    if (stateIndex < 3) {
       if (!setupElem) {
         this.insertTemplatedElement(
           "sync-setup-template",
           "tabpickup-steps",
           "sync-setup-placeholder"
         );
         setupElem = this.setupContainerElem;
       }
       if (tabsElem) {
         tabsElem.hidden = true;
       }
       setupElem.hidden = false;
       setupElem.selectedViewName = `sync-setup-view${stateIndex}`;
-
-      if (stateIndex == 0 && this.errorState) {
-        this.generateErrorMessage();
-      }
       return;
     }
 
     if (!tabsElem) {
       this.insertTemplatedElement(
         "synced-tabs-template",
         "tabpickup-tabs-container",
         "synced-tabs-placeholder"
@@ -238,17 +188,17 @@ class TabPickupContainer extends HTMLEle
       tabsElem = this.tabsContainerElem;
     }
     if (setupElem) {
       setupElem.hidden = true;
     }
     tabsElem.hidden = false;
     tabsElem.classList.toggle("loading", isLoading);
 
-    if (stateIndex == 5) {
+    if (stateIndex == 4) {
       this.collapsibleButton.hidden = false;
     }
     mobilePromoElem.hidden = !this._showMobilePromo;
     mobileSuccessElem.hidden = !this._showMobilePairSuccess;
   }
 }
 customElements.define("tab-pickup-container", TabPickupContainer);
 
--- a/browser/components/firefoxview/tests/browser/browser_setup_state.js
+++ b/browser/components/firefoxview/tests/browser/browser_setup_state.js
@@ -57,17 +57,17 @@ async function setupWithDesktopDevices()
       },
       {
         id: 2,
         name: "Other Device",
         type: "desktop",
       },
     ],
   });
-
+  // ensure tab sync is false so we don't skip onto next step
   await SpecialPowers.pushPrefEnv({
     set: [["services.sync.engine.tabs", true]],
   });
   return sandbox;
 }
 
 async function waitForVisibleStep(browser, expected) {
   const { document } = browser.contentWindow;
@@ -134,19 +134,16 @@ function checkMobilePromo(browser, expec
 
 async function tearDown(sandbox) {
   sandbox?.restore();
   Services.prefs.clearUserPref("services.sync.lastTabFetch");
   Services.prefs.clearUserPref(MOBILE_PROMO_DISMISSED_PREF);
 }
 
 add_setup(async function() {
-  // we only use this for the first test, then we reset it
-  Services.prefs.lockPref("identity.fxaccounts.enabled");
-
   if (!Services.prefs.getBoolPref("browser.tabs.firefox-view")) {
     info(
       "firefox-view pref was off, toggling it on and adding the tabstrip widget"
     );
     await SpecialPowers.pushPrefEnv({
       set: [["browser.tabs.firefox-view", true]],
     });
     CustomizableUI.addWidgetToArea(
@@ -168,65 +165,22 @@ add_setup(async function() {
     await tearDown();
   });
   // set tab sync false so we don't skip setup states
   await SpecialPowers.pushPrefEnv({
     set: [["services.sync.engine.tabs", false]],
   });
 });
 
-add_task(async function test_sync_admin_disabled() {
-  const sandbox = setupMocks({ state: UIState.STATUS_NOT_CONFIGURED });
-  await withFirefoxView({}, async browser => {
-    const { document } = browser.contentWindow;
-
-    Services.obs.notifyObservers(null, UIState.ON_UPDATE);
-    is(
-      Services.prefs.getBoolPref("identity.fxaccounts.enabled"),
-      true,
-      "Expected identity.fxaccounts.enabled pref to be false"
-    );
-
-    is(
-      Services.prefs.prefIsLocked("identity.fxaccounts.enabled"),
-      true,
-      "Expected identity.fxaccounts.enabled pref to be locked"
-    );
-
-    await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view0",
-    });
-
-    const errorStateHeader = document.querySelector(
-      "#tabpickup-steps-view0-header"
-    );
-
-    await BrowserTestUtils.waitForMutationCondition(
-      errorStateHeader,
-      { childList: true },
-      () => errorStateHeader.textContent.includes("disabled")
-    );
-
-    ok(
-      errorStateHeader
-        .getAttribute("data-l10n-id")
-        .includes("fxa-admin-disabled"),
-      "Correct message should show when fxa is disabled by an admin"
-    );
-  });
-  Services.prefs.unlockPref("identity.fxaccounts.enabled");
-  await tearDown(sandbox);
-});
-
 add_task(async function test_unconfigured_initial_state() {
   const sandbox = setupMocks({ state: UIState.STATUS_NOT_CONFIGURED });
   await withFirefoxView({}, async browser => {
     Services.obs.notifyObservers(null, UIState.ON_UPDATE);
     await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view1",
+      expectedVisible: "#tabpickup-steps-view0",
     });
     checkMobilePromo(browser, {
       mobilePromo: false,
       mobileConfirmation: false,
     });
   });
   await tearDown(sandbox);
 });
@@ -238,21 +192,20 @@ add_task(async function test_signed_in()
       {
         id: 1,
         name: "This Device",
         isCurrentDevice: true,
         type: "desktop",
       },
     ],
   });
-
   await withFirefoxView({}, async browser => {
     Services.obs.notifyObservers(null, UIState.ON_UPDATE);
     await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view2",
+      expectedVisible: "#tabpickup-steps-view1",
     });
 
     is(
       fxAccounts.device.recentDeviceList?.length,
       1,
       "Just 1 device connected"
     );
     checkMobilePromo(browser, {
@@ -284,17 +237,17 @@ add_task(async function test_2nd_desktop
     // ensure tab sync is false so we don't skip onto next step
     ok(
       !Services.prefs.getBoolPref("services.sync.engine.tabs", false),
       "services.sync.engine.tabs is initially false"
     );
 
     Services.obs.notifyObservers(null, UIState.ON_UPDATE);
     await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view3",
+      expectedVisible: "#tabpickup-steps-view2",
     });
 
     is(fxAccounts.device.recentDeviceList?.length, 2, "2 devices connected");
     ok(
       fxAccounts.device.recentDeviceList?.every(
         device => device.type !== "mobile"
       ),
       "No connected device is type:mobile"
@@ -328,17 +281,17 @@ add_task(async function test_mobile_conn
     // ensure tab sync is false so we don't skip onto next step
     ok(
       !Services.prefs.getBoolPref("services.sync.engine.tabs", false),
       "services.sync.engine.tabs is initially false"
     );
 
     Services.obs.notifyObservers(null, UIState.ON_UPDATE);
     await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view3",
+      expectedVisible: "#tabpickup-steps-view2",
     });
 
     is(fxAccounts.device.recentDeviceList?.length, 2, "2 devices connected");
     ok(
       fxAccounts.device.recentDeviceList?.some(
         device => device.type !== "mobile"
       ),
       "A connected device is type:mobile"
@@ -368,17 +321,17 @@ add_task(async function test_tab_sync_en
       },
     ],
   });
   await withFirefoxView({}, async browser => {
     Services.obs.notifyObservers(null, UIState.ON_UPDATE);
 
     // test initial state, with the pref not enabled
     await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view3",
+      expectedVisible: "#tabpickup-steps-view2",
     });
     checkMobilePromo(browser, {
       mobilePromo: false,
       mobileConfirmation: false,
     });
 
     // test with the pref toggled on
     await SpecialPowers.pushPrefEnv({
@@ -388,25 +341,25 @@ add_task(async function test_tab_sync_en
     checkMobilePromo(browser, {
       mobilePromo: false,
       mobileConfirmation: false,
     });
 
     // reset and test clicking the action button
     await SpecialPowers.popPrefEnv();
     await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view3",
+      expectedVisible: "#tabpickup-steps-view2",
     });
     checkMobilePromo(browser, {
       mobilePromo: false,
       mobileConfirmation: false,
     });
 
     const actionButton = browser.contentWindow.document.querySelector(
-      "#tabpickup-steps-view3 button.primary"
+      "#tabpickup-steps-view2 button.primary"
     );
     actionButton.click();
 
     await waitForElementVisible(browser, "#tabpickup-steps", false);
     checkMobilePromo(browser, {
       mobilePromo: false,
       mobileConfirmation: false,
     });
@@ -715,81 +668,8 @@ add_task(async function test_mobile_prom
           });
         }
       }
     );
     await BrowserTestUtils.closeWindow(win2);
   });
   await tearDown(sandbox);
 });
-
-add_task(async function test_network_offline() {
-  const sandbox = await setupWithDesktopDevices();
-  await withFirefoxView({}, async browser => {
-    const { document } = browser.contentWindow;
-
-    Services.obs.notifyObservers(
-      null,
-      "network:offline-status-changed",
-      "offline"
-    );
-    await waitForElementVisible(browser, "#tabpickup-steps", true);
-    await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view0",
-    });
-
-    const errorStateHeader = document.querySelector(
-      "#tabpickup-steps-view0-header"
-    );
-
-    await BrowserTestUtils.waitForMutationCondition(
-      errorStateHeader,
-      { childList: true },
-      () => errorStateHeader.textContent.includes("connection")
-    );
-
-    ok(
-      errorStateHeader.getAttribute("data-l10n-id").includes("network-offline"),
-      "Correct message should show when network connection is lost"
-    );
-
-    Services.obs.notifyObservers(
-      null,
-      "network:offline-status-changed",
-      "online"
-    );
-
-    await waitForElementVisible(browser, "#tabpickup-tabs-container", true);
-  });
-  await tearDown(sandbox);
-});
-
-add_task(async function test_sync_error() {
-  const sandbox = await setupWithDesktopDevices();
-  await withFirefoxView({}, async browser => {
-    const { document } = browser.contentWindow;
-
-    Services.obs.notifyObservers(null, "weave:service:sync:error");
-
-    await waitForElementVisible(browser, "#tabpickup-steps", true);
-    await waitForVisibleStep(browser, {
-      expectedVisible: "#tabpickup-steps-view0",
-    });
-
-    const errorStateHeader = document.querySelector(
-      "#tabpickup-steps-view0-header"
-    );
-
-    await BrowserTestUtils.waitForMutationCondition(
-      errorStateHeader,
-      { childList: true },
-      () => errorStateHeader.textContent.includes("trouble syncing")
-    );
-
-    ok(
-      errorStateHeader.getAttribute("data-l10n-id").includes("sync-error"),
-      "Correct message should show when there's a sync service error"
-    );
-
-    Services.obs.notifyObservers(null, "weave:service:sync:finished");
-  });
-  await tearDown(sandbox);
-});
--- a/toolkit/themes/shared/desktop-jar.inc.mn
+++ b/toolkit/themes/shared/desktop-jar.inc.mn
@@ -72,16 +72,19 @@
   skin/classic/global/icons/highlights.svg                 (../../shared/icons/highlights.svg)
   skin/classic/global/icons/indicator-private-browsing.svg (../../shared/icons/indicator-private-browsing.svg)
   skin/classic/global/icons/info.svg                       (../../shared/icons/info.svg)
   skin/classic/global/icons/info-filled.svg                (../../shared/icons/info-filled.svg)
   skin/classic/global/icons/lightbulb.svg                  (../../shared/icons/lightbulb.svg)
   skin/classic/global/icons/link.svg                       (../../shared/icons/link.svg)
   skin/classic/global/icons/loading.png                    (../../shared/icons/loading.png)
   skin/classic/global/icons/loading@2x.png                 (../../shared/icons/loading@2x.png)
+#ifdef NIGHTLY_BUILD
+  skin/classic/global/icons/loading-dial.svg               (../../shared/icons/loading-dial.svg)
+#endif
   skin/classic/global/icons/more.svg                       (../../shared/icons/more.svg)
   skin/classic/global/icons/open-in-new.svg                (../../shared/icons/open-in-new.svg)
   skin/classic/global/icons/page-portrait.svg              (../../shared/icons/page-portrait.svg)
   skin/classic/global/icons/page-landscape.svg             (../../shared/icons/page-landscape.svg)
   skin/classic/global/icons/performance.svg                (../../shared/icons/performance.svg)
   skin/classic/global/icons/plugin.svg                     (../../shared/icons/plugin.svg)
   skin/classic/global/icons/plugin-blocked.svg             (../../shared/icons/plugin-blocked.svg)
   skin/classic/global/icons/plus.svg                       (../../shared/icons/plus.svg)
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/shared/icons/loading-dial.svg
@@ -0,0 +1,18 @@
+<!-- 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/.-->
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity" style="animation:spinIcon 1.2s steps(12,end) infinite">
+  <style>@keyframes spinIcon{to{transform:rotate(360deg)}}</style>
+  <path d="m7 3 0-2s0-1 1-1 1 1 1 1l0 2s0 1-1 1-1-1-1-1z"/>
+  <path d="m4.634 4.17-1-1.732s-.5-.866.366-1.366 1.366.366 1.366.366l1 1.732s.5.866-.366 1.366-1.366-.366-1.366-.366z" opacity=".93"/>
+  <path d="m3.17 6.366-1.732-1S.572 4.866 1.072 4s1.366-.366 1.366-.366l1.732 1s.866.5.366 1.366-1.366.366-1.366.366z" opacity=".86"/>
+  <path d="M3 9 1 9S0 9 0 8s1-1 1-1l2 0s1 0 1 1-1 1-1 1z" opacity=".79"/>
+  <path d="m4.17 11.366-1.732 1s-.866.5-1.366-.366.366-1.366.366-1.366l1.732-1s.866-.5 1.366.366-.366 1.366-.366 1.366z" opacity=".72"/>
+  <path d="m6.366 12.83-1 1.732s-.5.866-1.366.366-.366-1.366-.366-1.366l1-1.732s.5-.866 1.366-.366.366 1.366.366 1.366z" opacity=".65"/>
+  <path d="m9 13 0 2s0 1-1 1-1-1-1-1l0-2s0-1 1-1 1 1 1 1z" opacity=".58"/>
+  <path d="m11.366 11.83 1 1.732s.5.866-.366 1.366-1.366-.366-1.366-.366l-1-1.732s-.5-.866.366-1.366 1.366.366 1.366.366z" opacity=".51"/>
+  <path d="m12.83 9.634 1.732 1s.866.5.366 1.366-1.366.366-1.366.366l-1.732-1s-.866-.5-.366-1.366 1.366-.366 1.366-.366z" opacity=".44"/>
+  <path d="m13 7 2 0s1 0 1 1-1 1-1 1l-2 0s-1 0-1-1 1-1 1-1z" opacity=".37"/>
+  <path d="m11.83 4.634 1.732-1s.866-.5 1.366.366-.366 1.366-.366 1.366l-1.732 1s-.866.5-1.366-.366.366-1.366.366-1.366z" opacity=".5"/>
+  <path d="m9.634 3.17 1-1.732s.5-.866 1.366-.366.366 1.366.366 1.366l-1 1.732s-.5.866-1.366.366-.366-1.366-.366-1.366z" opacity=".75"/>
+</svg>