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