idle_logout_dialog_view.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/chromeos/ui/idle_logout_dialog_view.h"
6
7#include "ash/shell.h"
8#include "base/bind.h"
9#include "base/bind_helpers.h"
10#include "base/strings/string_number_conversions.h"
11#include "base/time.h"
12#include "base/utf_string_conversions.h"
13#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
14#include "chrome/browser/ui/browser_list.h"
15#include "chromeos/dbus/dbus_thread_manager.h"
16#include "chromeos/dbus/session_manager_client.h"
17#include "grit/browser_resources.h"
18#include "grit/generated_resources.h"
19#include "ui/aura/root_window.h"
20#include "ui/base/l10n/l10n_util.h"
21#include "ui/base/resource/resource_bundle.h"
22#include "ui/views/controls/label.h"
23#include "ui/views/layout/grid_layout.h"
24#include "ui/views/layout/layout_constants.h"
25#include "ui/views/widget/widget.h"
26
27namespace {
28
29// Global singleton instance of our dialog class.
30chromeos::IdleLogoutDialogView* g_instance = NULL;
31
32const int kIdleLogoutDialogMaxWidth = 300;
33const int kCountdownUpdateIntervalMs = 1000;
34
35}  // namespace
36
37namespace chromeos {
38
39IdleLogoutSettingsProvider* IdleLogoutDialogView::provider_ = NULL;
40
41////////////////////////////////////////////////////////////////////////////////
42// IdleLogoutSettingsProvider public methods
43IdleLogoutSettingsProvider::IdleLogoutSettingsProvider() {
44}
45
46IdleLogoutSettingsProvider::~IdleLogoutSettingsProvider() {
47}
48
49base::TimeDelta IdleLogoutSettingsProvider::GetCountdownUpdateInterval() {
50  return base::TimeDelta::FromMilliseconds(kCountdownUpdateIntervalMs);
51}
52
53KioskModeSettings* IdleLogoutSettingsProvider::GetKioskModeSettings() {
54  return KioskModeSettings::Get();
55}
56
57void IdleLogoutSettingsProvider::LogoutCurrentUser(IdleLogoutDialogView*) {
58  DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
59}
60
61////////////////////////////////////////////////////////////////////////////////
62// IdleLogoutDialogView public static methods
63// static
64void IdleLogoutDialogView::ShowDialog() {
65  // We only show the dialog if it is not already showing. We don't want two
66  // countdowns on the screen for any reason. If the dialog is closed by using
67  // CloseDialog, we reset g_instance so the next Show will work correctly; in
68  // case the dialog is closed by the system, DeleteDelegate is guaranteed to be
69  // called, in which case we reset g_instance there if not already reset.
70  if (!g_instance) {
71    g_instance = new IdleLogoutDialogView();
72    g_instance->InitAndShow();
73  }
74}
75
76// static
77void IdleLogoutDialogView::CloseDialog() {
78  if (g_instance)
79    g_instance->Close();
80}
81
82////////////////////////////////////////////////////////////////////////////////
83// Overridden from views::DialogDelegateView
84int IdleLogoutDialogView::GetDialogButtons() const {
85  return ui::DIALOG_BUTTON_NONE;
86}
87
88ui::ModalType IdleLogoutDialogView::GetModalType() const {
89  return ui::MODAL_TYPE_WINDOW;
90}
91
92string16 IdleLogoutDialogView::GetWindowTitle() const {
93  return l10n_util::GetStringUTF16(IDS_IDLE_LOGOUT_TITLE);
94}
95
96////////////////////////////////////////////////////////////////////////////////
97// IdleLogoutDialog private methods
98IdleLogoutDialogView::IdleLogoutDialogView()
99    : restart_label_(NULL),
100      weak_ptr_factory_(this) {
101  if (!IdleLogoutDialogView::provider_)
102    IdleLogoutDialogView::provider_ = new IdleLogoutSettingsProvider();
103}
104
105IdleLogoutDialogView::~IdleLogoutDialogView() {
106  if (this == g_instance)
107    g_instance = NULL;
108}
109
110void IdleLogoutDialogView::InitAndShow() {
111  KioskModeSettings* settings =
112      IdleLogoutDialogView::provider_->GetKioskModeSettings();
113  if (!settings->is_initialized()) {
114    settings->Initialize(base::Bind(&IdleLogoutDialogView::InitAndShow,
115                                    weak_ptr_factory_.GetWeakPtr()));
116    return;
117  }
118
119  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
120
121  restart_label_ = new views::Label();
122  restart_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
123  restart_label_->SetMultiLine(true);
124  restart_label_->SetFont(rb.GetFont(ui::ResourceBundle::BaseFont));
125
126  views::GridLayout* layout = views::GridLayout::CreatePanel(this);
127  SetLayoutManager(layout);
128
129  views::ColumnSet* column_set = layout->AddColumnSet(0);
130  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1,
131                        views::GridLayout::FIXED, kIdleLogoutDialogMaxWidth, 0);
132  layout->StartRow(0, 0);
133  layout->AddPaddingRow(0, views::kRelatedControlHorizontalSpacing);
134  layout->StartRow(0, 0);
135  layout->AddView(restart_label_);
136  layout->AddPaddingRow(0, views::kRelatedControlHorizontalSpacing);
137
138  // We're initialized, show the dialog.
139  Show();
140}
141
142void IdleLogoutDialogView::Show() {
143  KioskModeSettings* settings =
144        IdleLogoutDialogView::provider_->GetKioskModeSettings();
145
146  // Setup the countdown label before showing.
147  countdown_end_time_ = base::Time::Now() +
148      settings->GetIdleLogoutWarningDuration();
149
150  UpdateCountdown();
151
152  views::Widget::CreateWindowWithContext(this,
153                                         ash::Shell::GetPrimaryRootWindow());
154  GetWidget()->SetAlwaysOnTop(true);
155  GetWidget()->Show();
156
157  // Update countdown every 1 second.
158  timer_.Start(FROM_HERE,
159               IdleLogoutDialogView::provider_->GetCountdownUpdateInterval(),
160               this,
161               &IdleLogoutDialogView::UpdateCountdown);
162}
163
164void IdleLogoutDialogView::Close() {
165  DCHECK(GetWidget());
166
167  if (timer_.IsRunning())
168    timer_.Stop();
169  GetWidget()->Close();
170
171  // We just closed our dialog. The global
172  // instance is invalid now, set it to null.
173  g_instance = NULL;
174}
175
176void IdleLogoutDialogView::UpdateCountdown() {
177  base::TimeDelta logout_warning_time = countdown_end_time_ -
178                                        base::Time::Now();
179  int64 seconds_left = (logout_warning_time.InMillisecondsF() /
180                        base::Time::kMillisecondsPerSecond) + 0.5;
181
182  if (seconds_left > 1) {
183    restart_label_->SetText(l10n_util::GetStringFUTF16(
184        IDS_IDLE_LOGOUT_WARNING_RESTART,
185        base::Int64ToString16(seconds_left)));
186  } else if (seconds_left > 0) {
187    restart_label_->SetText(l10n_util::GetStringUTF16(
188        IDS_IDLE_LOGOUT_WARNING_RESTART_1S));
189  } else {
190    // Set the label - the logout probably won't be instant.
191    restart_label_->SetText(l10n_util::GetStringUTF16(
192        IDS_IDLE_LOGOUT_WARNING_RESTART_NOW));
193
194    // We're done; stop the timer and logout.
195    timer_.Stop();
196    IdleLogoutDialogView::provider_->LogoutCurrentUser(this);
197  }
198}
199
200// static
201IdleLogoutDialogView* IdleLogoutDialogView::current_instance() {
202  return g_instance;
203}
204
205// static
206void IdleLogoutDialogView::set_settings_provider(
207    IdleLogoutSettingsProvider* provider) {
208  provider_ = provider;
209}
210
211}  // namespace chromeos
212