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/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