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/strings/sys_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/profiles/profile.h" 10 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 11 #include "chrome/browser/signin/signin_global_error.h" 12 #include "chrome/browser/signin/signin_global_error_factory.h" 13 #include "chrome/browser/signin/signin_manager_factory.h" 14 #include "chrome/browser/sync/profile_sync_service.h" 15 #include "chrome/browser/sync/profile_sync_service_factory.h" 16 #include "chrome/browser/sync/sync_global_error.h" 17 #include "chrome/browser/sync/sync_global_error_factory.h" 18 #include "components/signin/core/browser/profile_oauth2_token_service.h" 19 #include "components/signin/core/browser/signin_manager.h" 20 #include "grit/chromium_strings.h" 21 #include "grit/generated_resources.h" 22 #include "ui/base/l10n/l10n_util.h" 23 #include "ui/gfx/font_list.h" 24 #include "ui/gfx/text_elider.h" 25 26 namespace { 27 // Maximum width of a username - we trim emails that are wider than this so 28 // the wrench menu doesn't get ridiculously wide. 29 const int kUsernameMaxWidth = 200; 30 } // namespace 31 32 namespace signin_ui_util { 33 34 GlobalError* GetSignedInServiceError(Profile* profile) { 35 std::vector<GlobalError*> errors = GetSignedInServiceErrors(profile); 36 if (errors.empty()) 37 return NULL; 38 return errors[0]; 39 } 40 41 std::vector<GlobalError*> GetSignedInServiceErrors(Profile* profile) { 42 std::vector<GlobalError*> errors; 43 // Chrome OS doesn't use SigninGlobalError or SyncGlobalError. Other platforms 44 // may use these services to show auth and sync errors in the toolbar menu. 45 #if !defined(OS_CHROMEOS) 46 // Auth errors have the highest priority - after that, individual service 47 // errors. 48 SigninGlobalError* signin_error = 49 SigninGlobalErrorFactory::GetForProfile(profile); 50 if (signin_error && signin_error->HasError()) 51 errors.push_back(signin_error); 52 53 // No auth error - now try other services. Currently the list is just hard- 54 // coded but in the future if we add more we can create some kind of 55 // registration framework. 56 if (profile->IsSyncAccessible()) { 57 SyncGlobalError* error = SyncGlobalErrorFactory::GetForProfile(profile); 58 if (error && error->HasMenuItem()) 59 errors.push_back(error); 60 } 61 #endif 62 63 return errors; 64 } 65 66 base::string16 GetSigninMenuLabel(Profile* profile) { 67 GlobalError* error = signin_ui_util::GetSignedInServiceError(profile); 68 if (error) 69 return error->MenuItemLabel(); 70 71 // No errors, so just display the signed in user, if any. 72 ProfileSyncService* service = profile->IsSyncAccessible() ? 73 ProfileSyncServiceFactory::GetForProfile(profile) : NULL; 74 75 // Even if the user is signed in, don't display the "signed in as..." 76 // label if we're still setting up sync. 77 if (!service || !service->FirstSetupInProgress()) { 78 std::string username; 79 SigninManagerBase* signin_manager = 80 SigninManagerFactory::GetForProfileIfExists(profile); 81 if (signin_manager) 82 username = signin_manager->GetAuthenticatedUsername(); 83 if (!username.empty() && !signin_manager->AuthInProgress()) { 84 const base::string16 elided = gfx::ElideText(base::UTF8ToUTF16(username), 85 gfx::FontList(), kUsernameMaxWidth, gfx::ELIDE_EMAIL); 86 return l10n_util::GetStringFUTF16(IDS_SYNC_MENU_SYNCED_LABEL, elided); 87 } 88 } 89 return l10n_util::GetStringFUTF16(IDS_SYNC_MENU_PRE_SYNCED_LABEL, 90 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME)); 91 } 92 93 // Given an authentication state this helper function returns various labels 94 // that can be used to display information about the state. 95 void GetStatusLabelsForAuthError(Profile* profile, 96 const SigninManagerBase& signin_manager, 97 base::string16* status_label, 98 base::string16* link_label) { 99 base::string16 username = 100 base::UTF8ToUTF16(signin_manager.GetAuthenticatedUsername()); 101 base::string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 102 if (link_label) 103 link_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL)); 104 105 const GoogleServiceAuthError::State state = 106 ProfileOAuth2TokenServiceFactory::GetForProfile(profile)-> 107 signin_error_controller()->auth_error().state(); 108 switch (state) { 109 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 110 case GoogleServiceAuthError::SERVICE_ERROR: 111 case GoogleServiceAuthError::ACCOUNT_DELETED: 112 case GoogleServiceAuthError::ACCOUNT_DISABLED: 113 // If the user name is empty then the first login failed, otherwise the 114 // credentials are out-of-date. 115 if (username.empty()) { 116 if (status_label) { 117 status_label->assign( 118 l10n_util::GetStringUTF16(IDS_SYNC_INVALID_USER_CREDENTIALS)); 119 } 120 } else { 121 if (status_label) { 122 status_label->assign( 123 l10n_util::GetStringUTF16(IDS_SYNC_LOGIN_INFO_OUT_OF_DATE)); 124 } 125 } 126 break; 127 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: 128 if (status_label) { 129 status_label->assign( 130 l10n_util::GetStringUTF16(IDS_SYNC_SERVICE_UNAVAILABLE)); 131 } 132 if (link_label) 133 link_label->clear(); 134 break; 135 case GoogleServiceAuthError::CONNECTION_FAILED: 136 if (status_label) { 137 status_label->assign( 138 l10n_util::GetStringFUTF16(IDS_SYNC_SERVER_IS_UNREACHABLE, 139 product_name)); 140 } 141 // Note that there is little the user can do if the server is not 142 // reachable. Since attempting to re-connect is done automatically by 143 // the Syncer, we do not show the (re)login link. 144 if (link_label) 145 link_label->clear(); 146 break; 147 default: 148 if (status_label) { 149 status_label->assign(l10n_util::GetStringUTF16( 150 IDS_SYNC_ERROR_SIGNING_IN)); 151 } 152 break; 153 } 154 } 155 156 } // namespace signin_ui_util 157