[unified-consent] Add 'Cancel sync?' dialog

- Add sync setup cancel dialog for confirming
  the sync cancellation during opt-in.
- This dialog is shown when the user clicks
  the 'Cancel' button in the account control
  or navigates away from the sync page.

Screenshot:
https://drive.google.com/file/d/1TaQbBntf1Or4y4CPOzFDHhKf9qLZWpDI/view?usp=sharing

Bug: 919745
Change-Id: I88de095ce7947cabf9363208579556a6486283a3
Reviewed-on: https://chromium-review.googlesource.com/c/1430016
Reviewed-by: Demetrios Papadopoulos <dpapad@chromium.org>
Commit-Queue: Thomas Tangl <tangltom@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#626780}(cherry picked from commit 501c7b5248048022035d30d36f988b2fc32539bf)
Reviewed-on: https://chromium-review.googlesource.com/c/1449662
Reviewed-by: Thomas Tangl <tangltom@chromium.org>
Cr-Commit-Position: refs/branch-heads/3683@{#118}
Cr-Branched-From: e51029943e0a38dd794b73caaf6373d5496ae783-refs/heads/master@{#625896}
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index f73abbf..1aa4c57 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -3661,6 +3661,12 @@
     <message name="IDS_SETTINGS_SYNC_SETTINGS_CANCEL_SYNC" desc="The label of button that allows user to cancel sync.">
       Cancel sync
     </message>
+    <message name="IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_TITLE" desc="The title of the dialog to confirm the sync cancellation.">
+      Cancel sync?
+    </message>
+    <message name="IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_BODY" desc="The body text of the dialog to confirm the sync cancellation.">
+      You can turn on sync anytime in settings
+    </message>
   </if>
   <message name="IDS_SETTINGS_SYNC_TIMEOUT" desc="Text explaining what to do if sync times out.">
     Check your internet connection. If the problem continues, try signing out and signing in again.
diff --git a/chrome/browser/resources/settings/people_page/sync_page.html b/chrome/browser/resources/settings/people_page/sync_page.html
index af69a2e..d4cd336 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.html
+++ b/chrome/browser/resources/settings/people_page/sync_page.html
@@ -3,6 +3,7 @@
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/html/util.html">
 <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html">
+<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_input/cr_input.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_radio_button/cr_radio_button.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_radio_group/cr_radio_group.html">
@@ -334,6 +335,24 @@
     </template>
 
 <if expr="not chromeos">
+    <template is="dom-if" if="[[showSetupCancelDialog_]]" restamp>
+      <cr-dialog id="setupCancelDialog" on-close="onSetupCancelDialogClose_"
+          ignore-popstate>
+        <div slot="title">$i18n{syncSetupCancelDialogTitle}</div>
+        <div slot="body">$i18n{syncSetupCancelDialogBody}</div>
+        <div slot="button-container">
+          <paper-button class="cancel-button"
+              on-click="onSetupCancelDialogBack_">
+            $i18n{back}
+          </paper-button>
+          <paper-button class="action-button"
+              on-click="onSetupCancelDialogConfirm_">
+            $i18n{cancelSync}
+          </paper-button>
+        </div>
+      </cr-dialog>
+    </template>
+
     <template is="dom-if" if="[[!unifiedConsentEnabled]]">
       <cr-toast id="toast" open="[[syncStatus.setupInProgress]]">
         <div>$i18n{syncWillStart}</div>
diff --git a/chrome/browser/resources/settings/people_page/sync_page.js b/chrome/browser/resources/settings/people_page/sync_page.js
index e7377df..b102f70 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.js
+++ b/chrome/browser/resources/settings/people_page/sync_page.js
@@ -141,6 +141,12 @@
       type: Boolean,
       observer: 'initializeDidAbort_',
     },
+
+    /** @private */
+    showSetupCancelDialog_: {
+      type: Boolean,
+      value: false,
+    },
   },
 
   /** @private {?settings.SyncBrowserProxy} */
@@ -172,6 +178,12 @@
    */
   didAbort_: false,
 
+  /**
+   * Whether the user clicked the confirm button on the "Cancel sync?" dialog.
+   * @private {boolean}
+   */
+  setupCancelDialogConfirmed_: false,
+
   /** @override */
   created: function() {
     this.browserProxy_ = settings.SyncBrowserProxyImpl.getInstance();
@@ -229,12 +241,42 @@
     return this.syncStatus != undefined && !!this.syncStatus.managed;
   },
 
