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