Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / sync / sync_ui_util.cc
blobd84eab8ee43177c984912def809ee9e15913c659
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/sync/sync_ui_util.h"
7 #include "base/i18n/number_formatting.h"
8 #include "base/i18n/time_formatting.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/profiles/profile_manager.h"
14 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
15 #include "chrome/browser/signin/signin_ui_util.h"
16 #include "chrome/browser/sync/profile_sync_service.h"
17 #include "chrome/browser/sync/profile_sync_service_factory.h"
18 #include "chrome/browser/ui/browser.h"
19 #include "chrome/browser/ui/browser_window.h"
20 #include "chrome/browser/ui/webui/signin/login_ui_service.h"
21 #include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "chrome/common/pref_names.h"
24 #include "chrome/common/url_constants.h"
25 #include "components/signin/core/browser/profile_oauth2_token_service.h"
26 #include "components/signin/core/browser/signin_error_controller.h"
27 #include "components/signin/core/browser/signin_manager_base.h"
28 #include "google_apis/gaia/google_service_auth_error.h"
29 #include "grit/browser_resources.h"
30 #include "grit/chromium_strings.h"
31 #include "grit/generated_resources.h"
32 #include "grit/locale_settings.h"
33 #include "sync/internal_api/public/base/model_type.h"
34 #include "sync/internal_api/public/sessions/sync_session_snapshot.h"
35 #include "sync/protocol/proto_enum_conversions.h"
36 #include "sync/protocol/sync_protocol_error.h"
37 #include "ui/base/l10n/l10n_util.h"
38 #include "ui/base/resource/resource_bundle.h"
40 #if defined(OS_CHROMEOS)
41 #include "chrome/browser/chromeos/login/user_manager.h"
42 #endif // defined(OS_CHROMEOS)
44 typedef GoogleServiceAuthError AuthError;
46 namespace sync_ui_util {
48 namespace {
50 // Returns the message that should be displayed when the user is authenticated
51 // and can connect to the sync server. If the user hasn't yet authenticated, an
52 // empty string is returned.
53 base::string16 GetSyncedStateStatusLabel(ProfileSyncService* service,
54 const SigninManagerBase& signin,
55 StatusLabelStyle style) {
56 std::string user_display_name = signin.GetAuthenticatedUsername();
58 #if defined(OS_CHROMEOS)
59 if (chromeos::UserManager::IsInitialized()) {
60 // On CrOS user email is sanitized and then passed to the signin manager.
61 // Original email (containing dots) is stored as "display email".
62 user_display_name = chromeos::UserManager::Get()->
63 GetUserDisplayEmail(user_display_name);
65 #endif // defined(OS_CHROMEOS)
67 base::string16 user_name = base::UTF8ToUTF16(user_display_name);
69 if (!user_name.empty()) {
70 if (!service || service->IsManaged()) {
71 // User is signed in, but sync is disabled.
72 return l10n_util::GetStringFUTF16(IDS_SIGNED_IN_WITH_SYNC_DISABLED,
73 user_name);
74 } else if (service->IsStartSuppressed()) {
75 // User is signed in, but sync has been stopped.
76 return l10n_util::GetStringFUTF16(IDS_SIGNED_IN_WITH_SYNC_SUPPRESSED,
77 user_name);
81 if (!service || !service->sync_initialized()) {
82 // User is not signed in, or sync is still initializing.
83 return base::string16();
86 DCHECK(!user_name.empty());
88 // Message may also carry additional advice with an HTML link, if acceptable.
89 switch (style) {
90 case PLAIN_TEXT:
91 return l10n_util::GetStringFUTF16(
92 IDS_SYNC_ACCOUNT_SYNCING_TO_USER,
93 user_name);
94 case WITH_HTML:
95 return l10n_util::GetStringFUTF16(
96 IDS_SYNC_ACCOUNT_SYNCING_TO_USER_WITH_MANAGE_LINK,
97 user_name,
98 base::ASCIIToUTF16(chrome::kSyncGoogleDashboardURL));
99 default:
100 NOTREACHED();
101 return NULL;
105 void GetStatusForActionableError(
106 const syncer::SyncProtocolError& error,
107 base::string16* status_label) {
108 DCHECK(status_label);
109 switch (error.action) {
110 case syncer::STOP_AND_RESTART_SYNC:
111 status_label->assign(
112 l10n_util::GetStringUTF16(IDS_SYNC_STOP_AND_RESTART_SYNC));
113 break;
114 case syncer::UPGRADE_CLIENT:
115 status_label->assign(
116 l10n_util::GetStringFUTF16(IDS_SYNC_UPGRADE_CLIENT,
117 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
118 break;
119 case syncer::ENABLE_SYNC_ON_ACCOUNT:
120 status_label->assign(
121 l10n_util::GetStringUTF16(IDS_SYNC_ENABLE_SYNC_ON_ACCOUNT));
122 break;
123 case syncer::CLEAR_USER_DATA_AND_RESYNC:
124 status_label->assign(
125 l10n_util::GetStringUTF16(IDS_SYNC_CLEAR_USER_DATA));
126 break;
127 default:
128 NOTREACHED();
132 // TODO(akalin): Write unit tests for these three functions below.
134 // status_label and link_label must either be both NULL or both non-NULL.
135 MessageType GetStatusInfo(ProfileSyncService* service,
136 const SigninManagerBase& signin,
137 StatusLabelStyle style,
138 base::string16* status_label,
139 base::string16* link_label) {
140 DCHECK_EQ(status_label == NULL, link_label == NULL);
142 MessageType result_type(SYNCED);
144 if (signin.GetAuthenticatedUsername().empty())
145 return PRE_SYNCED;
147 if (!service || service->IsManaged() || service->HasSyncSetupCompleted() ||
148 service->IsStartSuppressed()) {
149 // The order or priority is going to be: 1. Unrecoverable errors.
150 // 2. Auth errors. 3. Protocol errors. 4. Passphrase errors.
152 if (service && service->HasUnrecoverableError()) {
153 if (status_label) {
154 status_label->assign(l10n_util::GetStringFUTF16(
155 IDS_SYNC_STATUS_UNRECOVERABLE_ERROR,
156 l10n_util::GetStringUTF16(IDS_SYNC_UNRECOVERABLE_ERROR_HELP_URL)));
158 return SYNC_ERROR;
161 // For auth errors first check if an auth is in progress.
162 if (signin.AuthInProgress()) {
163 if (status_label) {
164 status_label->assign(
165 l10n_util::GetStringUTF16(IDS_SYNC_AUTHENTICATING_LABEL));
167 return PRE_SYNCED;
170 // Check for sync errors if the sync service is enabled.
171 if (service) {
172 // Since there is no auth in progress, check for an auth error first.
173 AuthError auth_error =
174 ProfileOAuth2TokenServiceFactory::GetForProfile(service->profile())->
175 signin_error_controller()->auth_error();
176 if (auth_error.state() != AuthError::NONE) {
177 if (status_label && link_label)
178 signin_ui_util::GetStatusLabelsForAuthError(
179 service->profile(), signin, status_label, link_label);
180 return SYNC_ERROR;
183 // We don't have an auth error. Check for an actionable error.
184 ProfileSyncService::Status status;
185 service->QueryDetailedSyncStatus(&status);
186 if (ShouldShowActionOnUI(status.sync_protocol_error)) {
187 if (status_label) {
188 GetStatusForActionableError(status.sync_protocol_error,
189 status_label);
191 return SYNC_ERROR;
194 // Check for a passphrase error.
195 if (service->IsPassphraseRequired()) {
196 if (service->IsPassphraseRequiredForDecryption()) {
197 // TODO(lipalani) : Ask tim if this is still needed.
198 // NOT first machine.
199 // Show a link ("needs attention"), but still indicate the
200 // current synced status. Return SYNC_PROMO so that
201 // the configure link will still be shown.
202 if (status_label && link_label) {
203 status_label->assign(GetSyncedStateStatusLabel(
204 service, signin, style));
205 link_label->assign(
206 l10n_util::GetStringUTF16(IDS_SYNC_PASSWORD_SYNC_ATTENTION));
208 return SYNC_PROMO;
212 // Check to see if sync has been disabled via the dasboard and needs to be
213 // set up once again.
214 if (service->IsStartSuppressed() &&
215 status.sync_protocol_error.error_type == syncer::NOT_MY_BIRTHDAY) {
216 if (status_label) {
217 status_label->assign(GetSyncedStateStatusLabel(service,
218 signin,
219 style));
221 return PRE_SYNCED;
225 // There is no error. Display "Last synced..." message.
226 if (status_label)
227 status_label->assign(GetSyncedStateStatusLabel(service, signin, style));
228 return SYNCED;
229 } else {
230 // Either show auth error information with a link to re-login, auth in prog,
231 // or provide a link to continue with setup.
232 if (service->FirstSetupInProgress()) {
233 result_type = PRE_SYNCED;
234 ProfileSyncService::Status status;
235 service->QueryDetailedSyncStatus(&status);
236 AuthError auth_error =
237 ProfileOAuth2TokenServiceFactory::GetForProfile(service->profile())->
238 signin_error_controller()->auth_error();
239 if (status_label) {
240 status_label->assign(
241 l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS));
243 if (signin.AuthInProgress()) {
244 if (status_label) {
245 status_label->assign(
246 l10n_util::GetStringUTF16(IDS_SYNC_AUTHENTICATING_LABEL));
248 } else if (auth_error.state() != AuthError::NONE &&
249 auth_error.state() != AuthError::TWO_FACTOR) {
250 if (status_label && link_label) {
251 status_label->clear();
252 signin_ui_util::GetStatusLabelsForAuthError(
253 service->profile(), signin, status_label, link_label);
255 result_type = SYNC_ERROR;
257 } else if (service->HasUnrecoverableError()) {
258 result_type = SYNC_ERROR;
259 ProfileSyncService::Status status;
260 service->QueryDetailedSyncStatus(&status);
261 if (ShouldShowActionOnUI(status.sync_protocol_error)) {
262 if (status_label) {
263 GetStatusForActionableError(status.sync_protocol_error,
264 status_label);
266 } else if (status_label) {
267 status_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_SETUP_ERROR));
269 } else if (!signin.GetAuthenticatedUsername().empty()) {
270 // The user is signed in, but sync has been stopped.
271 if (status_label) {
272 base::string16 label = l10n_util::GetStringFUTF16(
273 IDS_SIGNED_IN_WITH_SYNC_SUPPRESSED,
274 base::UTF8ToUTF16(signin.GetAuthenticatedUsername()));
275 status_label->assign(label);
276 result_type = PRE_SYNCED;
280 return result_type;
283 // Returns the status info for use on the new tab page, where we want slightly
284 // different information than in the settings panel.
285 MessageType GetStatusInfoForNewTabPage(ProfileSyncService* service,
286 const SigninManagerBase& signin,
287 base::string16* status_label,
288 base::string16* link_label) {
289 DCHECK(status_label);
290 DCHECK(link_label);
292 if (service->HasSyncSetupCompleted() &&
293 service->IsPassphraseRequired()) {
294 if (service->passphrase_required_reason() == syncer::REASON_ENCRYPTION) {
295 // First machine migrating to passwords. Show as a promotion.
296 if (status_label && link_label) {
297 status_label->assign(
298 l10n_util::GetStringFUTF16(
299 IDS_SYNC_NTP_PASSWORD_PROMO,
300 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
301 link_label->assign(
302 l10n_util::GetStringUTF16(IDS_SYNC_NTP_PASSWORD_ENABLE));
304 return SYNC_PROMO;
305 } else {
306 // NOT first machine.
307 // Show a link and present as an error ("needs attention").
308 if (status_label && link_label) {
309 status_label->assign(base::string16());
310 link_label->assign(
311 l10n_util::GetStringUTF16(IDS_SYNC_CONFIGURE_ENCRYPTION));
313 return SYNC_ERROR;
317 // Fallback to default.
318 return GetStatusInfo(service, signin, WITH_HTML, status_label, link_label);
321 } // namespace
323 MessageType GetStatusLabels(ProfileSyncService* service,
324 const SigninManagerBase& signin,
325 StatusLabelStyle style,
326 base::string16* status_label,
327 base::string16* link_label) {
328 DCHECK(status_label);
329 DCHECK(link_label);
330 return sync_ui_util::GetStatusInfo(
331 service, signin, style, status_label, link_label);
334 MessageType GetStatusLabelsForNewTabPage(ProfileSyncService* service,
335 const SigninManagerBase& signin,
336 base::string16* status_label,
337 base::string16* link_label) {
338 DCHECK(status_label);
339 DCHECK(link_label);
340 return sync_ui_util::GetStatusInfoForNewTabPage(
341 service, signin, status_label, link_label);
344 #if !defined(OS_CHROMEOS)
345 void GetStatusLabelsForSyncGlobalError(const ProfileSyncService* service,
346 base::string16* menu_label,
347 base::string16* bubble_message,
348 base::string16* bubble_accept_label) {
349 DCHECK(menu_label);
350 DCHECK(bubble_message);
351 DCHECK(bubble_accept_label);
352 *menu_label = base::string16();
353 *bubble_message = base::string16();
354 *bubble_accept_label = base::string16();
356 // Only display an error if we've completed sync setup.
357 if (!service->HasSyncSetupCompleted())
358 return;
360 // Display a passphrase error if we have one.
361 if (service->IsPassphraseRequired() &&
362 service->IsPassphraseRequiredForDecryption()) {
363 // This is not the first machine so ask user to enter passphrase.
364 *menu_label = l10n_util::GetStringUTF16(
365 IDS_SYNC_PASSPHRASE_ERROR_WRENCH_MENU_ITEM);
366 *bubble_message = l10n_util::GetStringUTF16(
367 IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE);
368 *bubble_accept_label = l10n_util::GetStringUTF16(
369 IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_ACCEPT);
370 return;
373 #endif
375 MessageType GetStatus(
376 ProfileSyncService* service, const SigninManagerBase& signin) {
377 return sync_ui_util::GetStatusInfo(service, signin, WITH_HTML, NULL, NULL);
380 base::string16 ConstructTime(int64 time_in_int) {
381 base::Time time = base::Time::FromInternalValue(time_in_int);
383 // If time is null the format function returns a time in 1969.
384 if (time.is_null())
385 return base::string16();
386 return base::TimeFormatFriendlyDateAndTime(time);
389 } // namespace sync_ui_util