diff options
author | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-22 00:47:16 +0000 |
---|---|---|
committer | skuhne@chromium.org <skuhne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-22 00:49:08 +0000 |
commit | 0e316c3f250b7a2cf9d5858df42bbc773d72c403 (patch) | |
tree | 38d95923d5f88af1f0b18243e2267e7700e4ba43 /ash | |
parent | 38881e37ad2c72fafbeb70b83d1aaaa4f2094e33 (diff) | |
download | chromium_src-0e316c3f250b7a2cf9d5858df42bbc773d72c403.zip chromium_src-0e316c3f250b7a2cf9d5858df42bbc773d72c403.tar.gz chromium_src-0e316c3f250b7a2cf9d5858df42bbc773d72c403.tar.bz2 |
Multiprofile security: Show a warning messagebox when desktop
casting/sharing is turned on upon user switch
Purpose of this change:
Asks the user with a system modal dialog box if he wants to
turn off screen sharing/screen casting and then switch users
or abort switching users.
BUG=353170
TEST=TrySwitchingUserTest.*
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=291152
Review URL: https://codereview.chromium.org/496563002
Cr-Commit-Position: refs/heads/master@{#291276}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@291276 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/ash.gyp | 3 | ||||
-rw-r--r-- | ash/ash_chromeos_strings.grdp | 14 | ||||
-rw-r--r-- | ash/system/OWNERS | 1 | ||||
-rw-r--r-- | ash/system/chromeos/multi_user/user_switch_util.cc | 199 | ||||
-rw-r--r-- | ash/system/chromeos/multi_user/user_switch_util.h | 26 | ||||
-rw-r--r-- | ash/system/chromeos/multi_user/user_switch_util_unittest.cc | 228 | ||||
-rw-r--r-- | ash/system/tray/system_tray.cc | 6 | ||||
-rw-r--r-- | ash/system/tray/system_tray.h | 8 | ||||
-rw-r--r-- | ash/system/user/tray_user.cc | 7 | ||||
-rw-r--r-- | ash/system/user/tray_user_separator.cc | 4 | ||||
-rw-r--r-- | ash/system/user/user_view.cc | 7 |
11 files changed, 496 insertions, 7 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 5e8383e..f6a0581 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -291,6 +291,8 @@ 'system/chromeos/keyboard_brightness_controller.h', 'system/chromeos/label_tray_view.cc', 'system/chromeos/label_tray_view.h', + 'system/chromeos/multi_user/user_switch_util.cc', + 'system/chromeos/multi_user/user_switch_util.h', 'system/chromeos/network/network_connect.cc', 'system/chromeos/network/network_connect.h', 'system/chromeos/network/network_detailed_view.h', @@ -810,6 +812,7 @@ 'system/chromeos/power/power_status_view_unittest.cc', 'system/chromeos/power/tray_power_unittest.cc', 'system/chromeos/rotation/tray_rotation_lock_unittest.cc', + 'system/chromeos/multi_user/user_switch_util_unittest.cc', 'system/chromeos/screen_security/screen_tray_item_unittest.cc', 'system/chromeos/session/logout_confirmation_controller_unittest.cc', 'system/chromeos/session/tray_session_length_limit_unittest.cc', diff --git a/ash/ash_chromeos_strings.grdp b/ash/ash_chromeos_strings.grdp index e8e49fd3..ae39085 100644 --- a/ash/ash_chromeos_strings.grdp +++ b/ash/ash_chromeos_strings.grdp @@ -134,6 +134,20 @@ Server message: <ph name="server_msg">$3<ex>Incorrect password</ex></ph> Activation of '<ph name="name">$1<ex>Generic Wireless</ex></ph>' requires a network connection. </message> + <!-- Ash multi-user warning dialog --> + <message name="IDS_DESKTOP_CASTING_ACTIVE_TITLE" desc="The title for the dialog which tells the user that desktop casting is in progress, asking if the casting should be stopped before switching - or - the switch should be aborted."> + Stop screen sharing? + </message> + <message name="IDS_DESKTOP_CASTING_ACTIVE_MESSAGE" desc="The message for the dialog which tells the user that desktop casting is in progress, asking if the casting should be stopped before switching - or - the switch should be aborted."> + Screen sharing will stop when you switch to another user. Do you want to continue? + </message> + <message name="IDS_DESKTOP_CASTING_ACTIVE_BUTTON_SWITCH_USER" desc="The button label for the dialog which tells the user that desktop casting is in progress. By selecting this button the casting will be stopped and the user will get switched."> + Yes + </message> + <message name="IDS_DESKTOP_CASTING_ACTIVE_BUTTON_ABORT_USER_SWITCH" desc="The button label for the dialog which tells the user that desktop casting is in progress. By selecting this button the user switch will be cancelled."> + No + </message> + <!-- Network error strings --> <message name="IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN" desc="Network error details in notifications: UNKNOWN"> Unknown network error diff --git a/ash/system/OWNERS b/ash/system/OWNERS index de76ad8..91d332f 100644 --- a/ash/system/OWNERS +++ b/ash/system/OWNERS @@ -1,3 +1,4 @@ sadrul@chromium.org stevenjb@chromium.org jennyz@chromium.org +skuhne@chromium.org diff --git a/ash/system/chromeos/multi_user/user_switch_util.cc b/ash/system/chromeos/multi_user/user_switch_util.cc new file mode 100644 index 0000000..b6668f9 --- /dev/null +++ b/ash/system/chromeos/multi_user/user_switch_util.cc @@ -0,0 +1,199 @@ +// Copyright 2014 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 "ash/system/chromeos/multi_user/user_switch_util.h" + +#include "ash/shell.h" +#include "ash/system/chromeos/screen_security/screen_tray_item.h" +#include "ash/system/tray/system_tray.h" +#include "grit/ash_strings.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/widget/widget.h" +#include "ui/views/window/dialog_delegate.h" + +namespace ash { + +namespace { + +// Default width/height of the dialog. +const int kDefaultWidth = 500; +const int kDefaultHeight = 150; + +const int kPaddingToMessage = 30; +const int kInset = 40; +const int kTopInset = 10; + +//////////////////////////////////////////////////////////////////////////////// +// Dialog for multi-profiles desktop casting warning. +class DesktopCastingWarningView : public views::DialogDelegateView { + public: + DesktopCastingWarningView(base::Callback<void()> on_accept); + virtual ~DesktopCastingWarningView(); + + static void ShowDialog(const base::Callback<void()> on_accept); + + // views::DialogDelegate overrides. + virtual bool Accept() OVERRIDE; + virtual base::string16 GetDialogButtonLabel( + ui::DialogButton button) const OVERRIDE; + virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE; + virtual int GetDefaultDialogButton() const OVERRIDE; + + // views::WidgetDelegate overrides. + virtual ui::ModalType GetModalType() const OVERRIDE; + + // views::View overrides. + virtual gfx::Size GetPreferredSize() const OVERRIDE; + + private: + void InitDialog(); + + const base::Callback<void()> on_switch_; + + DISALLOW_COPY_AND_ASSIGN(DesktopCastingWarningView); +}; + +// The current instance of the running dialog - or NULL. This is used for +// unittest related functions. +static DesktopCastingWarningView* instance_for_test; + +//////////////////////////////////////////////////////////////////////////////// +// DesktopCastingWarningView implementation. + +DesktopCastingWarningView::DesktopCastingWarningView( + const base::Callback<void()> on_switch) + : on_switch_(on_switch) { + DCHECK(!instance_for_test); + instance_for_test = this; +} + +DesktopCastingWarningView::~DesktopCastingWarningView() { + DCHECK(instance_for_test); + instance_for_test = NULL; +} + +// static +void DesktopCastingWarningView::ShowDialog( + const base::Callback<void()> on_accept) { + DesktopCastingWarningView* dialog_view = + new DesktopCastingWarningView(on_accept); + views::DialogDelegate::CreateDialogWidget( + dialog_view, ash::Shell::GetTargetRootWindow(), NULL); + dialog_view->InitDialog(); + views::Widget* widget = dialog_view->GetWidget(); + DCHECK(widget); + widget->Show(); +} + +bool DesktopCastingWarningView::Accept() { + // Stop screen sharing and capturing. + SystemTray* system_tray = ash::Shell::GetInstance()->GetPrimarySystemTray(); + if (system_tray->GetScreenShareItem()->is_started()) + system_tray->GetScreenShareItem()->Stop(); + if (system_tray->GetScreenCaptureItem()->is_started()) + system_tray->GetScreenCaptureItem()->Stop(); + + on_switch_.Run(); + return true; +} + +base::string16 DesktopCastingWarningView::GetDialogButtonLabel( + ui::DialogButton button) const { + return l10n_util::GetStringUTF16( + button == ui::DIALOG_BUTTON_OK ? + IDS_DESKTOP_CASTING_ACTIVE_BUTTON_SWITCH_USER : + IDS_DESKTOP_CASTING_ACTIVE_BUTTON_ABORT_USER_SWITCH); +} + +bool DesktopCastingWarningView::IsDialogButtonEnabled( + ui::DialogButton button) const { + return button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL; +} + +int DesktopCastingWarningView::GetDefaultDialogButton() const { + // The default should turn off the casting. + return ui::DIALOG_BUTTON_CANCEL; +} + +ui::ModalType DesktopCastingWarningView::GetModalType() const { + return ui::MODAL_TYPE_SYSTEM; +} + +gfx::Size DesktopCastingWarningView::GetPreferredSize() const { + return gfx::Size(kDefaultWidth, kDefaultHeight); +} + +void DesktopCastingWarningView::InitDialog() { + const gfx::Insets kDialogInsets(kTopInset, kInset, kInset, kInset); + + // Create the views and layout manager and set them up. + views::GridLayout* grid_layout = views::GridLayout::CreatePanel(this); + grid_layout->SetInsets(kDialogInsets); + + views::ColumnSet* column_set = grid_layout->AddColumnSet(0); + column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, + views::GridLayout::USE_PREF, 0, 0); + + // Title + views::Label* title_label_ = new views::Label( + l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_TITLE)); + title_label_->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( + ui::ResourceBundle::MediumBoldFont)); + title_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); + grid_layout->StartRow(0, 0); + grid_layout->AddView(title_label_); + grid_layout->AddPaddingRow(0, kPaddingToMessage); + + // Explanation string + views::Label* label = new views::Label( + l10n_util::GetStringUTF16(IDS_DESKTOP_CASTING_ACTIVE_MESSAGE)); + label->SetFontList(ui::ResourceBundle::GetSharedInstance().GetFontList( + ui::ResourceBundle::MediumFont)); + label->SetMultiLine(true); + label->SetHorizontalAlignment(gfx::ALIGN_LEFT); + label->SetAllowCharacterBreak(true); + grid_layout->StartRow(0, 0); + grid_layout->AddView(label); + + SetLayoutManager(grid_layout); + Layout(); +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// Factory function. + +void TrySwitchingActiveUser( + const base::Callback<void()> on_switch) { + // Some unit tests do not have a shell. In that case simply execute. + if (!ash::Shell::HasInstance()) { + on_switch.Run(); + return; + } + // If neither screen sharing nor capturing is going on we can immediately + // switch users. + SystemTray* system_tray = ash::Shell::GetInstance()->GetPrimarySystemTray(); + if (!system_tray->GetScreenShareItem()->is_started() && + !system_tray->GetScreenCaptureItem()->is_started()) { + on_switch.Run(); + return; + } + DesktopCastingWarningView::ShowDialog(on_switch); +} + +bool TestAndTerminateDesktopCastingWarningForTest(bool accept) { + if (!instance_for_test) + return false; + if (accept) + instance_for_test->Accept(); + delete instance_for_test->GetWidget()->GetNativeWindow(); + CHECK(!instance_for_test); + return true; +} + +} // namespace chromeos diff --git a/ash/system/chromeos/multi_user/user_switch_util.h b/ash/system/chromeos/multi_user/user_switch_util.h new file mode 100644 index 0000000..965f014 --- /dev/null +++ b/ash/system/chromeos/multi_user/user_switch_util.h @@ -0,0 +1,26 @@ +// Copyright 2014 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. + +#ifndef ASH_SYSTEM_CHROMEOS_MULTI_USER_MULTI_USER_SWITCH_UTIL_H_ +#define ASH_SYSTEM_CHROMEOS_MULTI_USER_MULTI_USER_SWITCH_UTIL_H_ + +#include "ash/ash_export.h" +#include "base/callback.h" + +namespace ash { + +// Tries to switch to a new user by first checking if desktop casting / sharing +// is going on, and let the user decide if he wants to terminate it or not. +// After terminating any desktop sharing operations, the |switch_user| function +// will be called. +void ASH_EXPORT TrySwitchingActiveUser( + const base::Callback<void()> switch_user); + +// Terminates the "DesktopCastingWarning" dialog from a unit tests and |accept|s +// it. False will be returned if there was no dialog shown. +bool ASH_EXPORT TestAndTerminateDesktopCastingWarningForTest(bool accept); + +} // namespace chromeos + +#endif // ASH_SYSTEM_CHROMEOS_MULTI_USER_MULTI_USER_SWITCH_UTIL_H_ diff --git a/ash/system/chromeos/multi_user/user_switch_util_unittest.cc b/ash/system/chromeos/multi_user/user_switch_util_unittest.cc new file mode 100644 index 0000000..16eb032 --- /dev/null +++ b/ash/system/chromeos/multi_user/user_switch_util_unittest.cc @@ -0,0 +1,228 @@ +// Copyright 2014 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 "ash/shell.h" +#include "ash/system/chromeos/multi_user/user_switch_util.h" +#include "ash/system/chromeos/screen_security/screen_tray_item.h" +#include "ash/system/tray/system_tray.h" +#include "ash/test/ash_test_base.h" + +namespace ash { + +class TrySwitchingUserTest : public ash::test::AshTestBase { + public: + // The action type to perform / check for upon user switching. + enum ActionType { + NO_DIALOG, // No dialog should be shown. + ACCEPT_DIALOG, // A dialog should be shown and we should accept it. + DECLINE_DIALOG, // A dialog should be shown and we do not accept it. + }; + TrySwitchingUserTest() + : capture_item_(NULL), + share_item_(NULL), + stop_capture_callback_hit_count_(0), + stop_share_callback_hit_count_(0), + switch_callback_hit_count_(0) {} + virtual ~TrySwitchingUserTest() {} + + virtual void SetUp() OVERRIDE { + test::AshTestBase::SetUp(); + TrayItemView::DisableAnimationsForTest(); + SystemTray* system_tray = Shell::GetInstance()->GetPrimarySystemTray(); + share_item_ = system_tray->GetScreenShareItem(); + capture_item_ = system_tray->GetScreenCaptureItem(); + EXPECT_TRUE(share_item_); + EXPECT_TRUE(capture_item_); + } + + // Accessing the capture session functionality. + // Simulates a screen capture session start. + void StartCaptureSession() { + capture_item_->Start( + base::Bind(&TrySwitchingUserTest::StopCaptureCallback, + base::Unretained(this))); + } + + // The callback which gets called when the screen capture gets stopped. + void StopCaptureSession() { + capture_item_->Stop(); + } + + // Simulates a screen capture session stop. + void StopCaptureCallback() { + stop_capture_callback_hit_count_++; + } + + // Accessing the share session functionality. + // Simulate a Screen share session start. + void StartShareSession() { + share_item_->Start( + base::Bind(&TrySwitchingUserTest::StopShareCallback, + base::Unretained(this))); + } + + // Simulates a screen share session stop. + void StopShareSession() { + share_item_->Stop(); + } + + // The callback which gets called when the screen share gets stopped. + void StopShareCallback() { + stop_share_callback_hit_count_++; + } + + // Issuing a switch user call which might or might not create a dialog. + // The passed |action| type parameter defines the outcome (which will be + // checked) and the action the user will choose. + void SwitchUser(ActionType action) { + TrySwitchingActiveUser( + base::Bind(&TrySwitchingUserTest::SwitchCallback, + base::Unretained(this))); + switch(action) { + case NO_DIALOG: + EXPECT_TRUE(!TestAndTerminateDesktopCastingWarningForTest(true)); + return; + case ACCEPT_DIALOG: + EXPECT_TRUE(TestAndTerminateDesktopCastingWarningForTest(true)); + return; + case DECLINE_DIALOG: + EXPECT_TRUE(TestAndTerminateDesktopCastingWarningForTest(false)); + return; + } + } + + // Called when the user will get actually switched. + void SwitchCallback() { + switch_callback_hit_count_++; + } + + // Various counter accessors. + int stop_capture_callback_hit_count() const { + return stop_capture_callback_hit_count_; + } + int stop_share_callback_hit_count() const { + return stop_share_callback_hit_count_; + } + int switch_callback_hit_count() const { return switch_callback_hit_count_; } + + private: + // The two items from the SystemTray for the screen capture / share + // functionality. + ScreenTrayItem* capture_item_; + ScreenTrayItem* share_item_; + + // Various counters to query for. + int stop_capture_callback_hit_count_; + int stop_share_callback_hit_count_; + int switch_callback_hit_count_; + + DISALLOW_COPY_AND_ASSIGN(TrySwitchingUserTest); +}; + +// Test that when there is no screen operation going on the user switch will be +// performed as planned. +TEST_F(TrySwitchingUserTest, NoLock) { + EXPECT_EQ(0, switch_callback_hit_count()); + SwitchUser(TrySwitchingUserTest::NO_DIALOG); + EXPECT_EQ(1, switch_callback_hit_count()); +} + +// Test that with a screen capture operation going on, the user will need to +// confirm. Declining will neither change the running state or switch users. +TEST_F(TrySwitchingUserTest, CaptureActiveDeclined) { + EXPECT_EQ(0, switch_callback_hit_count()); + StartCaptureSession(); + SwitchUser(TrySwitchingUserTest::DECLINE_DIALOG); + EXPECT_EQ(0, switch_callback_hit_count()); + EXPECT_EQ(0, stop_capture_callback_hit_count()); + EXPECT_EQ(0, stop_share_callback_hit_count()); + StopCaptureSession(); + EXPECT_EQ(0, switch_callback_hit_count()); + EXPECT_EQ(1, stop_capture_callback_hit_count()); + EXPECT_EQ(0, stop_share_callback_hit_count()); +} + +// Test that with a screen share operation going on, the user will need to +// confirm. Declining will neither change the running state or switch users. +TEST_F(TrySwitchingUserTest, ShareActiveDeclined) { + EXPECT_EQ(0, switch_callback_hit_count()); + StartShareSession(); + SwitchUser(TrySwitchingUserTest::DECLINE_DIALOG); + EXPECT_EQ(0, switch_callback_hit_count()); + EXPECT_EQ(0, stop_capture_callback_hit_count()); + EXPECT_EQ(0, stop_share_callback_hit_count()); + StopShareSession(); + EXPECT_EQ(0, switch_callback_hit_count()); + EXPECT_EQ(0, stop_capture_callback_hit_count()); + EXPECT_EQ(1, stop_share_callback_hit_count()); +} + +// Test that with both operations going on, the user will need to confirm. +// Declining will neither change the running state or switch users. +TEST_F(TrySwitchingUserTest, BothActiveDeclined) { + EXPECT_EQ(0, switch_callback_hit_count()); + StartShareSession(); + StartCaptureSession(); + SwitchUser(TrySwitchingUserTest::DECLINE_DIALOG); + EXPECT_EQ(0, switch_callback_hit_count()); + EXPECT_EQ(0, stop_capture_callback_hit_count()); + EXPECT_EQ(0, stop_share_callback_hit_count()); + StopShareSession(); + StopCaptureSession(); + EXPECT_EQ(0, switch_callback_hit_count()); + EXPECT_EQ(1, stop_capture_callback_hit_count()); + EXPECT_EQ(1, stop_share_callback_hit_count()); +} + +// Test that with a screen capture operation going on, the user will need to +// confirm. Accepting will change to stopped state and switch users. +TEST_F(TrySwitchingUserTest, CaptureActiveAccepted) { + EXPECT_EQ(0, switch_callback_hit_count()); + StartCaptureSession(); + SwitchUser(TrySwitchingUserTest::ACCEPT_DIALOG); + EXPECT_EQ(1, switch_callback_hit_count()); + EXPECT_EQ(1, stop_capture_callback_hit_count()); + EXPECT_EQ(0, stop_share_callback_hit_count()); + // Another stop should have no effect. + StopCaptureSession(); + EXPECT_EQ(1, switch_callback_hit_count()); + EXPECT_EQ(1, stop_capture_callback_hit_count()); + EXPECT_EQ(0, stop_share_callback_hit_count()); +} + +// Test that with a screen share operation going on, the user will need to +// confirm. Accepting will change to stopped state and switch users. +TEST_F(TrySwitchingUserTest, ShareActiveAccepted) { + EXPECT_EQ(0, switch_callback_hit_count()); + StartShareSession(); + SwitchUser(TrySwitchingUserTest::ACCEPT_DIALOG); + EXPECT_EQ(1, switch_callback_hit_count()); + EXPECT_EQ(0, stop_capture_callback_hit_count()); + EXPECT_EQ(1, stop_share_callback_hit_count()); + // Another stop should have no effect. + StopShareSession(); + EXPECT_EQ(1, switch_callback_hit_count()); + EXPECT_EQ(0, stop_capture_callback_hit_count()); + EXPECT_EQ(1, stop_share_callback_hit_count()); +} + +// Test that with both operations going on, the user will need to confirm. +// Accepting will change to stopped state and switch users. +TEST_F(TrySwitchingUserTest, BothActiveAccepted) { + EXPECT_EQ(0, switch_callback_hit_count()); + StartShareSession(); + StartCaptureSession(); + SwitchUser(TrySwitchingUserTest::ACCEPT_DIALOG); + EXPECT_EQ(1, switch_callback_hit_count()); + EXPECT_EQ(1, stop_capture_callback_hit_count()); + EXPECT_EQ(1, stop_share_callback_hit_count()); + // Another stop should have no effect. + StopShareSession(); + StopCaptureSession(); + EXPECT_EQ(1, switch_callback_hit_count()); + EXPECT_EQ(1, stop_capture_callback_hit_count()); + EXPECT_EQ(1, stop_share_callback_hit_count()); +} + +} // namespace ash diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 9bd30a0..cbd5f13 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc @@ -182,8 +182,10 @@ void SystemTray::CreateItems(SystemTrayDelegate* delegate) { AddTrayItem(new TraySms(this)); AddTrayItem(new TrayBluetooth(this)); AddTrayItem(new TrayDisplay(this)); - AddTrayItem(new ScreenCaptureTrayItem(this)); - AddTrayItem(new ScreenShareTrayItem(this)); + screen_capture_tray_item_ = new ScreenCaptureTrayItem(this); + AddTrayItem(screen_capture_tray_item_); + screen_share_tray_item_ = new ScreenShareTrayItem(this); + AddTrayItem(screen_share_tray_item_); AddTrayItem(new MultiProfileMediaTrayItem(this)); AddTrayItem(new TrayAudioChromeOs(this)); AddTrayItem(new TrayBrightness(this)); diff --git a/ash/system/tray/system_tray.h b/ash/system/tray/system_tray.h index 2df725d..301ef13 100644 --- a/ash/system/tray/system_tray.h +++ b/ash/system/tray/system_tray.h @@ -20,6 +20,7 @@ #include <vector> namespace ash { +class ScreenTrayItem; class SystemBubbleWrapper; class SystemTrayDelegate; class SystemTrayItem; @@ -141,6 +142,9 @@ class ASH_EXPORT SystemTray : public TrayBackgroundView, AnchorAlignment anchor_alignment) const OVERRIDE; virtual void HideBubble(const views::TrayBubbleView* bubble_view) OVERRIDE; + ScreenTrayItem* GetScreenShareItem() { return screen_share_tray_item_; } + ScreenTrayItem* GetScreenCaptureItem() { return screen_capture_tray_item_; } + TrayAccessibility* GetTrayAccessibilityForTest() { return tray_accessibility_; } @@ -232,6 +236,10 @@ class ASH_EXPORT SystemTray : public TrayBackgroundView, TrayAccessibility* tray_accessibility_; // not owned TrayDate* tray_date_; + // A reference to the Screen share and capture item. + ScreenTrayItem* screen_capture_tray_item_; // not owned + ScreenTrayItem* screen_share_tray_item_; // not owned + DISALLOW_COPY_AND_ASSIGN(SystemTray); }; diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc index cb86298..9851ba1 100644 --- a/ash/system/user/tray_user.cc +++ b/ash/system/user/tray_user.cc @@ -93,8 +93,11 @@ views::View* TrayUser::CreateDefaultView(user::LoginStatus status) { const SessionStateDelegate* session_state_delegate = Shell::GetInstance()->session_state_delegate(); - // If the screen is locked show only the currently active user. - if (multiprofile_index_ && session_state_delegate->IsUserSessionBlocked()) + // If the screen is locked or a system modal dialog box is shown, show only + // the currently active user. + if (multiprofile_index_ && + (session_state_delegate->IsUserSessionBlocked() || + Shell::GetInstance()->IsSystemModalWindowOpen())) return NULL; CHECK(user_ == NULL); diff --git a/ash/system/user/tray_user_separator.cc b/ash/system/user/tray_user_separator.cc index 7058d2f..d152a3b 100644 --- a/ash/system/user/tray_user_separator.cc +++ b/ash/system/user/tray_user_separator.cc @@ -26,8 +26,10 @@ views::View* TrayUserSeparator::CreateDefaultView(user::LoginStatus status) { const SessionStateDelegate* session_state_delegate = Shell::GetInstance()->session_state_delegate(); - // If the screen is locked, or only a single user is shown, show nothing. + // If the screen is locked, a system modal dialog or a single user is shown, + // show nothing. if (session_state_delegate->IsUserSessionBlocked() || + Shell::GetInstance()->IsSystemModalWindowOpen() || session_state_delegate->NumberOfLoggedInUsers() < 2) return NULL; diff --git a/ash/system/user/user_view.cc b/ash/system/user/user_view.cc index 689764f..52f128d 100644 --- a/ash/system/user/user_view.cc +++ b/ash/system/user/user_view.cc @@ -400,8 +400,11 @@ void UserView::AddUserCard(user::LoginStatus login) { max_card_width -= logout_button_->GetPreferredSize().width(); user_card_view_ = new UserCardView(login, max_card_width, multiprofile_index_); - bool clickable = IsMultiProfileSupportedAndUserActive() || - IsMultiAccountSupportedAndUserActive(); + // The entry is clickable when no system modal dialog is open and one of the + // multi user options is active. + bool clickable = !Shell::GetInstance()->IsSystemModalWindowOpen() && + (IsMultiProfileSupportedAndUserActive() || + IsMultiAccountSupportedAndUserActive()); if (clickable) { // To allow the border to start before the icon, reduce the size before and // add an inset to the icon to get the spacing. |