Home | History | Annotate | Download | only in multi_user
      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 "ash/system/chromeos/multi_user/user_switch_util.h"
      6 
      7 #include "ash/shell.h"
      8 #include "ash/system/chromeos/screen_security/screen_tray_item.h"
      9 #include "ash/system/tray/system_tray.h"
     10 #include "grit/ash_strings.h"
     11 #include "ui/base/l10n/l10n_util.h"
     12 #include "ui/base/resource/resource_bundle.h"
     13 #include "ui/views/controls/label.h"
     14 #include "ui/views/layout/grid_layout.h"
     15 #include "ui/views/widget/widget.h"
     16 #include "ui/views/window/dialog_delegate.h"
     17 
     18 namespace ash {
     19 
     20 namespace {
     21 
     22 // Default width/height of the dialog.
     23 const int kDefaultWidth = 500;
     24 const int kDefaultHeight = 150;
     25 
     26 const int kPaddingToMessage = 30;
     27 const int kInset = 40;
     28 const int kTopInset = 10;
     29 
     30 ////////////////////////////////////////////////////////////////////////////////
     31 // Dialog for multi-profiles desktop casting warning.
     32 class DesktopCastingWarningView : public views::DialogDelegateView {
     33  public:
     34   DesktopCastingWarningView(base::Callback<void()> on_accept);
     35   virtual ~DesktopCastingWarningView();
     36 
     37   static void ShowDialog(const base::Callback<void()> on_accept);
     38 
     39   // views::DialogDelegate overrides.
     40   virtual bool Accept() OVERRIDE;
     41   virtual base::string16 GetDialogButtonLabel(
     42         ui::DialogButton button) const OVERRIDE;
     43   virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
     44   virtual int GetDefaultDialogButton() const OVERRIDE;
     45 
     46   // views::WidgetDelegate overrides.
     47   virtual ui::ModalType GetModalType() const OVERRIDE;
     48 
     49   // views::View overrides.
     50   virtual gfx::Size GetPreferredSize() const OVERRIDE;
     51 
     52  private:
     53   void InitDialog();
     54 
     55   const base::Callback<void()> on_switch_;
     56 
     57   DISALLOW_COPY_AND_ASSIGN(DesktopCastingWarningView);
     58 };
     59 
     60 // The current instance of the running dialog - or NULL. This is used for
     61 // unittest related functions.
     62 static DesktopCastingWarningView* instance_for_test;
     63 
     64 ////////////////////////////////////////////////////////////////////////////////
     65 // DesktopCastingWarningView implementation.
     66 
     67 DesktopCastingWarningView::DesktopCastingWarningView(
     68     const base::Callback<void()> on_switch)
     69     : on_switch_(on_switch) {
     70   DCHECK(!instance_for_test);
     71   instance_for_test = this;
     72 }
     73 
     74 DesktopCastingWarningView::~DesktopCastingWarningView() {
     75   DCHECK(instance_for_test);
     76   instance_for_test = NULL;
     77 }
     78 
     79 // static
     80 void DesktopCastingWarningView::ShowDialog(
     81     const base::Callback<void()> on_accept) {
     82   DesktopCastingWarningView* dialog_view =
     83       new DesktopCastingWarningView(on_accept);
     84   views::DialogDelegate::CreateDialogWidget(
     85       dialog_view, ash::Shell::GetTargetRootWindow(), NULL);
     86   dialog_view->InitDialog();
     87   views::Widget* widget = dialog_view->GetWidget();
     88   DCHECK(widget);
     89   widget->Show();
     90 }
     91 
     92 bool DesktopCastingWarningView::Accept() {
     93   // Stop screen sharing and capturing.
     94   SystemTray* system_tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
     95   if (system_tray->GetScreenShareItem()->is_started())
     96     system_tray->GetScreenShareItem()->Stop();
     97   if (system_tray->GetScreenCaptureItem()->is_started())
     98     system_tray->GetScreenCaptureItem()->Stop();
     99 
    100   on_switch_.Run();
    101   return true;
    102 }
    103 
    104 base::string16 DesktopCastingWarningView::GetDialogButtonLabel(
    105       ui::DialogButton button) const {
    106   return l10n_util::GetStringUTF16(
    107       button == ui::DIALOG_BUTTON_OK ?
    108           IDS_DESKTOP_CASTING_ACTIVE_BUTTON_SWITCH_USER :
    109           IDS_DESKTOP_CASTING_ACTIVE_BUTTON_ABORT_USER_SWITCH);
    110 }
    111 
    112 bool DesktopCastingWarningView::IsDialogButtonEnabled(
    113     ui::DialogButton button) const {
    114   return button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL;
    115 }
    116 
    117 int DesktopCastingWarningView::GetDefaultDialogButton() const {
    118   // The default should turn off the casting.
    119   return ui::DIALOG_BUTTON_CANCEL;
    120 }
    121 
    122 ui::ModalType DesktopCastingWarningView::GetModalType() const {
    123   return ui::MODAL_TYPE_SYSTEM;
    124 }
    125 
    126 gfx::Size DesktopCastingWarningView::GetPreferredSize() const {
    127   return gfx::Size(kDefaultWidth, kDefaultHeight);
    128 }
    129 
    130 void DesktopCastingWarningView::InitDialog() {
    131   const gfx::Insets kDialogInsets(kTopInset, kInset, kInset, kInset);
    132 
    133   // Create the views and layout manager and set them up.
    134   views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this);
    135   grid_layout->SetInsets(kDialogInsets);
    136 
    137   views::ColumnSet* column_set = grid_layout->AddColumnSet(0);
    138   column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
    139                         views::GridLayout::USE_PREF, 0, 0);
    140 
    141   // Title
    142   views::Label* title_label_ = new views::Label(
    143       l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_TITLE));
    144   title_label_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
    145       ui::ResourceBundle::MediumBoldFont));
    146   title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    147   grid_layout->StartRow(0, 0);
    148   grid_layout->AddView(title_label_);
    149   grid_layout->AddPaddingRow(0, kPaddingToMessage);
    150 
    151   // Explanation string
    152   views::Label* label = new views::Label(
    153       l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_MESSAGE));
    154   label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList(
    155       ui::ResourceBundle::MediumFont));
    156   label->SetMultiLine(true);
    157   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    158   label->SetAllowCharacterBreak(true);
    159   grid_layout->StartRow(0, 0);
    160   grid_layout->AddView(label);
    161 
    162   SetLayoutManager(grid_layout);
    163   Layout();
    164 }
    165 
    166 }  // namespace
    167 
    168 ////////////////////////////////////////////////////////////////////////////////
    169 // Factory function.
    170 
    171 void TrySwitchingActiveUser(
    172    const base::Callback<void()> on_switch) {
    173   // Some unit tests do not have a shell. In that case simply execute.
    174   if (!ash::Shell::HasInstance()) {
    175     on_switch.Run();
    176     return;
    177   }
    178   // If neither screen sharing nor capturing is going on we can immediately
    179   // switch users.
    180   SystemTray* system_tray = ash::Shell::GetInstance()->GetPrimarySystemTray();
    181   if (!system_tray->GetScreenShareItem()->is_started() &&
    182       !system_tray->GetScreenCaptureItem()->is_started()) {
    183     on_switch.Run();
    184     return;
    185   }
    186   DesktopCastingWarningView::ShowDialog(on_switch);
    187 }
    188 
    189 bool TestAndTerminateDesktopCastingWarningForTest(bool accept) {
    190   if (!instance_for_test)
    191     return false;
    192   if (accept)
    193     instance_for_test->Accept();
    194   delete instance_for_test->GetWidget()->GetNativeWindow();
    195   CHECK(!instance_for_test);
    196   return true;
    197 }
    198 
    199 }  // namespace chromeos
    200