172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sync_ui_util.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/command_line.h"
8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/i18n/number_formatting.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/i18n/time_formatting.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/string_util.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h"
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/profile_sync_service.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/browser.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_window.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/ui/options/options_window.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/chrome_switches.h"
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/net/gaia/google_service_auth_error.h"
1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/common/url_constants.h"
203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "grit/browser_resources.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochtypedef GoogleServiceAuthError AuthError;
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace sync_ui_util {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Given an authentication state, this helper function returns the appropriate
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// status message and, if necessary, the text that should appear in the
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// re-login link.
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid GetStatusLabelsForAuthError(const AuthError& auth_error,
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProfileSyncService* service, string16* status_label,
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    string16* link_label) {
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (link_label)
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    link_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_RELOGIN_LINK_LABEL));
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (auth_error.state() == AuthError::INVALID_GAIA_CREDENTIALS ||
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      auth_error.state() == AuthError::ACCOUNT_DELETED ||
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      auth_error.state() == AuthError::ACCOUNT_DISABLED) {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the user name is empty then the first login failed, otherwise the
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // credentials are out-of-date.
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (service->GetAuthenticatedUsername().empty())
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      status_label->assign(
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          l10n_util::GetStringUTF16(IDS_SYNC_INVALID_USER_CREDENTIALS));
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    else
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      status_label->assign(
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          l10n_util::GetStringUTF16(IDS_SYNC_LOGIN_INFO_OUT_OF_DATE));
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else if (auth_error.state() == AuthError::SERVICE_UNAVAILABLE) {
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(service->GetAuthenticatedUsername().empty());
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    status_label->assign(
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        l10n_util::GetStringUTF16(IDS_SYNC_SERVICE_UNAVAILABLE));
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else if (auth_error.state() == AuthError::CONNECTION_FAILED) {
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Note that there is little the user can do if the server is not
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // reachable. Since attempting to re-connect is done automatically by
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the Syncer, we do not show the (re)login link.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    status_label->assign(
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        l10n_util::GetStringFUTF16(IDS_SYNC_SERVER_IS_UNREACHABLE,
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                              l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (link_label)
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      link_label->clear();
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    status_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_ERROR_SIGNING_IN));
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Returns the message that should be displayed when the user is authenticated
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// and can connect to the sync server. If the user hasn't yet authenticated, an
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// empty string is returned.
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 GetSyncedStateStatusLabel(ProfileSyncService* service) {
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 label;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 user_name(service->GetAuthenticatedUsername());
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (user_name.empty())
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return label;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return l10n_util::GetStringFUTF16(
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browser_command_line.HasSwitch(switches::kMultiProfiles) ?
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          IDS_PROFILES_SYNCED_TO_USER_WITH_TIME :
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          IDS_SYNC_ACCOUNT_SYNCED_TO_USER_WITH_TIME,
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      user_name,
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      service->GetLastSyncedTimeString());
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TODO(akalin): Write unit tests for these three functions below.
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// status_label and link_label must either be both NULL or both non-NULL.
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMessageType GetStatusInfo(ProfileSyncService* service,
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          string16* status_label,
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          string16* link_label) {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK_EQ(status_label == NULL, link_label == NULL);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageType result_type(SYNCED);
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!service) {
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return PRE_SYNCED;
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (service->HasSyncSetupCompleted()) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ProfileSyncService::Status status(service->QueryDetailedSyncStatus());
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const AuthError& auth_error = service->GetAuthError();
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Either show auth error information with a link to re-login, auth in prog,
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // or note that everything is OK with the last synced time.
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (status.authenticated && !service->observed_passphrase_required()) {
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Everything is peachy.
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (status_label) {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        status_label->assign(GetSyncedStateStatusLabel(service));
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DCHECK_EQ(auth_error.state(), AuthError::NONE);
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (service->UIShouldDepictAuthInProgress()) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (status_label) {
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        status_label->assign(
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          l10n_util::GetStringUTF16(IDS_SYNC_AUTHENTICATING_LABEL));
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result_type = PRE_SYNCED;
1193f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    } else if (service->observed_passphrase_required()) {
1203f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      if (service->passphrase_required_for_decryption()) {
1213f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        // NOT first machine.
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // Show a link ("needs attention"), but still indicate the
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // current synced status.  Return SYNC_PROMO so that
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // the configure link will still be shown.
1253f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        if (status_label && link_label) {
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          status_label->assign(GetSyncedStateStatusLabel(service));
1273f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen          link_label->assign(
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen              l10n_util::GetStringUTF16(IDS_SYNC_PASSWORD_SYNC_ATTENTION));
1293f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        }
1303f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        result_type = SYNC_PROMO;
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      } else {
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // First machine.  Don't show promotion, just show everything
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        // normal.
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        if (status_label)
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          status_label->assign(GetSyncedStateStatusLabel(service));
1363f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      }
1373f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    } else if (auth_error.state() != AuthError::NONE) {
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (status_label && link_label) {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        GetStatusLabelsForAuthError(auth_error, service,
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    status_label, link_label);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result_type = SYNC_ERROR;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Either show auth error information with a link to re-login, auth in prog,
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // or provide a link to continue with setup.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result_type = PRE_SYNCED;
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (service->SetupInProgress()) {
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ProfileSyncService::Status status(service->QueryDetailedSyncStatus());
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const AuthError& auth_error = service->GetAuthError();
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (status_label) {
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        status_label->assign(
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            l10n_util::GetStringUTF16(IDS_SYNC_NTP_SETUP_IN_PROGRESS));
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (service->UIShouldDepictAuthInProgress()) {
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (status_label) {
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          status_label->assign(
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              l10n_util::GetStringUTF16(IDS_SYNC_AUTHENTICATING_LABEL));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (auth_error.state() != AuthError::NONE) {
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (status_label) {
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          status_label->clear();
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetStatusLabelsForAuthError(auth_error, service, status_label, NULL);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        result_type = SYNC_ERROR;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else if (!status.authenticated) {
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (status_label) {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          status_label->assign(
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              l10n_util::GetStringUTF16(IDS_SYNC_ACCOUNT_DETAILS_NOT_ENTERED));
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        }
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (service->unrecoverable_error_detected()) {
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      result_type = SYNC_ERROR;
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (status_label) {
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        status_label->assign(l10n_util::GetStringUTF16(IDS_SYNC_SETUP_ERROR));
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result_type;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Returns the status info for use on the new tab page, where we want slightly
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// different information than in the settings panel.
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMessageType GetStatusInfoForNewTabPage(ProfileSyncService* service,
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       string16* status_label,
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       string16* link_label) {
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(status_label);
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(link_label);
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (service->HasSyncSetupCompleted() &&
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service->observed_passphrase_required()) {
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (!service->passphrase_required_for_decryption()) {
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // First machine migrating to passwords.  Show as a promotion.
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (status_label && link_label) {
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        status_label->assign(
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            l10n_util::GetStringFUTF16(
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                IDS_SYNC_NTP_PASSWORD_PROMO,
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)));
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        link_label->assign(
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            l10n_util::GetStringUTF16(IDS_SYNC_NTP_PASSWORD_ENABLE));
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return SYNC_PROMO;
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    } else {
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // NOT first machine.
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // Show a link and present as an error ("needs attention").
20672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      if (status_label && link_label) {
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        status_label->assign(string16());
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        link_label->assign(
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen            l10n_util::GetStringUTF16(IDS_SYNC_CONFIGURE_ENCRYPTION));
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      }
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return SYNC_ERROR;
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Fallback to default.
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return GetStatusInfo(service, status_label, link_label);
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMessageType GetStatusLabels(ProfileSyncService* service,
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            string16* status_label,
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            string16* link_label) {
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(status_label);
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(link_label);
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return sync_ui_util::GetStatusInfo(service, status_label, link_label);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenMessageType GetStatusLabelsForNewTabPage(ProfileSyncService* service,
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         string16* status_label,
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                         string16* link_label) {
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(status_label);
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(link_label);
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return sync_ui_util::GetStatusInfoForNewTabPage(
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service, status_label, link_label);
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochMessageType GetStatus(ProfileSyncService* service) {
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return sync_ui_util::GetStatusInfo(service, NULL, NULL);
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ShouldShowSyncErrorButton(ProfileSyncService* service) {
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return service &&
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         ((!service->IsManaged() &&
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           service->HasSyncSetupCompleted()) &&
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         (GetStatus(service) == sync_ui_util::SYNC_ERROR ||
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          service->observed_passphrase_required()));
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstring16 GetSyncMenuLabel(ProfileSyncService* service) {
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageType type = GetStatus(service);
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == sync_ui_util::SYNCED)
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return l10n_util::GetStringUTF16(IDS_SYNC_MENU_SYNCED_LABEL);
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (type == sync_ui_util::SYNC_ERROR)
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return l10n_util::GetStringUTF16(IDS_SYNC_MENU_SYNC_ERROR_LABEL);
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return l10n_util::GetStringUTF16(IDS_SYNC_START_SYNC_BUTTON_LABEL);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid OpenSyncMyBookmarksDialog(Profile* profile,
26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               Browser* browser,
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                               ProfileSyncService::SyncEventCodes code) {
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileSyncService* service =
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    profile->GetOriginalProfile()->GetProfileSyncService();
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!service || !service->IsSyncEnabled()) {
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    LOG(DFATAL) << "OpenSyncMyBookmarksDialog called with sync disabled";
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (service->HasSyncSetupCompleted()) {
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool create_window = browser == NULL;
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (create_window)
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browser = Browser::Create(profile);
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    browser->ShowOptionsTab(chrome::kPersonalOptionsSubPage);
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (create_window)
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      browser->window()->Show();
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    service->ShowLoginDialog(NULL);
2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ProfileSyncService::SyncEvent(code);  // UMA stats
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AddBoolSyncDetail(ListValue* details,
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       const std::string& stat_name,
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       bool stat_value) {
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DictionaryValue* val = new DictionaryValue;
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  val->SetString("stat_name", stat_name);
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  val->SetBoolean("stat_value", stat_value);
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  details->Append(val);
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AddIntSyncDetail(ListValue* details, const std::string& stat_name,
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                      int64 stat_value) {
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DictionaryValue* val = new DictionaryValue;
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  val->SetString("stat_name", stat_name);
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  val->SetString("stat_value", base::FormatNumber(stat_value));
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  details->Append(val);
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
30121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstring16 ConstructTime(int64 time_in_int) {
30221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  base::Time time = base::Time::FromInternalValue(time_in_int);
30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
30421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // If time is null the format function returns a time in 1969.
30521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  if (time.is_null())
30621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return string16();
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base::TimeFormatFriendlyDateAndTime(time);
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickstd::string MakeSyncAuthErrorText(
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const GoogleServiceAuthError::State& state) {
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  switch (state) {
313731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS:
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case GoogleServiceAuthError::ACCOUNT_DELETED:
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case GoogleServiceAuthError::ACCOUNT_DISABLED:
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return "INVALID_GAIA_CREDENTIALS";
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case GoogleServiceAuthError::USER_NOT_SIGNED_UP:
319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return "USER_NOT_SIGNED_UP";
320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case GoogleServiceAuthError::CONNECTION_FAILED:
321731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return "CONNECTION_FAILED";
322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    default:
323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return std::string();
324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
325731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
326731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid ConstructAboutInformation(ProfileSyncService* service,
328731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                               DictionaryValue* strings) {
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  CHECK(strings);
33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!service || !service->HasSyncSetupCompleted()) {
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->SetString("summary", "SYNC DISABLED");
332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_api::SyncManager::Status full_status(
334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        service->QueryDetailedSyncStatus());
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->SetString("service_url", service->sync_service_url().spec());
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->SetString("summary",
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       ProfileSyncService::BuildSyncStatusSummaryText(
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       full_status.summary));
340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->Set("authenticated",
342731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                 new FundamentalValue(full_status.authenticated));
343731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->SetString("auth_problem",
344731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       sync_ui_util::MakeSyncAuthErrorText(
345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       service->GetAuthError().state()));
346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
347731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->SetString("time_since_sync", service->GetLastSyncedTimeString());
348731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
349731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    ListValue* details = new ListValue();
350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    strings->Set("details", details);
351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Server Up",
353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.server_up);
354731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
355731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Server Reachable",
356731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.server_reachable);
357731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
358731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Server Broken",
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.server_broken);
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Notifications Enabled",
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.notifications_enabled);
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   "Notifications Received",
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.notifications_received);
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   "Notifications Sent",
368731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.notifications_sent);
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   "Unsynced Count",
371731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.unsynced_count);
372731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
373731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   "Conflicting Count",
374731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.conflicting_count);
375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details, "Syncing", full_status.syncing);
376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
377731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Initial Sync Ended",
378731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.initial_sync_ended);
379731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
380731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Syncer Stuck",
381731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.syncer_stuck);
382731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
383731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   "Updates Available",
384731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.updates_available);
385731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
38672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                   "Updates Downloaded (All)",
387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.updates_received);
38872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sync_ui_util::AddIntSyncDetail(details,
38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                   "Updates Downloaded (Tombstones)",
39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                   full_status.tombstone_updates_received);
391731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddBoolSyncDetail(details,
392731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    "Disk Full",
393731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    full_status.disk_full);
394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    sync_ui_util::AddIntSyncDetail(details,
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   "Max Consecutive Errors",
396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                   full_status.max_consecutive_errors);
397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
398731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (service->unrecoverable_error_detected()) {
399731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      strings->Set("unrecoverable_error_detected", new FundamentalValue(true));
400731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      strings->SetString("unrecoverable_error_message",
401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         service->unrecoverable_error_message());
402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      tracked_objects::Location loc(service->unrecoverable_error_location());
403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      std::string location_str;
404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      loc.Write(true, true, &location_str);
405731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      strings->SetString("unrecoverable_error_location", location_str);
4063f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen    } else if (!service->sync_initialized()) {
4073f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      strings->SetString("summary", "Sync not yet initialized");
408731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    } else {
409731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      browser_sync::ModelSafeRoutingInfo routes;
41072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      service->GetModelSafeRoutingInfo(&routes);
411731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ListValue* routing_info = new ListValue();
412731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      strings->Set("routing_info", routing_info);
413731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      browser_sync::ModelSafeRoutingInfo::const_iterator it = routes.begin();
414731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      for (; it != routes.end(); ++it) {
415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        DictionaryValue* val = new DictionaryValue;
416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        val->SetString("model_type", ModelTypeToString(it->first));
417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        val->SetString("group", ModelSafeGroupToString(it->second));
418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        routing_info->Append(val);
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sync_ui_util::AddBoolSyncDetail(details,
42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          "Autofill Migrated",
42372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          service->GetAutofillMigrationState() ==
42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          syncable::MIGRATED);
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      syncable::AutofillMigrationDebugInfo info =
42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen          service->GetAutofillMigrationDebugInfo();
42721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sync_ui_util::AddIntSyncDetail(details,
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                     "Bookmarks created during migration",
43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                     info.bookmarks_added_during_migration);
43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sync_ui_util::AddIntSyncDetail(details,
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          "Autofill entries created during migration",
43321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          info.autofill_entries_added_during_migration);
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      sync_ui_util::AddIntSyncDetail(details,
43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          "Autofill Profiles created during migration",
43621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen          info.autofill_profile_added_during_migration);
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      DictionaryValue* val = new DictionaryValue;
43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      val->SetString("stat_name", "Autofill Migration Time");
44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      val->SetString("stat_value", ConstructTime(info.autofill_migration_time));
44121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      details->Append(val);
442731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
443731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
444731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
445731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace sync_ui_util
447