Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / ash / accelerators / exit_warning_handler.cc
1 // Copyright 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 "ash/accelerators/exit_warning_handler.h"
6
7 #include "ash/metrics/user_metrics_recorder.h"
8 #include "ash/shell.h"
9 #include "ash/shell_delegate.h"
10 #include "ash/shell_window_ids.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/time/time.h"
13 #include "base/timer/timer.h"
14 #include "grit/ash_strings.h"
15 #include "ui/accessibility/ax_view_state.h"
16 #include "ui/aura/window.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/font_list.h"
21 #include "ui/gfx/text_utils.h"
22 #include "ui/views/controls/label.h"
23 #include "ui/views/layout/fill_layout.h"
24 #include "ui/views/view.h"
25 #include "ui/views/widget/widget.h"
26 #include "ui/views/widget/widget_delegate.h"
27
28 namespace ash {
29 namespace {
30
31 const int64 kTimeOutMilliseconds = 2000;
32 // Color of the text of the warning message.
33 const SkColor kTextColor = SK_ColorWHITE;
34 // Color of the window background.
35 const SkColor kWindowBackgroundColor = SkColorSetARGB(0xC0, 0x0, 0x0, 0x0);
36 // Radius of the rounded corners of the window.
37 const int kWindowCornerRadius = 2;
38 const int kHorizontalMarginAroundText = 100;
39 const int kVerticalMarginAroundText = 100;
40
41 class ExitWarningLabel : public views::Label {
42  public:
43   ExitWarningLabel() {}
44
45   virtual ~ExitWarningLabel() {}
46
47  private:
48   virtual void PaintText(gfx::Canvas* canvas,
49                          const base::string16& text,
50                          const gfx::Rect& text_bounds,
51                          int flags) OVERRIDE {
52     // Turn off subpixel rendering.
53     views::Label::PaintText(canvas,
54                             text,
55                             text_bounds,
56                             flags | gfx::Canvas::NO_SUBPIXEL_RENDERING);
57   }
58
59   DISALLOW_COPY_AND_ASSIGN(ExitWarningLabel);
60 };
61
62 class ExitWarningWidgetDelegateView : public views::WidgetDelegateView {
63  public:
64   ExitWarningWidgetDelegateView() : text_width_(0), width_(0), height_(0) {
65     text_ = l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT);
66     accessible_name_ =
67         l10n_util::GetStringUTF16(IDS_ASH_EXIT_WARNING_POPUP_TEXT_ACCESSIBLE);
68     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
69     const gfx::FontList& font_list =
70         rb.GetFontList(ui::ResourceBundle::LargeFont);
71     text_width_ = gfx::GetStringWidth(text_, font_list);
72     width_ = text_width_ + kHorizontalMarginAroundText;
73     height_ = font_list.GetHeight() + kVerticalMarginAroundText;
74     views::Label* label = new ExitWarningLabel;
75     label->SetText(text_);
76     label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
77     label->SetFontList(font_list);
78     label->SetEnabledColor(kTextColor);
79     label->SetDisabledColor(kTextColor);
80     label->SetAutoColorReadabilityEnabled(false);
81     AddChildView(label);
82     SetLayoutManager(new views::FillLayout);
83   }
84
85   virtual gfx::Size GetPreferredSize() OVERRIDE {
86     return gfx::Size(width_, height_);
87   }
88
89   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
90     SkPaint paint;
91     paint.setStyle(SkPaint::kFill_Style);
92     paint.setColor(kWindowBackgroundColor);
93     canvas->DrawRoundRect(GetLocalBounds(), kWindowCornerRadius, paint);
94     views::WidgetDelegateView::OnPaint(canvas);
95   }
96
97   virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE {
98     state->name = accessible_name_;
99     state->role = ui::AX_ROLE_ALERT;
100   }
101
102  private:
103   base::string16 text_;
104   base::string16 accessible_name_;
105   int text_width_;
106   int width_;
107   int height_;
108
109   DISALLOW_COPY_AND_ASSIGN(ExitWarningWidgetDelegateView);
110 };
111
112 }  // namespace
113
114 ExitWarningHandler::ExitWarningHandler()
115     : state_(IDLE),
116       stub_timer_for_test_(false) {
117 }
118
119 ExitWarningHandler::~ExitWarningHandler() {
120   // Note: If a timer is outstanding, it is stopped in its destructor.
121   Hide();
122 }
123
124 void ExitWarningHandler::HandleAccelerator() {
125   ShellDelegate* shell_delegate = Shell::GetInstance()->delegate();
126   switch (state_) {
127     case IDLE:
128       state_ = WAIT_FOR_DOUBLE_PRESS;
129       Show();
130       StartTimer();
131       Shell::GetInstance()->
132           metrics()->RecordUserMetricsAction(UMA_ACCEL_EXIT_FIRST_Q);
133       break;
134     case WAIT_FOR_DOUBLE_PRESS:
135       state_ = EXITING;
136       CancelTimer();
137       Hide();
138       Shell::GetInstance()->
139           metrics()->RecordUserMetricsAction(UMA_ACCEL_EXIT_SECOND_Q);
140       shell_delegate->Exit();
141       break;
142     case EXITING:
143       break;
144     default:
145       NOTREACHED();
146       break;
147   }
148 }
149
150 void ExitWarningHandler::TimerAction() {
151   Hide();
152   if (state_ == WAIT_FOR_DOUBLE_PRESS)
153     state_ = IDLE;
154 }
155
156 void ExitWarningHandler::StartTimer() {
157   if (stub_timer_for_test_)
158     return;
159   timer_.Start(FROM_HERE,
160                base::TimeDelta::FromMilliseconds(kTimeOutMilliseconds),
161                this,
162                &ExitWarningHandler::TimerAction);
163 }
164
165 void ExitWarningHandler::CancelTimer() {
166   timer_.Stop();
167 }
168
169 void ExitWarningHandler::Show() {
170   if (widget_)
171     return;
172   aura::Window* root_window = Shell::GetTargetRootWindow();
173   ExitWarningWidgetDelegateView* delegate = new ExitWarningWidgetDelegateView;
174   gfx::Size rs = root_window->bounds().size();
175   gfx::Size ps = delegate->GetPreferredSize();
176   gfx::Rect bounds((rs.width() - ps.width()) / 2,
177                    (rs.height() - ps.height()) / 3,
178                    ps.width(), ps.height());
179   views::Widget::InitParams params;
180   params.type = views::Widget::InitParams::TYPE_POPUP;
181   params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
182   params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
183   params.accept_events = false;
184   params.can_activate = false;
185   params.keep_on_top = true;
186   params.remove_standard_frame = true;
187   params.delegate = delegate;
188   params.bounds = bounds;
189   params.parent =
190       Shell::GetContainer(root_window, kShellWindowId_SettingBubbleContainer);
191   widget_.reset(new views::Widget);
192   widget_->Init(params);
193   widget_->SetContentsView(delegate);
194   widget_->GetNativeView()->SetName("ExitWarningWindow");
195   widget_->Show();
196
197   delegate->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
198 }
199
200 void ExitWarningHandler::Hide() {
201   widget_.reset();
202 }
203
204 }  // namespace ash