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