OLD | NEW |
| (Empty) |
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_global_error.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "chrome/app/chrome_command_ids.h" | |
9 #include "chrome/browser/signin/signin_manager.h" | |
10 #include "chrome/browser/signin/signin_manager_factory.h" | |
11 #include "chrome/browser/ui/browser_commands.h" | |
12 #include "chrome/browser/ui/chrome_pages.h" | |
13 #include "chrome/browser/ui/global_error/global_error_service.h" | |
14 #include "chrome/browser/ui/global_error/global_error_service_factory.h" | |
15 #include "chrome/browser/ui/webui/signin/login_ui_service.h" | |
16 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" | |
17 #include "chrome/common/url_constants.h" | |
18 #include "grit/chromium_strings.h" | |
19 #include "grit/generated_resources.h" | |
20 #include "ui/base/l10n/l10n_util.h" | |
21 | |
22 SigninGlobalError::SigninGlobalError(Profile* profile) | |
23 : auth_error_(GoogleServiceAuthError::None()), | |
24 profile_(profile) { | |
25 } | |
26 | |
27 SigninGlobalError::~SigninGlobalError() { | |
28 DCHECK(provider_set_.empty()) | |
29 << "All AuthStatusProviders should be unregistered before" | |
30 << " SigninManager::Shutdown() is called"; | |
31 } | |
32 | |
33 void SigninGlobalError::AddProvider(const AuthStatusProvider* provider) { | |
34 DCHECK(provider_set_.find(provider) == provider_set_.end()) | |
35 << "Adding same AuthStatusProvider multiple times"; | |
36 provider_set_.insert(provider); | |
37 AuthStatusChanged(); | |
38 } | |
39 | |
40 void SigninGlobalError::RemoveProvider(const AuthStatusProvider* provider) { | |
41 std::set<const AuthStatusProvider*>::iterator iter = | |
42 provider_set_.find(provider); | |
43 DCHECK(iter != provider_set_.end()) | |
44 << "Removing provider that was never added"; | |
45 provider_set_.erase(iter); | |
46 AuthStatusChanged(); | |
47 } | |
48 | |
49 SigninGlobalError::AuthStatusProvider::AuthStatusProvider() { | |
50 } | |
51 | |
52 SigninGlobalError::AuthStatusProvider::~AuthStatusProvider() { | |
53 } | |
54 | |
55 void SigninGlobalError::AuthStatusChanged() { | |
56 // Walk all of the status providers and collect any error. | |
57 GoogleServiceAuthError current_error(GoogleServiceAuthError::None()); | |
58 for (std::set<const AuthStatusProvider*>::const_iterator it = | |
59 provider_set_.begin(); it != provider_set_.end(); ++it) { | |
60 current_error = (*it)->GetAuthStatus(); | |
61 // Break out if any provider reports an error (ignoring ordinary network | |
62 // errors, which are not surfaced to the user). This logic may eventually | |
63 // need to be extended to prioritize different auth errors, but for now | |
64 // all auth errors are treated the same. | |
65 if (current_error.state() != GoogleServiceAuthError::NONE && | |
66 current_error.state() != GoogleServiceAuthError::CONNECTION_FAILED) { | |
67 break; | |
68 } | |
69 } | |
70 if (current_error.state() != auth_error_.state()) { | |
71 auth_error_ = current_error; | |
72 GlobalErrorServiceFactory::GetForProfile(profile_)->NotifyErrorsChanged( | |
73 this); | |
74 } | |
75 } | |
76 | |
77 bool SigninGlobalError::HasBadge() { | |
78 // Badge the wrench menu any time there is a menu item reflecting an auth | |
79 // error. | |
80 return !MenuItemLabel().empty(); | |
81 } | |
82 | |
83 bool SigninGlobalError::HasMenuItem() { | |
84 // Auth errors are only reported via a separate menu item on chromeos - on | |
85 // other platforms, WrenchMenuModel overlays the errors on top of the | |
86 // "Signed in as xxxxx" menu item. | |
87 #if defined(OS_CHROMEOS) | |
88 return HasBadge(); | |
89 #else | |
90 return false; | |
91 #endif | |
92 } | |
93 | |
94 int SigninGlobalError::MenuItemCommandID() { | |
95 return IDC_SHOW_SIGNIN_ERROR; | |
96 } | |
97 | |
98 string16 SigninGlobalError::MenuItemLabel() { | |
99 if (SigninManagerFactory::GetForProfile(profile_)-> | |
100 GetAuthenticatedUsername().empty() || | |
101 auth_error_.state() == GoogleServiceAuthError::NONE || | |
102 auth_error_.state() == GoogleServiceAuthError::CONNECTION_FAILED) { | |
103 // If the user isn't signed in, or there's no auth error worth elevating to | |
104 // the user, don't display any menu item. | |
105 return string16(); | |
106 } else { | |
107 // There's an auth error the user should know about - notify the user. | |
108 return l10n_util::GetStringUTF16(IDS_SYNC_SIGN_IN_ERROR_WRENCH_MENU_ITEM); | |
109 } | |
110 } | |
111 | |
112 void SigninGlobalError::ExecuteMenuItem(Browser* browser) { | |
113 #if defined(OS_CHROMEOS) | |
114 if (auth_error_.state() != GoogleServiceAuthError::NONE) { | |
115 DLOG(INFO) << "Signing out the user to fix a sync error."; | |
116 // TODO(beng): seems like this could just call browser::AttemptUserExit(). | |
117 chrome::ExecuteCommand(browser, IDC_EXIT); | |
118 return; | |
119 } | |
120 #endif | |
121 | |
122 // Global errors don't show up in the wrench menu on android. | |
123 #if !defined(OS_ANDROID) | |
124 LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(profile_); | |
125 if (login_ui->current_login_ui()) { | |
126 login_ui->current_login_ui()->FocusUI(); | |
127 return; | |
128 } | |
129 // Need to navigate to the settings page and display the UI. | |
130 chrome::ShowSettingsSubPage(browser, chrome::kSyncSetupSubPage); | |
131 #endif | |
132 } | |
133 | |
134 bool SigninGlobalError::HasBubbleView() { | |
135 return !GetBubbleViewMessage().empty(); | |
136 } | |
137 | |
138 string16 SigninGlobalError::GetBubbleViewTitle() { | |
139 return l10n_util::GetStringUTF16(IDS_SIGNIN_ERROR_BUBBLE_VIEW_TITLE); | |
140 } | |
141 | |
142 string16 SigninGlobalError::GetBubbleViewMessage() { | |
143 // If the user isn't signed in, no need to display an error bubble. | |
144 if (SigninManagerFactory::GetForProfile(profile_)-> | |
145 GetAuthenticatedUsername().empty()) { | |
146 return string16(); | |
147 } | |
148 | |
149 switch (auth_error_.state()) { | |
150 // In the case of no error, or a simple network error, don't bother | |
151 // displaying a popup bubble. | |
152 case GoogleServiceAuthError::CONNECTION_FAILED: | |
153 case GoogleServiceAuthError::NONE: | |
154 return string16(); | |
155 | |
156 // User credentials are invalid (bad acct, etc). | |
157 case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: | |
158 case GoogleServiceAuthError::ACCOUNT_DELETED: | |
159 case GoogleServiceAuthError::ACCOUNT_DISABLED: | |
160 return l10n_util::GetStringFUTF16( | |
161 IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE, | |
162 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | |
163 | |
164 // Sync service is not available for this account's domain. | |
165 case GoogleServiceAuthError::SERVICE_UNAVAILABLE: | |
166 return l10n_util::GetStringFUTF16( | |
167 IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_MESSAGE, | |
168 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | |
169 | |
170 // Generic message for "other" errors. | |
171 default: | |
172 return l10n_util::GetStringFUTF16( | |
173 IDS_SYNC_OTHER_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE, | |
174 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | |
175 } | |
176 } | |
177 | |
178 string16 SigninGlobalError::GetBubbleViewAcceptButtonLabel() { | |
179 // If the service is unavailable, don't give the user the option to try | |
180 // signing in again. | |
181 if (auth_error_.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE) { | |
182 return l10n_util::GetStringUTF16( | |
183 IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_ACCEPT); | |
184 } else { | |
185 return l10n_util::GetStringUTF16(IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_ACCEPT); | |
186 } | |
187 } | |
188 | |
189 string16 SigninGlobalError::GetBubbleViewCancelButtonLabel() { | |
190 return string16(); | |
191 } | |
192 | |
193 void SigninGlobalError::OnBubbleViewDidClose(Browser* browser) { | |
194 } | |
195 | |
196 void SigninGlobalError::BubbleViewAcceptButtonPressed(Browser* browser) { | |
197 ExecuteMenuItem(browser); | |
198 } | |
199 | |
200 void SigninGlobalError::BubbleViewCancelButtonPressed(Browser* browser) { | |
201 NOTREACHED(); | |
202 } | |
OLD | NEW |