+  /** @private */
+  onSetupCancelDialogBack_: function() {
+    this.$$('#setupCancelDialog').cancel();
+  },
+
+  /** @private */
+  onSetupCancelDialogConfirm_: function() {
+    this.setupCancelDialogConfirmed_ = true;
+    this.$$('#setupCancelDialog').close();
+    settings.navigateTo(settings.routes.BASIC);
+  },
+
+  /** @private */
+  onSetupCancelDialogClose_: function() {
+    this.showSetupCancelDialog_ = false;
+  },
+
   /** @protected */
   currentRouteChanged: function() {
     if (settings.getCurrentRoute() == settings.routes.SYNC) {
       this.onNavigateToPage_();
     } else if (!settings.routes.SYNC.contains(settings.getCurrentRoute())) {
-      this.onNavigateAwayFromPage_();
+      // When the user wants to cancel the sync setup, but hasn't confirmed
+      // the cancel dialog, navigate back and show the dialog.
+      if (this.unifiedConsentEnabled && this.syncStatus &&
+          !!this.syncStatus.setupInProgress && this.didAbort_ &&
+          !this.setupCancelDialogConfirmed_) {
+        settings.navigateTo(settings.routes.SYNC);
+        this.showSetupCancelDialog_ = true;
+        // Flush to make sure that the setup cancel dialog is attached.
+        Polymer.dom.flush();
+        this.$$('#setupCancelDialog').showModal();
+      } else {
+        this.setupCancelDialogConfirmed_ = false;
+        this.onNavigateAwayFromPage_();
+      }
     }
   },
 
@@ -540,7 +582,10 @@
         !this.unifiedConsentEnabled;
   },
 
-  /** @private */
+  /**
+   * Used when unified consent is disabled.
+   * @private
+   */
   onSyncSetupCancel_: function() {
     this.didAbort_ = true;
     settings.navigateTo(settings.routes.BASIC);
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 6e713e6..9d67762 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -1721,6 +1721,8 @@
                           : IDS_SETTINGS_SYNC_WILL_START},
     {"syncSettingsSavedToast", IDS_SETTINGS_SYNC_SETTINGS_SAVED_TOAST_LABEL},
     {"cancelSync", IDS_SETTINGS_SYNC_SETTINGS_CANCEL_SYNC},
+    {"syncSetupCancelDialogTitle", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_TITLE},
+    {"syncSetupCancelDialogBody", IDS_SETTINGS_SYNC_SETUP_CANCEL_DIALOG_BODY},
 #endif  // defined(OS_CHROMEOS)
 #if BUILDFLAG(ENABLE_DICE_SUPPORT)
     {"peopleSignIn", IDS_PROFILES_DICE_SIGNIN_BUTTON},
diff --git a/chrome/test/data/webui/settings/people_page_sync_page_test.js b/chrome/test/data/webui/settings/people_page_sync_page_test.js
index b7b2e1e..a444757 100644
--- a/chrome/test/data/webui/settings/people_page_sync_page_test.js
+++ b/chrome/test/data/webui/settings/people_page_sync_page_test.js
@@ -536,13 +536,43 @@
         const cancelButton =
             syncPage.$$('settings-sync-account-control')
                 .shadowRoot.querySelector('#setup-buttons .secondary-button');
-
         assertTrue(!!cancelButton);
-        cancelButton.click();
 
-        return browserProxy.whenCalled('didNavigateAwayFromSyncPage')
-            .then(abort => {
-              assertTrue(abort);
+        // Clicking the setup cancel button opens the 'Cancel sync?' dialog.
+        cancelButton.click();
+        Polymer.dom.flush();
+
+        assertEquals(settings.routes.SYNC, settings.getCurrentRoute());
+        assertTrue(!!syncPage.$$('#setupCancelDialog'));
+        assertTrue(syncPage.$$('#setupCancelDialog').open);
+
+        // Clicking the cancel button on the 'Cancel sync?' dialog closes the
+        // dialog and removes it from the DOM.
+        syncPage.$$('#setupCancelDialog')
+            .querySelector('.cancel-button')
+            .click();
+        return test_util
+            .eventToPromise('close', syncPage.$$('#setupCancelDialog'))
+            .then(() => {
+              Polymer.dom.flush();
+              assertEquals(settings.routes.SYNC, settings.getCurrentRoute());
+              assertFalse(!!syncPage.$$('#setupCancelDialog'));
+
+              // Clicking the setup cancel button shows the 'Cancel sync?'
+              // dialog again.
+              cancelButton.click();
+              Polymer.dom.flush();
+              assertTrue(syncPage.$$('#setupCancelDialog').open);
+
+              // Clicking the confirm button on the dialog aborts sync.
+              syncPage.$$('#setupCancelDialog')
+                  .querySelector('.action-button')
+                  .click();
+
+              return browserProxy.whenCalled('didNavigateAwayFromSyncPage')
+                  .then(abort => {
+                    assertTrue(abort);
+                  });
             });
       });
 
@@ -573,9 +603,26 @@
 
       test('SyncSetupLeavePage UnifiedConsentEnabled', function() {
         syncPage.unifiedConsentEnabled = true;
+        syncPage.syncStatus = {
+          signinAllowed: true,
+          syncSystemEnabled: true,
+          setupInProgress: true,
+          signedIn: true
+        };
         Polymer.dom.flush();
 
+        // Navigating away while setup is in progress opens the 'Cancel sync?'
+        // dialog.
         settings.navigateTo(settings.routes.BASIC);
+        Polymer.dom.flush();
+
+        assertEquals(settings.routes.SYNC, settings.getCurrentRoute());
+        assertTrue(syncPage.$$('#setupCancelDialog').open);
+
+        // Clicking the confirm button on the dialog aborts sync.
+        syncPage.$$('#setupCancelDialog')
+            .querySelector('.action-button')
+            .click();
 
         return browserProxy.whenCalled('didNavigateAwayFromSyncPage')
             .then(abort => {