12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/signin/signin_global_error.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/app/chrome_command_ids.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/profiles/profile.h" 10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/signin/signin_header_helper.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_manager_factory.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_promo.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/global_error/global_error_service_factory.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/ui/singleton_tabs.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/signin/login_ui_service.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h" 2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/chromium_strings.h" 2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h" 24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h" 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/signin/core/common/profile_management_switches.h" 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/base/url_util.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SigninGlobalError::SigninGlobalError( 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SigninErrorController* error_controller, 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Profile* profile) 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) : profile_(profile), 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) error_controller_(error_controller), 34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_added_to_global_error_service_(false) { 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_controller_->AddObserver(this); 36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) is_added_to_global_error_service_ = !switches::IsNewAvatarMenu(); 37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_added_to_global_error_service_) 38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GlobalErrorServiceFactory::GetForProfile(profile_)->AddGlobalError(this); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SigninGlobalError::~SigninGlobalError() { 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(!error_controller_) 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) << "SigninGlobalError::Shutdown() was not called"; 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool SigninGlobalError::HasError() { 47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return HasMenuItem(); 48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void SigninGlobalError::AttemptToFixError(Browser* browser) { 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!HasError()) 52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExecuteMenuItem(browser); 55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SigninGlobalError::Shutdown() { 58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (is_added_to_global_error_service_) { 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GlobalErrorServiceFactory::GetForProfile(profile_)->RemoveGlobalError(this); 60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) is_added_to_global_error_service_ = false; 61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_controller_->RemoveObserver(this); 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) error_controller_ = NULL; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SigninGlobalError::HasMenuItem() { 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return error_controller_->HasError(); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int SigninGlobalError::MenuItemCommandID() { 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return IDC_SHOW_SIGNIN_ERROR; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SigninGlobalError::MenuItemLabel() { 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Notify the user if there's an auth error the user should know about. 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_controller_->HasError()) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return l10n_util::GetStringUTF16(IDS_SYNC_SIGN_IN_ERROR_WRENCH_MENU_ITEM); 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return base::string16(); 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SigninGlobalError::ExecuteMenuItem(Browser* browser) { 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_controller_->auth_error().state() != 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GoogleServiceAuthError::NONE) { 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DVLOG(1) << "Signing out the user to fix a sync error."; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(beng): seems like this could just call chrome::AttemptUserExit(). 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::ExecuteCommand(browser, IDC_EXIT); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Global errors don't show up in the wrench menu on android. 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(OS_ANDROID) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(profile_); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (login_ui->current_login_ui()) { 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) login_ui->current_login_ui()->FocusUI(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (switches::IsNewAvatarMenu()) { 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) browser->window()->ShowAvatarBubbleFromAvatarButton( 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) BrowserWindow::AVATAR_BUBBLE_MODE_REAUTH, 1046d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) signin::ManageAccountsParams()); 105cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else { 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::ShowSingletonTab( 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) browser, 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) signin::GetReauthURL(profile_, error_controller_->error_account_id())); 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SigninGlobalError::HasBubbleView() { 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !GetBubbleViewMessages().empty(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SigninGlobalError::GetBubbleViewTitle() { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return l10n_util::GetStringUTF16(IDS_SIGNIN_ERROR_BUBBLE_VIEW_TITLE); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::vector<base::string16> SigninGlobalError::GetBubbleViewMessages() { 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<base::string16> messages; 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the user isn't signed in, no need to display an error bubble. 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SigninManagerBase* signin_manager = 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SigninManagerFactory::GetForProfileIfExists(profile_); 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (signin_manager && !signin_manager->IsAuthenticated()) 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return messages; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!error_controller_->HasError()) 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return messages; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) switch (error_controller_->auth_error().state()) { 1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(rogerta): use account id in error messages. 1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // User credentials are invalid (bad acct, etc). 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case GoogleServiceAuthError::SERVICE_ERROR: 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GoogleServiceAuthError::ACCOUNT_DELETED: 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GoogleServiceAuthError::ACCOUNT_DISABLED: 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) messages.push_back(l10n_util::GetStringUTF16( 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE)); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sync service is not available for this account's domain. 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case GoogleServiceAuthError::SERVICE_UNAVAILABLE: 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) messages.push_back(l10n_util::GetStringUTF16( 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_MESSAGE)); 149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Generic message for "other" errors. 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) messages.push_back(l10n_util::GetStringUTF16( 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) IDS_SYNC_OTHER_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE)); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return messages; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SigninGlobalError::GetBubbleViewAcceptButtonLabel() { 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // If the auth service is unavailable, don't give the user the option to try 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // signing in again. 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (error_controller_->auth_error().state() == 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GoogleServiceAuthError::SERVICE_UNAVAILABLE) { 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return l10n_util::GetStringUTF16( 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_ACCEPT); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return l10n_util::GetStringUTF16(IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_ACCEPT); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 SigninGlobalError::GetBubbleViewCancelButtonLabel() { 172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return base::string16(); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SigninGlobalError::OnBubbleViewDidClose(Browser* browser) { 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SigninGlobalError::BubbleViewAcceptButtonPressed(Browser* browser) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ExecuteMenuItem(browser); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SigninGlobalError::BubbleViewCancelButtonPressed(Browser* browser) { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void SigninGlobalError::OnErrorChanged() { 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GlobalErrorServiceFactory::GetForProfile(profile_)->NotifyErrorsChanged(this); 1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 189