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.
4
5#include "chrome/browser/sync/sync_global_error.h"
6
7#include "chrome/app/chrome_command_ids.h"
8#include "chrome/browser/sync/profile_sync_service.h"
9#include "chrome/browser/sync/sync_ui_util.h"
10#include "chrome/browser/ui/browser.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 "chrome/grit/generated_resources.h"
19#include "google_apis/gaia/google_service_auth_error.h"
20#include "ui/base/l10n/l10n_util.h"
21
22SyncGlobalError::SyncGlobalError(SyncErrorController* error_controller,
23                                 ProfileSyncService* profile_sync_service)
24    : error_controller_(error_controller),
25      service_(profile_sync_service) {
26  DCHECK(service_);
27  error_controller_->AddObserver(this);
28  GlobalErrorServiceFactory::GetForProfile(service_->profile())->
29      AddGlobalError(this);
30}
31
32SyncGlobalError::~SyncGlobalError() {
33  DCHECK(!error_controller_)
34      << "SyncGlobalError::Shutdown() was not called";
35}
36
37void SyncGlobalError::Shutdown() {
38  GlobalErrorServiceFactory::GetForProfile(service_->profile())->
39      RemoveGlobalError(this);
40  error_controller_->RemoveObserver(this);
41  error_controller_ = NULL;
42}
43
44bool SyncGlobalError::HasMenuItem() {
45  return !menu_label_.empty();
46}
47
48int SyncGlobalError::MenuItemCommandID() {
49  return IDC_SHOW_SYNC_ERROR;
50}
51
52base::string16 SyncGlobalError::MenuItemLabel() {
53  return menu_label_;
54}
55
56void SyncGlobalError::ExecuteMenuItem(Browser* browser) {
57  LoginUIService* login_ui = LoginUIServiceFactory::GetForProfile(
58      service_->profile());
59  if (login_ui->current_login_ui()) {
60    login_ui->current_login_ui()->FocusUI();
61    return;
62  }
63  // Need to navigate to the settings page and display the UI.
64  chrome::ShowSettingsSubPage(browser, chrome::kSyncSetupSubPage);
65}
66
67bool SyncGlobalError::HasBubbleView() {
68  return !bubble_message_.empty() && !bubble_accept_label_.empty();
69}
70
71base::string16 SyncGlobalError::GetBubbleViewTitle() {
72  return l10n_util::GetStringUTF16(IDS_SYNC_ERROR_BUBBLE_VIEW_TITLE);
73}
74
75std::vector<base::string16> SyncGlobalError::GetBubbleViewMessages() {
76  return std::vector<base::string16>(1, bubble_message_);
77}
78
79base::string16 SyncGlobalError::GetBubbleViewAcceptButtonLabel() {
80  return bubble_accept_label_;
81}
82
83base::string16 SyncGlobalError::GetBubbleViewCancelButtonLabel() {
84  return base::string16();
85}
86
87void SyncGlobalError::OnBubbleViewDidClose(Browser* browser) {
88}
89
90void SyncGlobalError::BubbleViewAcceptButtonPressed(Browser* browser) {
91  ExecuteMenuItem(browser);
92}
93
94void SyncGlobalError::BubbleViewCancelButtonPressed(Browser* browser) {
95  NOTREACHED();
96}
97
98void SyncGlobalError::OnErrorChanged() {
99  base::string16 menu_label;
100  base::string16 bubble_message;
101  base::string16 bubble_accept_label;
102  sync_ui_util::GetStatusLabelsForSyncGlobalError(
103      service_, &menu_label, &bubble_message, &bubble_accept_label);
104
105  // All the labels should be empty or all of them non-empty.
106  DCHECK((menu_label.empty() && bubble_message.empty() &&
107          bubble_accept_label.empty()) ||
108         (!menu_label.empty() && !bubble_message.empty() &&
109          !bubble_accept_label.empty()));
110
111  if (menu_label != menu_label_ || bubble_message != bubble_message_ ||
112      bubble_accept_label != bubble_accept_label_) {
113    menu_label_ = menu_label;
114    bubble_message_ = bubble_message;
115    bubble_accept_label_ = bubble_accept_label;
116
117    // Profile can be NULL during tests.
118    Profile* profile = service_->profile();
119    if (profile) {
120      GlobalErrorServiceFactory::GetForProfile(
121          profile)->NotifyErrorsChanged(this);
122    }
123  }
124}
125