Home | History | Annotate | Download | only in signin
      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(&params);
    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