| Index: chrome/browser/ui/views/profiles/profile_chooser_view.cc
|
| diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
|
| index 55004998fff8cab168ef10f41037d458d50be60c..72d65ad4300b604ee8037d07f3fe37f9648ad024 100644
|
| --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc
|
| +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
|
| @@ -21,6 +21,7 @@
|
| #include "chrome/browser/signin/signin_manager_factory.h"
|
| #include "chrome/browser/signin/signin_promo.h"
|
| #include "chrome/browser/signin/signin_ui_util.h"
|
| +#include "chrome/browser/sync/profile_sync_service_factory.h"
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/browser_commands.h"
|
| #include "chrome/browser/ui/browser_dialogs.h"
|
| @@ -36,12 +37,14 @@
|
| #include "chrome/common/url_constants.h"
|
| #include "chrome/grit/chromium_strings.h"
|
| #include "chrome/grit/generated_resources.h"
|
| +#include "components/browser_sync/browser/profile_sync_service.h"
|
| #include "components/prefs/pref_service.h"
|
| #include "components/signin/core/browser/profile_oauth2_token_service.h"
|
| #include "components/signin/core/browser/signin_error_controller.h"
|
| #include "components/signin/core/browser/signin_header_helper.h"
|
| #include "components/signin/core/browser/signin_manager.h"
|
| #include "components/signin/core/common/profile_management_switches.h"
|
| +#include "components/sync_driver/sync_error_controller.h"
|
| #include "content/public/browser/render_widget_host_view.h"
|
| #include "content/public/browser/user_metrics.h"
|
| #include "grit/theme_resources.h"
|
| @@ -764,6 +767,17 @@ void ProfileChooserView::ResetView() {
|
| open_other_profile_indexes_map_.clear();
|
| delete_account_button_map_.clear();
|
| reauth_account_button_map_.clear();
|
| + tutorial_sync_settings_ok_button_ = nullptr;
|
| + tutorial_close_button_ = nullptr;
|
| + tutorial_sync_settings_link_ = nullptr;
|
| + tutorial_see_whats_new_button_ = nullptr;
|
| + tutorial_not_you_link_ = nullptr;
|
| + tutorial_learn_more_link_ = nullptr;
|
| + sync_error_signin_button_ = nullptr;
|
| + sync_error_passphrase_button_ = nullptr;
|
| + sync_error_upgrade_button_ = nullptr;
|
| + sync_error_signin_again_button_ = nullptr;
|
| + sync_error_signout_button_ = nullptr;
|
| manage_accounts_link_ = nullptr;
|
| manage_accounts_button_ = nullptr;
|
| signin_current_profile_button_ = nullptr;
|
| @@ -783,12 +797,6 @@ void ProfileChooserView::ResetView() {
|
| add_person_button_ = nullptr;
|
| disconnect_button_ = nullptr;
|
| switch_user_cancel_button_ = nullptr;
|
| - tutorial_sync_settings_ok_button_ = nullptr;
|
| - tutorial_close_button_ = nullptr;
|
| - tutorial_sync_settings_link_ = nullptr;
|
| - tutorial_see_whats_new_button_ = nullptr;
|
| - tutorial_not_you_link_ = nullptr;
|
| - tutorial_learn_more_link_ = nullptr;
|
| }
|
|
|
| void ProfileChooserView::Init() {
|
| @@ -873,7 +881,12 @@ void ProfileChooserView::ShowView(profiles::BubbleViewMode view_to_display,
|
| DCHECK(switches::IsEnableAccountConsistency());
|
| const AvatarMenu::Item& active_item = avatar_menu->GetItemAt(
|
| avatar_menu->GetActiveProfileIndex());
|
| - DCHECK(active_item.signed_in);
|
| + if (!active_item.signed_in) {
|
| + // This is the case when the user selects the sign out option in the user
|
| + // menu upon encountering unrecoverable errors. Afterwards, the profile
|
| + // chooser view is shown instead of the account management view.
|
| + view_to_display = profiles::BUBBLE_VIEW_MODE_PROFILE_CHOOSER;
|
| + }
|
| }
|
|
|
| if (browser_->profile()->IsSupervised() &&
|
| @@ -1001,8 +1014,22 @@ void ProfileChooserView::ButtonPressed(views::Button* sender,
|
| PostActionPerformed(ProfileMetrics::PROFILE_DESKTOP_MENU_LOCK);
|
| } else if (sender == close_all_windows_button_) {
|
| profiles::CloseProfileWindows(browser_->profile());
|
| - } else if (sender == auth_error_email_button_) {
|
| + } else if (sender == auth_error_email_button_ ||
|
| + sender == sync_error_signin_button_) {
|
| ShowViewFromMode(profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH);
|
| + } else if (sender == sync_error_passphrase_button_) {
|
| + chrome::ShowSettingsSubPage(browser_, chrome::kSyncSetupSubPage);
|
| + } else if (sender == sync_error_upgrade_button_) {
|
| + chrome::OpenUpdateChromeDialog(browser_);
|
| + } else if (sender == sync_error_signin_again_button_) {
|
| + if (ProfileSyncServiceFactory::GetForProfile(browser_->profile()))
|
| + ProfileSyncService::SyncEvent(ProfileSyncService::STOP_FROM_OPTIONS);
|
| + SigninManagerFactory::GetForProfile(browser_->profile())
|
| + ->SignOut(signin_metrics::USER_CLICKED_SIGNOUT_SETTINGS,
|
| + signin_metrics::SignoutDelete::IGNORE_METRIC);
|
| + ShowViewFromMode(profiles::BUBBLE_VIEW_MODE_GAIA_SIGNIN);
|
| + } else if (sender == sync_error_signout_button_) {
|
| + chrome::ShowSettingsSubPage(browser_, chrome::kSignOutSubPage);
|
| } else if (sender == tutorial_sync_settings_ok_button_) {
|
| LoginUIServiceFactory::GetForProfile(browser_->profile())->
|
| SyncConfirmationUIClosed(LoginUIService::SYNC_WITH_DEFAULT_SETTINGS);
|
| @@ -1176,6 +1203,7 @@ void ProfileChooserView::PopulateCompleteProfileChooserView(
|
| // Separate items into active and alternatives.
|
| Indexes other_profiles;
|
| views::View* tutorial_view = NULL;
|
| + views::View* sync_error_view = NULL;
|
| views::View* current_profile_view = NULL;
|
| views::View* current_profile_accounts = NULL;
|
| views::View* option_buttons_view = NULL;
|
| @@ -1190,10 +1218,13 @@ void ProfileChooserView::PopulateCompleteProfileChooserView(
|
| ? CreateMaterialDesignCurrentProfileView(item, false)
|
| : CreateCurrentProfileView(item, false);
|
| if (IsProfileChooser(view_mode_)) {
|
| - tutorial_view = CreateTutorialViewIfNeeded(item);
|
| + if (!switches::IsMaterialDesignUserMenu())
|
| + tutorial_view = CreateTutorialViewIfNeeded(item);
|
| } else {
|
| current_profile_accounts = CreateCurrentProfileAccountsView(item);
|
| }
|
| + if (switches::IsMaterialDesignUserMenu())
|
| + sync_error_view = CreateSyncErrorViewIfNeeded();
|
| } else {
|
| other_profiles.push_back(i);
|
| }
|
| @@ -1207,6 +1238,13 @@ void ProfileChooserView::PopulateCompleteProfileChooserView(
|
| tutorial_mode_ = profiles::TUTORIAL_MODE_NONE;
|
| }
|
|
|
| + if (sync_error_view) {
|
| + layout->StartRow(1, 0);
|
| + layout->AddView(sync_error_view);
|
| + layout->StartRow(0, 0);
|
| + layout->AddView(new views::Separator(views::Separator::HORIZONTAL));
|
| + }
|
| +
|
| if (!current_profile_view) {
|
| // Guest windows don't have an active profile.
|
| current_profile_view = CreateGuestProfileView();
|
| @@ -1435,6 +1473,127 @@ views::View* ProfileChooserView::CreateTutorialView(
|
| return view;
|
| }
|
|
|
| +views::View* ProfileChooserView::CreateSyncErrorViewIfNeeded() {
|
| + ProfileSyncService* service =
|
| + ProfileSyncServiceFactory::GetForProfile(browser_->profile());
|
| +
|
| + // The order or priority is going to be: 1. Unrecoverable errors.
|
| + // 2. Auth errors. 3. Protocol errors. 4. Passphrase errors.
|
| + if (service && service->HasUnrecoverableError()) {
|
| + // An unrecoverable error is sometimes accompanied by an actionable error.
|
| + // If an actionable error is not set to be UPGRADE_CLIENT, then show a
|
| + // generic unrecoverable error message.
|
| + ProfileSyncService::Status status;
|
| + service->QueryDetailedSyncStatus(&status);
|
| + if (status.sync_protocol_error.action != syncer::UPGRADE_CLIENT) {
|
| + // Display different messages and buttons for managed accounts.
|
| + if (SigninManagerFactory::GetForProfile(browser_->profile())
|
| + ->IsSignoutProhibited()) {
|
| + // For a managed user, the user is directed to the signout
|
| + // confirmation dialogue in the settings page.
|
| + return CreateSyncErrorView(IDS_SYNC_ERROR_USER_MENU_SIGNOUT_MESSAGE,
|
| + IDS_SYNC_ERROR_USER_MENU_SIGNOUT_BUTTON,
|
| + &sync_error_signout_button_);
|
| + }
|
| + // For a non-managed user, we sign out on the user's behalf and prompt
|
| + // the user to sign in again.
|
| + return CreateSyncErrorView(IDS_SYNC_ERROR_USER_MENU_SIGNIN_AGAIN_MESSAGE,
|
| + IDS_SYNC_ERROR_USER_MENU_SIGNIN_AGAIN_BUTTON,
|
| + &sync_error_signin_again_button_);
|
| + }
|
| + }
|
| +
|
| + // Check for an auth error.
|
| + if (HasAuthError(browser_->profile())) {
|
| + return CreateSyncErrorView(IDS_SYNC_ERROR_USER_MENU_SIGNIN_MESSAGE,
|
| + IDS_SYNC_ERROR_USER_MENU_SIGNIN_BUTTON,
|
| + &sync_error_signin_button_);
|
| + }
|
| +
|
| + // Check for sync errors if the sync service is enabled.
|
| + if (service) {
|
| + // Check for an actionable UPGRADE_CLIENT error.
|
| + ProfileSyncService::Status status;
|
| + service->QueryDetailedSyncStatus(&status);
|
| + if (status.sync_protocol_error.action == syncer::UPGRADE_CLIENT) {
|
| + return CreateSyncErrorView(IDS_SYNC_ERROR_USER_MENU_UPGRADE_MESSAGE,
|
| + IDS_SYNC_ERROR_USER_MENU_UPGRADE_BUTTON,
|
| + &sync_error_upgrade_button_);
|
| + }
|
| +
|
| + // Check for a sync passphrase error.
|
| + SyncErrorController* sync_error_controller =
|
| + service->sync_error_controller();
|
| + if (sync_error_controller && sync_error_controller->HasError()) {
|
| + return CreateSyncErrorView(IDS_SYNC_ERROR_USER_MENU_PASSPHRASE_MESSAGE,
|
| + IDS_SYNC_ERROR_USER_MENU_PASSPHRASE_BUTTON,
|
| + &sync_error_passphrase_button_);
|
| + }
|
| + }
|
| +
|
| + // There is no error.
|
| + return nullptr;
|
| +}
|
| +
|
| +views::View* ProfileChooserView::CreateSyncErrorView(
|
| + const int content_string_id,
|
| + const int button_string_id,
|
| + views::LabelButton** button_out) {
|
| + // Sets an overall horizontal layout.
|
| + views::View* view = new views::View();
|
| + views::BoxLayout* layout = new views::BoxLayout(
|
| + views::BoxLayout::kHorizontal, kMaterialMenuEdgeMargin,
|
| + kMaterialMenuEdgeMargin, views::kUnrelatedControlHorizontalSpacing);
|
| + layout->set_cross_axis_alignment(
|
| + views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
|
| + view->SetLayoutManager(layout);
|
| +
|
| + // Adds the sync problem icon.
|
| + views::ImageView* sync_problem_icon = new views::ImageView();
|
| + sync_problem_icon->SetImage(gfx::CreateVectorIcon(
|
| + gfx::VectorIconId::SYNC_PROBLEM, 20, gfx::kGoogleRed700));
|
| + view->AddChildView(sync_problem_icon);
|
| +
|
| + // Adds a vertical view to organize the error title, message, and button.
|
| + views::View* vertical_view = new views::View();
|
| + views::BoxLayout* vertical_layout =
|
| + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0,
|
| + views::kRelatedControlSmallVerticalSpacing);
|
| + vertical_layout->set_cross_axis_alignment(
|
| + views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
|
| + vertical_view->SetLayoutManager(vertical_layout);
|
| +
|
| + // Adds the title.
|
| + views::Label* title_label = new views::Label(
|
| + l10n_util::GetStringUTF16(IDS_SYNC_ERROR_USER_MENU_TITLE));
|
| + title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + title_label->SetEnabledColor(gfx::kGoogleRed700);
|
| + vertical_view->AddChildView(title_label);
|
| +
|
| + // Adds body content.
|
| + views::Label* content_label =
|
| + new views::Label(l10n_util::GetStringUTF16(content_string_id));
|
| + content_label->SetMultiLine(true);
|
| + content_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + vertical_view->AddChildView(content_label);
|
| +
|
| + // Adds a padding row between error title/content and the button.
|
| + SizedContainer* padding =
|
| + new SizedContainer(gfx::Size(0, views::kRelatedControlVerticalSpacing));
|
| + vertical_view->AddChildView(padding);
|
| +
|
| + // Adds an action button.
|
| + *button_out = views::MdTextButton::CreateSecondaryUiBlueButton(
|
| + this, l10n_util::GetStringUTF16(button_string_id));
|
| + vertical_view->AddChildView(*button_out);
|
| +
|
| + view->AddChildView(vertical_view);
|
| + view->SetBorder(views::Border::CreateEmptyBorder(
|
| + 0, 0, views::kRelatedControlSmallVerticalSpacing, 0));
|
| +
|
| + return view;
|
| +}
|
| +
|
| views::View* ProfileChooserView::CreateCurrentProfileView(
|
| const AvatarMenu::Item& avatar_item,
|
| bool is_guest) {
|
|
|