• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/gfx/font_list.h"
20 #include "ui/gfx/text_elider.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 
GetSignedInServiceError(Profile * profile)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 
GetSignedInServiceErrors(Profile * profile)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 
GetSigninMenuLabel(Profile * profile)60 base::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       base::string16 elided_username = gfx::ElideEmail(UTF8ToUTF16(username),
79                                                  gfx::FontList(),
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.
GetStatusLabelsForAuthError(Profile * profile,const SigninManagerBase & signin_manager,base::string16 * status_label,base::string16 * link_label)91 void GetStatusLabelsForAuthError(Profile* profile,
92                                  const SigninManagerBase& signin_manager,
93                                  base::string16* status_label,
94                                  base::string16* link_label) {
95   base::string16 username =
96       UTF8ToUTF16(signin_manager.GetAuthenticatedUsername());
97   base::string16 product_name = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME);
98   if (link_label)
99     link_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL));
100 
101   const GoogleServiceAuthError::State state =
102       SigninGlobalError::GetForProfile(profile)->GetLastAuthError().state();
103   switch (state) {
104     case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
105     case GoogleServiceAuthError::SERVICE_ERROR:
106     case GoogleServiceAuthError::ACCOUNT_DELETED:
107     case GoogleServiceAuthError::ACCOUNT_DISABLED:
108       // If the user name is empty then the first login failed, otherwise the
109       // credentials are out-of-date.
110       if (username.empty()) {
111         if (status_label) {
112           status_label->assign(
113               l10n_util::GetStringUTF16(IDS_SYNC_INVALID_USER_CREDENTIALS));
114         }
115       } else {
116         if (status_label) {
117           status_label->assign(
118               l10n_util::GetStringUTF16(IDS_SYNC_LOGIN_INFO_OUT_OF_DATE));
119         }
120       }
121       break;
122     case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
123       if (status_label) {
124         status_label->assign(
125             l10n_util::GetStringUTF16(IDS_SYNC_SERVICE_UNAVAILABLE));
126       }
127       if (link_label)
128         link_label->clear();
129       break;
130     case GoogleServiceAuthError::CONNECTION_FAILED:
131       if (status_label) {
132         status_label->assign(
133             l10n_util::GetStringFUTF16(IDS_SYNC_SERVER_IS_UNREACHABLE,
134                                        product_name));
135       }
136       // Note that there is little the user can do if the server is not
137       // reachable. Since attempting to re-connect is done automatically by
138       // the Syncer, we do not show the (re)login link.
139       if (link_label)
140         link_label->clear();
141       break;
142     default:
143       if (status_label) {
144         status_label->assign(l10n_util::GetStringUTF16(
145             IDS_SYNC_ERROR_SIGNING_IN));
146       }
147       break;
148   }
149 }
150 
151 }  // namespace signin_ui_util
152