1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/signin/signin_ui_util.h" 6 7 #include "base/prefs/pref_service.h" 8 #include "base/strings/sys_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/signin/account_tracker_service_factory.h" 12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 13 #include "chrome/browser/signin/signin_global_error.h" 14 #include "chrome/browser/signin/signin_global_error_factory.h" 15 #include "chrome/browser/signin/signin_manager_factory.h" 16 #include "chrome/browser/sync/profile_sync_service.h" 17 #include "chrome/browser/sync/profile_sync_service_factory.h" 18 #include "chrome/browser/sync/sync_global_error.h" 19 #include "chrome/browser/sync/sync_global_error_factory.h" 20 #include "chrome/browser/ui/browser_navigator.h" 21 #include "chrome/common/pref_names.h" 22 #include "chrome/grit/chromium_strings.h" 23 #include "chrome/grit/generated_resources.h" 24 #include "components/signin/core/browser/account_tracker_service.h" 25 #include "components/signin/core/browser/profile_oauth2_token_service.h" 26 #include "components/signin/core/browser/signin_manager.h" 27 #include "components/signin/core/common/profile_management_switches.h" 28 #include "ui/base/l10n/l10n_util.h" 29 #include "ui/gfx/font_list.h" 30 #include "ui/gfx/text_elider.h" 31 32 namespace { 33 // Maximum width of a username - we trim emails that are wider than this so 34 // the wrench menu doesn't get ridiculously wide. 35 const int kUsernameMaxWidth = 200; 36 } // namespace 37 38 namespace signin_ui_util { 39 40 GlobalError* GetSignedInServiceError(Profile* profile) { 41 std::vector<GlobalError*> errors = GetSignedInServiceErrors(profile); 42 if (errors.empty()) 43 return NULL; 44 return errors[0]; 45 } 46 47 std::vector<GlobalError*> GetSignedInServiceErrors(Profile* profile) { 48 std::vector<GlobalError*> errors; 49 // Chrome OS doesn't use SigninGlobalError or SyncGlobalError. Other platforms 50 // may use these services to show auth and sync errors in the toolbar menu. 51 #if !defined(OS_CHROMEOS) 52 // Auth errors have the highest priority - after that, individual service 53 // errors. 54 SigninGlobalError* signin_error = 55 SigninGlobalErrorFactory::GetForProfile(profile); 56 if (signin_error && signin_error->HasError()) 57 errors.push_back(signin_error); 58 59 // No auth error - now try other services. Currently the list is just hard- 60 // coded but in the future if we add more we can create some kind of 61 // registration framework. 62 if (profile->IsSyncAccessible()) { 63 SyncGlobalError* error = SyncGlobalErrorFactory::GetForProfile(profile); 64 if (error && error->HasMenuItem()) 65 errors.push_back(error); 66 } 67 #endif 68 69 return errors; 70 } 71 72 base::string16 GetSigninMenuLabel(Profile* profile) { 73 GlobalError* error = signin_ui_util::GetSignedInServiceError(profile); 74 if (error) 75 return error->MenuItemLabel(); 76 77 // No errors, so just display the signed in user, if any. 78 ProfileSyncService* service = profile->IsSyncAccessible() ? 79 ProfileSyncServiceFactory::GetForProfile(profile) : NULL; 80 81 // Even if the user is signed in, don't display the "signed in as..." 82 // label if we're still setting up sync. 83 if (!service || !service->FirstSetupInProgress()) { 84 std::string username; 85 SigninManagerBase* signin_manager = 86 SigninManagerFactory::GetForProfileIfExists(profile); 87 if (signin_manager) 88 username = signin_manager->GetAuthenticatedUsername(); 89 if (!username.empty() && !signin_manager->AuthInProgress()) { 90 const base::string16 elided = gfx::ElideText(base::UTF8ToUTF16(username), 91 gfx::FontList(), kUsernameMaxWidth, gfx::ELIDE_EMAIL); 92 return l10n_util::GetStringFUTF16(IDS_SYNC_MENU_SYNCED_LABEL, elided); 93 } 94 } 95 return l10n_util::GetStringFUTF16(IDS_SYNC_MENU_PRE_SYNCED_LABEL, 96 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); 97 } 98 99 // Given an authentication state this helper function returns various labels 100 // that can be used to display information about the state. 101 void GetStatusLabelsForAuthError(Profile* profile, 102 const SigninManagerBase& signin_manager, 103 base::string16* status_label, 104 base::string16* link_label) { 105 base::string16 username = 106 base::UTF8ToUTF16(signin_manager.GetAuthenticatedUsername()); 107 base::string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 108 if (link_label) 109 link_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL)); 110 111 const GoogleServiceAuthError::State state = 112 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)-> 113 signin_error_controller()->auth_error().state(); 114 switch (state) { 115 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 116 case GoogleServiceAuthError::SERVICE_ERROR: 117 case GoogleServiceAuthError::ACCOUNT_DELETED: 118 case GoogleServiceAuthError::ACCOUNT_DISABLED: 119 // If the user name is empty then the first login failed, otherwise the 120 // credentials are out-of-date. 121 if (username.empty()) { 122 if (status_label) { 123 status_label->assign( 124 l10n_util::GetStringUTF16(IDS_SYNC_INVALID_USER_CREDENTIALS)); 125 } 126 } else { 127 if (status_label) { 128 status_label->assign( 129 l10n_util::GetStringUTF16(IDS_SYNC_LOGIN_INFO_OUT_OF_DATE)); 130 } 131 } 132 break; 133 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: 134 if (status_label) { 135 status_label->assign( 136 l10n_util::GetStringUTF16(IDS_SYNC_SERVICE_UNAVAILABLE)); 137 } 138 if (link_label) 139 link_label->clear(); 140 break; 141 case GoogleServiceAuthError::CONNECTION_FAILED: 142 if (status_label) { 143 status_label->assign( 144 l10n_util::GetStringFUTF16(IDS_SYNC_SERVER_IS_UNREACHABLE, 145 product_name)); 146 } 147 // Note that there is little the user can do if the server is not 148 // reachable. Since attempting to re-connect is done automatically by 149 // the Syncer, we do not show the (re)login link. 150 if (link_label) 151 link_label->clear(); 152 break; 153 default: 154 if (status_label) { 155 status_label->assign(l10n_util::GetStringUTF16( 156 IDS_SYNC_ERROR_SIGNING_IN)); 157 } 158 break; 159 } 160 } 161 162 void InitializePrefsForProfile(Profile* profile) { 163 // Suppresses the upgrade tutorial for a new profile. 164 if (profile->IsNewProfile() && switches::IsNewAvatarMenu()) { 165 profile->GetPrefs()->SetInteger( 166 prefs::kProfileAvatarTutorialShown, kUpgradeWelcomeTutorialShowMax + 1); 167 } 168 } 169 170 void ShowSigninErrorLearnMorePage(Profile* profile) { 171 static const char kSigninErrorLearnMoreUrl[] = 172 "https://support.google.com/chrome/answer/1181420?"; 173 chrome::NavigateParams params( 174 profile, GURL(kSigninErrorLearnMoreUrl), ui::PAGE_TRANSITION_LINK); 175 params.disposition = NEW_FOREGROUND_TAB; 176 chrome::Navigate(¶ms); 177 } 178 179 std::string GetDisplayEmail(Profile* profile, const std::string& account_id) { 180 AccountTrackerService* account_tracker = 181 AccountTrackerServiceFactory::GetForProfile(profile); 182 std::string email = account_tracker->GetAccountInfo(account_id).email; 183 if (email.empty()) { 184 DCHECK_EQ(AccountTrackerService::MIGRATION_NOT_STARTED, 185 account_tracker->GetMigrationState()); 186 return account_id; 187 } 188 return email; 189 } 190 191 } // namespace signin_ui_util 192