| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chromeos/ui/idle_logout_dialog_view.h" |
| |
| #include "ash/shell.h" |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h" |
| #include "chrome/browser/ui/browser_list.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "chromeos/dbus/session_manager_client.h" |
| #include "grit/browser_resources.h" |
| #include "grit/generated_resources.h" |
| #include "ui/aura/root_window.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/layout/grid_layout.h" |
| #include "ui/views/layout/layout_constants.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace { |
| |
| // Global singleton instance of our dialog class. |
| chromeos::IdleLogoutDialogView* g_instance = NULL; |
| |
| const int kIdleLogoutDialogMaxWidth = 300; |
| const int kCountdownUpdateIntervalMs = 1000; |
| |
| } // namespace |
| |
| namespace chromeos { |
| |
| IdleLogoutSettingsProvider* IdleLogoutDialogView::provider_ = NULL; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // IdleLogoutSettingsProvider public methods |
| IdleLogoutSettingsProvider::IdleLogoutSettingsProvider() { |
| } |
| |
| IdleLogoutSettingsProvider::~IdleLogoutSettingsProvider() { |
| } |
| |
| base::TimeDelta IdleLogoutSettingsProvider::GetCountdownUpdateInterval() { |
| return base::TimeDelta::FromMilliseconds(kCountdownUpdateIntervalMs); |
| } |
| |
| KioskModeSettings* IdleLogoutSettingsProvider::GetKioskModeSettings() { |
| return KioskModeSettings::Get(); |
| } |
| |
| void IdleLogoutSettingsProvider::LogoutCurrentUser(IdleLogoutDialogView*) { |
| DBusThreadManager::Get()->GetSessionManagerClient()->StopSession(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // IdleLogoutDialogView public static methods |
| // static |
| void IdleLogoutDialogView::ShowDialog() { |
| // We only show the dialog if it is not already showing. We don't want two |
| // countdowns on the screen for any reason. If the dialog is closed by using |
| // CloseDialog, we reset g_instance so the next Show will work correctly; in |
| // case the dialog is closed by the system, DeleteDelegate is guaranteed to be |
| // called, in which case we reset g_instance there if not already reset. |
| if (!g_instance) { |
| g_instance = new IdleLogoutDialogView(); |
| g_instance->InitAndShow(); |
| } |
| } |
| |
| // static |
| void IdleLogoutDialogView::CloseDialog() { |
| if (g_instance) |
| g_instance->GetWidget()->Close(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // Overridden from views::DialogDelegateView |
| int IdleLogoutDialogView::GetDialogButtons() const { |
| return ui::DIALOG_BUTTON_NONE; |
| } |
| |
| ui::ModalType IdleLogoutDialogView::GetModalType() const { |
| return ui::MODAL_TYPE_WINDOW; |
| } |
| |
| base::string16 IdleLogoutDialogView::GetWindowTitle() const { |
| return l10n_util::GetStringUTF16(IDS_IDLE_LOGOUT_TITLE); |
| } |
| |
| bool IdleLogoutDialogView::Close() { |
| if (timer_.IsRunning()) |
| timer_.Stop(); |
| |
| // We just closed our dialog. The global |
| // instance is invalid now, set it to null. |
| g_instance = NULL; |
| |
| return true; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // IdleLogoutDialog private methods |
| IdleLogoutDialogView::IdleLogoutDialogView() |
| : restart_label_(NULL), |
| weak_ptr_factory_(this) { |
| if (!IdleLogoutDialogView::provider_) |
| IdleLogoutDialogView::provider_ = new IdleLogoutSettingsProvider(); |
| } |
| |
| IdleLogoutDialogView::~IdleLogoutDialogView() { |
| if (this == g_instance) |
| g_instance = NULL; |
| } |
| |
| void IdleLogoutDialogView::InitAndShow() { |
| KioskModeSettings* settings = |
| IdleLogoutDialogView::provider_->GetKioskModeSettings(); |
| if (!settings->is_initialized()) { |
| settings->Initialize(base::Bind(&IdleLogoutDialogView::InitAndShow, |
| weak_ptr_factory_.GetWeakPtr())); |
| return; |
| } |
| |
| ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| |
| restart_label_ = new views::Label(); |
| restart_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| restart_label_->SetMultiLine(true); |
| restart_label_->SetFont(rb.GetFont(ui::ResourceBundle::BaseFont)); |
| |
| views::GridLayout* layout = views::GridLayout::CreatePanel(this); |
| SetLayoutManager(layout); |
| |
| views::ColumnSet* column_set = layout->AddColumnSet(0); |
| column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER, 1, |
| views::GridLayout::FIXED, kIdleLogoutDialogMaxWidth, 0); |
| layout->StartRow(0, 0); |
| layout->AddPaddingRow(0, views::kRelatedControlHorizontalSpacing); |
| layout->StartRow(0, 0); |
| layout->AddView(restart_label_); |
| layout->AddPaddingRow(0, views::kRelatedControlHorizontalSpacing); |
| |
| // We're initialized, show the dialog. |
| Show(); |
| } |
| |
| void IdleLogoutDialogView::Show() { |
| KioskModeSettings* settings = |
| IdleLogoutDialogView::provider_->GetKioskModeSettings(); |
| |
| // Setup the countdown label before showing. |
| countdown_end_time_ = base::Time::Now() + |
| settings->GetIdleLogoutWarningDuration(); |
| |
| UpdateCountdown(); |
| |
| views::DialogDelegate::CreateDialogWidget( |
| this, ash::Shell::GetPrimaryRootWindow(), NULL); |
| GetWidget()->SetAlwaysOnTop(true); |
| GetWidget()->Show(); |
| |
| // Update countdown every 1 second. |
| timer_.Start(FROM_HERE, |
| IdleLogoutDialogView::provider_->GetCountdownUpdateInterval(), |
| this, |
| &IdleLogoutDialogView::UpdateCountdown); |
| } |
| |
| void IdleLogoutDialogView::UpdateCountdown() { |
| base::TimeDelta logout_warning_time = countdown_end_time_ - |
| base::Time::Now(); |
| int64 seconds_left = (logout_warning_time.InMillisecondsF() / |
| base::Time::kMillisecondsPerSecond) + 0.5; |
| |
| if (seconds_left > 1) { |
| restart_label_->SetText(l10n_util::GetStringFUTF16( |
| IDS_IDLE_LOGOUT_WARNING_RESTART, |
| base::Int64ToString16(seconds_left))); |
| } else if (seconds_left > 0) { |
| restart_label_->SetText(l10n_util::GetStringUTF16( |
| IDS_IDLE_LOGOUT_WARNING_RESTART_1S)); |
| } else { |
| // Set the label - the logout probably won't be instant. |
| restart_label_->SetText(l10n_util::GetStringUTF16( |
| IDS_IDLE_LOGOUT_WARNING_RESTART_NOW)); |
| |
| // We're done; stop the timer and logout. |
| timer_.Stop(); |
| IdleLogoutDialogView::provider_->LogoutCurrentUser(this); |
| } |
| } |
| |
| // static |
| IdleLogoutDialogView* IdleLogoutDialogView::current_instance() { |
| return g_instance; |
| } |
| |
| // static |
| void IdleLogoutDialogView::set_settings_provider( |
| IdleLogoutSettingsProvider* provider) { |
| provider_ = provider; |
| } |
| |
| } // namespace chromeos |