1// Copyright 2014 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/ui/views/download/download_feedback_dialog_view.h"
6
7#include "base/metrics/histogram.h"
8#include "base/prefs/pref_service.h"
9#include "base/supports_user_data.h"
10#include "chrome/browser/platform_util.h"
11#include "chrome/browser/profiles/profile.h"
12#include "chrome/browser/ui/views/constrained_window_views.h"
13#include "chrome/grit/chromium_strings.h"
14#include "chrome/grit/generated_resources.h"
15#include "content/public/browser/page_navigator.h"
16#include "ui/base/l10n/l10n_util.h"
17#include "ui/views/controls/link.h"
18#include "ui/views/controls/message_box_view.h"
19#include "ui/views/widget/widget.h"
20
21using content::OpenURLParams;
22
23namespace {
24
25const void* kDialogStatusKey = &kDialogStatusKey;
26
27class DialogStatusData : public base::SupportsUserData::Data {
28 public:
29  DialogStatusData() : currently_shown_(false) {}
30  virtual ~DialogStatusData() {}
31  bool currently_shown() const { return currently_shown_; }
32  void set_currently_shown(bool shown) { currently_shown_ = shown; }
33 private:
34  bool currently_shown_;
35};
36
37}  // namespace
38
39// static
40void DownloadFeedbackDialogView::Show(
41    gfx::NativeWindow parent_window,
42    Profile* profile,
43    content::PageNavigator* navigator,
44    const UserDecisionCallback& callback) {
45  // This dialog should only be shown if it hasn't been shown before.
46  DCHECK(!profile->GetPrefs()->HasPrefPath(
47      prefs::kSafeBrowsingExtendedReportingEnabled));
48
49  // Only one dialog should be shown at a time, so check to see if another one
50  // is open. If another one is open, treat this parallel call as if reporting
51  // is disabled (to be conservative).
52  DialogStatusData* data =
53      static_cast<DialogStatusData*>(profile->GetUserData(kDialogStatusKey));
54  if (data == NULL) {
55    data = new DialogStatusData();
56    profile->SetUserData(kDialogStatusKey, data);
57  }
58  if (data->currently_shown() == false) {
59    data->set_currently_shown(true);
60    DownloadFeedbackDialogView* window =
61        new DownloadFeedbackDialogView(profile, navigator, callback);
62    CreateBrowserModalDialogViews(window, parent_window)->Show();
63  } else {
64    callback.Run(false);
65  }
66}
67
68DownloadFeedbackDialogView::DownloadFeedbackDialogView(
69    Profile* profile,
70    content::PageNavigator* navigator,
71    const UserDecisionCallback& callback)
72    : profile_(profile),
73      navigator_(navigator),
74      callback_(callback),
75      explanation_box_view_(new views::MessageBoxView(
76          views::MessageBoxView::InitParams(l10n_util::GetStringUTF16(
77              IDS_FEEDBACK_SERVICE_DIALOG_EXPLANATION)))),
78      link_view_(new views::Link(l10n_util::GetStringUTF16(
79          IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE))),
80      title_text_(l10n_util::GetStringUTF16(IDS_FEEDBACK_SERVICE_DIALOG_TITLE)),
81      ok_button_text_(l10n_util::GetStringUTF16(
82          IDS_FEEDBACK_SERVICE_DIALOG_OK_BUTTON_LABEL)),
83      cancel_button_text_(l10n_util::GetStringUTF16(
84          IDS_FEEDBACK_SERVICE_DIALOG_CANCEL_BUTTON_LABEL)) {
85  link_view_->set_listener(this);
86}
87
88DownloadFeedbackDialogView::~DownloadFeedbackDialogView() {}
89
90int DownloadFeedbackDialogView::GetDefaultDialogButton() const {
91  return ui::DIALOG_BUTTON_CANCEL;
92}
93
94base::string16 DownloadFeedbackDialogView::GetDialogButtonLabel(
95    ui::DialogButton button) const {
96  return (button == ui::DIALOG_BUTTON_OK) ?
97      ok_button_text_ : cancel_button_text_;
98}
99
100bool DownloadFeedbackDialogView::OnButtonClicked(bool accepted) {
101  profile_->GetPrefs()->SetBoolean(prefs::kSafeBrowsingExtendedReportingEnabled,
102                                   accepted);
103  DialogStatusData* data =
104     static_cast<DialogStatusData*>(profile_->GetUserData(kDialogStatusKey));
105  DCHECK(data);
106  data->set_currently_shown(false);
107
108  UMA_HISTOGRAM_BOOLEAN("Download.FeedbackDialogEnabled", accepted);
109
110  callback_.Run(accepted);
111  return true;
112}
113
114bool DownloadFeedbackDialogView::Cancel() {
115  return OnButtonClicked(false);
116}
117
118bool DownloadFeedbackDialogView::Accept() {
119  return OnButtonClicked(true);
120}
121
122ui::ModalType DownloadFeedbackDialogView::GetModalType() const {
123  return ui::MODAL_TYPE_WINDOW;
124}
125
126base::string16 DownloadFeedbackDialogView::GetWindowTitle() const {
127  return title_text_;
128}
129
130void DownloadFeedbackDialogView::DeleteDelegate() {
131  delete this;
132}
133
134views::Widget* DownloadFeedbackDialogView::GetWidget() {
135  return explanation_box_view_->GetWidget();
136}
137
138const views::Widget* DownloadFeedbackDialogView::GetWidget() const {
139  return explanation_box_view_->GetWidget();
140}
141
142views::View* DownloadFeedbackDialogView::GetContentsView() {
143  return explanation_box_view_;
144}
145
146views::View* DownloadFeedbackDialogView::CreateExtraView() {
147  return link_view_;
148}
149
150void DownloadFeedbackDialogView::LinkClicked(
151    views::Link* source, int event_flags) {
152  WindowOpenDisposition disposition =
153      ui::DispositionFromEventFlags(event_flags);
154  content::OpenURLParams params(
155      GURL(l10n_util::GetStringUTF8(IDS_SAFE_BROWSING_PRIVACY_POLICY_URL)),
156      content::Referrer(),
157      disposition == CURRENT_TAB ? NEW_FOREGROUND_TAB : disposition,
158      ui::PAGE_TRANSITION_LINK, false);
159  navigator_->OpenURL(params);
160}
161