diff options
Diffstat (limited to 'ash')
-rw-r--r-- | ash/ash_strings.grd | 12 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_view.cc | 2 | ||||
-rw-r--r-- | ash/root_window_controller.cc | 2 | ||||
-rw-r--r-- | ash/root_window_controller_unittest.cc | 4 | ||||
-rw-r--r-- | ash/session_state_delegate.h | 42 | ||||
-rw-r--r-- | ash/session_state_delegate_stub.cc | 32 | ||||
-rw-r--r-- | ash/session_state_delegate_stub.h | 15 | ||||
-rw-r--r-- | ash/shell.cc | 2 | ||||
-rw-r--r-- | ash/system/tray/system_tray.cc | 12 | ||||
-rw-r--r-- | ash/system/tray/system_tray_delegate.h | 11 | ||||
-rw-r--r-- | ash/system/tray/system_tray_item.h | 2 | ||||
-rw-r--r-- | ash/system/tray/test_system_tray_delegate.cc | 20 | ||||
-rw-r--r-- | ash/system/tray/test_system_tray_delegate.h | 6 | ||||
-rw-r--r-- | ash/system/user/login_status.cc | 9 | ||||
-rw-r--r-- | ash/system/user/tray_user.cc | 393 | ||||
-rw-r--r-- | ash/system/user/tray_user.h | 10 | ||||
-rw-r--r-- | ash/test/test_session_state_delegate.cc | 34 | ||||
-rw-r--r-- | ash/test/test_session_state_delegate.h | 15 | ||||
-rw-r--r-- | ash/wm/gestures/shelf_gesture_handler.cc | 2 |
19 files changed, 473 insertions, 152 deletions
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 2ea0cf8..5da716d 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd @@ -218,6 +218,9 @@ Press Ctrl+Alt+Z to disable. <message name="IDS_ASH_STATUS_TRAY_SIGN_OUT" desc="The label used for the button in the status tray to sign out of the system."> Sign out </message> + <message name="IDS_ASH_STATUS_TRAY_SIGN_OUT_ALL" desc="The label used for the button in the status tray to sign out all users of the system."> + Sign out all + </message> <message name="IDS_ASH_STATUS_TRAY_GUEST_LABEL" desc="The label used in the system tray's user card to indicate that the current session is a guest session."> Guest </message> @@ -248,6 +251,15 @@ Press Ctrl+Alt+Z to disable. <message name="IDS_ASH_STATUS_TRAY_SMS_NUMBER" desc="Sender for SMS messagees in the system tray."> SMS from <ph name="PHONE_NUMBER">$1<ex>08700 776655</ex></ph> </message> + <message name="IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT" desc="The string for the button which lets the user add another account to the current session."> + Sign in another account... + </message> + <message name="IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER" desc="The caption for the error message when the user has reached the limit of multi profile users."> + Can't sign into another account. + </message> + <message name="IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER" desc="The error message when the user has reached the limit of multi profile users."> + You can only have up to three accounts in multiple sign-in. + </message> <message name="IDS_ASH_STATUS_TRAY_BLUETOOTH" desc="The label used as the header in the bluetooth popup."> Bluetooth diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc index 6d6e487..f851789 100644 --- a/ash/desktop_background/desktop_background_view.cc +++ b/ash/desktop_background/desktop_background_view.cc @@ -201,7 +201,7 @@ views::Widget* CreateDesktopBackground(aura::RootWindow* root_window, // 4. From an empty background, guest user logged in. if (wallpaper_delegate->ShouldShowInitialAnimation() || root_window->GetProperty(kAnimatingDesktopController) || - Shell::GetInstance()->session_state_delegate()->HasActiveUser()) { + Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers()) { views::corewm::SetWindowVisibilityAnimationTransition( desktop_widget->GetNativeView(), views::corewm::ANIMATE_SHOW); } else { diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 6d0355e..2dc3756 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -281,7 +281,7 @@ void RootWindowController::InitForPrimaryDisplay() { new ToplevelWindowEventHandler(panel_container)); panel_container->SetLayoutManager(panel_layout_manager_); - if (Shell::GetInstance()->session_state_delegate()->HasActiveUser()) + if (Shell::GetInstance()->session_state_delegate()->NumberOfLoggedInUsers()) shelf_->CreateLauncher(); InitKeyboard(); diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc index b33e012..4a3351e 100644 --- a/ash/root_window_controller_unittest.cc +++ b/ash/root_window_controller_unittest.cc @@ -327,7 +327,7 @@ TEST_F(RootWindowControllerTest, ModalContainerNotLoggedInLoggedIn) { SetUserLoggedIn(false); EXPECT_EQ(user::LOGGED_IN_NONE, shell->system_tray_delegate()->GetUserLoginStatus()); - EXPECT_FALSE(shell->session_state_delegate()->HasActiveUser()); + EXPECT_EQ(0, shell->session_state_delegate()->NumberOfLoggedInUsers()); EXPECT_FALSE(shell->session_state_delegate()->IsActiveUserSessionStarted()); internal::RootWindowController* controller = @@ -352,7 +352,7 @@ TEST_F(RootWindowControllerTest, ModalContainerNotLoggedInLoggedIn) { SetSessionStarted(true); EXPECT_EQ(user::LOGGED_IN_USER, shell->system_tray_delegate()->GetUserLoginStatus()); - EXPECT_TRUE(shell->session_state_delegate()->HasActiveUser()); + EXPECT_EQ(1, shell->session_state_delegate()->NumberOfLoggedInUsers()); EXPECT_TRUE(shell->session_state_delegate()->IsActiveUserSessionStarted()); EXPECT_EQ(Shell::GetContainer(controller->root_window(), internal::kShellWindowId_SystemModalContainer)->layout_manager(), diff --git a/ash/session_state_delegate.h b/ash/session_state_delegate.h index f5ee359..f5451cf 100644 --- a/ash/session_state_delegate.h +++ b/ash/session_state_delegate.h @@ -5,17 +5,36 @@ #ifndef ASH_SESSION_STATE_DELEGATE_H_ #define ASH_SESSION_STATE_DELEGATE_H_ +#include <string> +#include <vector> + #include "ash/ash_export.h" +#include "base/string16.h" + +namespace gfx { +class ImageSkia; +} // namespace gfx namespace ash { +// The index for the multi-profile item to use. The list is always LRU sorted +// So that the index #0 is the currently active user. +typedef int MultiProfileIndex; + +// A list of email addresses. +typedef std::vector<std::string> UserEmailList; + // Delegate for checking and modifying the session state. class ASH_EXPORT SessionStateDelegate { public: virtual ~SessionStateDelegate() {}; - // Returns |true| if a session is in progress and there is an active user. - virtual bool HasActiveUser() const = 0; + // Returns the maximum possible number of logged in users. + virtual int GetMaximumNumberOfLoggedInUsers() const = 0; + + // Returns the number of signed in users. If 0 is returned, there is either + // no session in progress or no active user. + virtual int NumberOfLoggedInUsers() const = 0; // Returns |true| if the session has been fully started for the active user. // When a user becomes active, the profile and browser UI are not immediately @@ -34,6 +53,25 @@ class ASH_EXPORT SessionStateDelegate { // Unlocks the screen. virtual void UnlockScreen() = 0; + + // Gets the displayed name for the user with the given |index|. + // Note that |index| can at maximum be |NumberOfLoggedInUsers() - 1|. + virtual const base::string16 GetUserDisplayName( + MultiProfileIndex index) const = 0; + + // Gets the email address for the user with the given |index|. + // Note that |index| can at maximum be |NumberOfLoggedInUsers() - 1|. + virtual const std::string GetUserEmail(MultiProfileIndex index) const = 0; + + // Gets the avatar image for the user with the given |index|. + // Note that |index| can at maximum be |NumberOfLoggedInUsers() - 1|. + virtual const gfx::ImageSkia& GetUserImage(MultiProfileIndex index) const = 0; + + // Returns a list of all logged in users. + virtual void GetLoggedInUsers(UserEmailList* users) = 0; + + // Switches to another active user (if that user has already signed in). + virtual void SwitchActiveUser(const std::string& email) = 0; }; } // namespace ash diff --git a/ash/session_state_delegate_stub.cc b/ash/session_state_delegate_stub.cc index b913b5f..86ce366 100644 --- a/ash/session_state_delegate_stub.cc +++ b/ash/session_state_delegate_stub.cc @@ -6,6 +6,8 @@ #include "ash/shell.h" #include "ash/shell/example_factory.h" +#include "base/string16.h" +#include "base/utf_string_conversions.h" namespace ash { @@ -15,8 +17,12 @@ SessionStateDelegateStub::SessionStateDelegateStub() : screen_locked_(false) { SessionStateDelegateStub::~SessionStateDelegateStub() { } -bool SessionStateDelegateStub::HasActiveUser() const { - return true; +int SessionStateDelegateStub::GetMaximumNumberOfLoggedInUsers() const { + return 3; +} + +int SessionStateDelegateStub::NumberOfLoggedInUsers() const { + return 1; } bool SessionStateDelegateStub::IsActiveUserSessionStarted() const { @@ -42,4 +48,26 @@ void SessionStateDelegateStub::UnlockScreen() { Shell::GetInstance()->UpdateShelfVisibility(); } +const base::string16 SessionStateDelegateStub::GetUserDisplayName( + MultiProfileIndex index) const { + return UTF8ToUTF16("stub-user"); +} + +const std::string SessionStateDelegateStub::GetUserEmail( + MultiProfileIndex index) const { + return "stub-user@domain.com"; +} + +const gfx::ImageSkia& SessionStateDelegateStub::GetUserImage( + MultiProfileIndex index) const { + return null_image_; +} + +void SessionStateDelegateStub::GetLoggedInUsers( + UserEmailList* users) { +} + +void SessionStateDelegateStub::SwitchActiveUser(const std::string& email) { +} + } // namespace ash diff --git a/ash/session_state_delegate_stub.h b/ash/session_state_delegate_stub.h index db9b711..707c53e 100644 --- a/ash/session_state_delegate_stub.h +++ b/ash/session_state_delegate_stub.h @@ -8,6 +8,7 @@ #include "ash/session_state_delegate.h" #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "ui/gfx/image/image_skia.h" namespace ash { @@ -18,16 +19,28 @@ class SessionStateDelegateStub : public SessionStateDelegate { virtual ~SessionStateDelegateStub(); // SessionStateDelegate: - virtual bool HasActiveUser() const OVERRIDE; + virtual int GetMaximumNumberOfLoggedInUsers() const OVERRIDE; + virtual int NumberOfLoggedInUsers() const OVERRIDE; virtual bool IsActiveUserSessionStarted() const OVERRIDE; virtual bool CanLockScreen() const OVERRIDE; virtual bool IsScreenLocked() const OVERRIDE; virtual void LockScreen() OVERRIDE; virtual void UnlockScreen() OVERRIDE; + virtual const base::string16 GetUserDisplayName( + ash::MultiProfileIndex index) const OVERRIDE; + virtual const std::string GetUserEmail( + ash::MultiProfileIndex index) const OVERRIDE; + virtual const gfx::ImageSkia& GetUserImage( + ash::MultiProfileIndex index) const OVERRIDE; + virtual void GetLoggedInUsers(UserEmailList* users) OVERRIDE; + virtual void SwitchActiveUser(const std::string& email) OVERRIDE; private: bool screen_locked_; + // A pseudo user image. + gfx::ImageSkia null_image_; + DISALLOW_COPY_AND_ASSIGN(SessionStateDelegateStub); }; diff --git a/ash/shell.cc b/ash/shell.cc index 9112130..1e75bab 100644 --- a/ash/shell.cc +++ b/ash/shell.cc @@ -616,7 +616,7 @@ void Shell::Init() { void Shell::ShowContextMenu(const gfx::Point& location_in_screen) { // No context menus if there is no session with an active user. - if (!session_state_delegate_->HasActiveUser()) + if (!session_state_delegate_->NumberOfLoggedInUsers()) return; // No context menus when screen is locked. if (session_state_delegate_->IsScreenLocked()) diff --git a/ash/system/tray/system_tray.cc b/ash/system/tray/system_tray.cc index 8dc0fa4..4602271 100644 --- a/ash/system/tray/system_tray.cc +++ b/ash/system/tray/system_tray.cc @@ -138,7 +138,17 @@ void SystemTray::CreateItems(SystemTrayDelegate* delegate) { #if !defined(OS_WIN) AddTrayItem(new internal::TraySessionLengthLimit(this)); AddTrayItem(new internal::TrayLogoutButton(this)); - AddTrayItem(new internal::TrayUser(this)); + // In multi-profile user mode we can have multiple user tiles. + ash::Shell* shell = ash::Shell::GetInstance(); + int maximum_user_profiles = + shell->delegate()->IsMultiProfilesEnabled() ? + shell->session_state_delegate()->GetMaximumNumberOfLoggedInUsers() : + 0; + // Note: We purposely use one more item then logged in users to account for + // the additional separator. + for (int i = 0; i <= maximum_user_profiles; i++) + AddTrayItem(new internal::TrayUser(this, i)); + #endif #if defined(OS_CHROMEOS) AddTrayItem(new internal::TrayEnterprise(this)); diff --git a/ash/system/tray/system_tray_delegate.h b/ash/system/tray/system_tray_delegate.h index 32c5830..2e84617 100644 --- a/ash/system/tray/system_tray_delegate.h +++ b/ash/system/tray/system_tray_delegate.h @@ -110,8 +110,6 @@ typedef std::vector<IMEInfo> IMEInfoList; class VolumeControlDelegate; -typedef std::vector<std::string> UserEmailList; - class SystemTrayDelegate { public: virtual ~SystemTrayDelegate() {} @@ -126,18 +124,9 @@ class SystemTrayDelegate { virtual bool GetTrayVisibilityOnStartup() = 0; // Gets information about the active user. - virtual const base::string16 GetUserDisplayName() const = 0; - virtual const std::string GetUserEmail() const = 0; - virtual const gfx::ImageSkia& GetUserImage() const = 0; virtual user::LoginStatus GetUserLoginStatus() const = 0; virtual bool IsOobeCompleted() const = 0; - // Returns a list of all logged in users. - virtual void GetLoggedInUsers(UserEmailList* users) = 0; - - // Switches to another active user (if that user has already signed in). - virtual void SwitchActiveUser(const std::string& email) = 0; - // Shows UI for changing user's profile picture. virtual void ChangeProfilePicture() = 0; diff --git a/ash/system/tray/system_tray_item.h b/ash/system/tray/system_tray_item.h index 29fdf8a..a0d7d1b 100644 --- a/ash/system/tray/system_tray_item.h +++ b/ash/system/tray/system_tray_item.h @@ -36,7 +36,7 @@ class ASH_EXPORT SystemTrayItem { // NOTE: The returned view should almost always be a TrayItemView, which // automatically resizes the widget when the size of the view changes, and // adds animation when the visibility of the view changes. If a view wants to - // avoid these behaviour, then it should not be a TrayItemView. + // avoid this behavior, then it should not be a TrayItemView. virtual views::View* CreateTrayView(user::LoginStatus status); // Returns a view for the item to be displayed in the list. This view can be diff --git a/ash/system/tray/test_system_tray_delegate.cc b/ash/system/tray/test_system_tray_delegate.cc index 10dc85c..a833f18 100644 --- a/ash/system/tray/test_system_tray_delegate.cc +++ b/ash/system/tray/test_system_tray_delegate.cc @@ -9,9 +9,7 @@ #include "ash/session_state_delegate.h" #include "ash/shell.h" #include "ash/volume_control_delegate.h" -#include "base/utf_string_conversions.h" #include "base/message_loop.h" -#include "base/string16.h" #include "base/time.h" namespace ash { @@ -74,18 +72,6 @@ bool TestSystemTrayDelegate::GetTrayVisibilityOnStartup() { } // Overridden from SystemTrayDelegate: -const base::string16 TestSystemTrayDelegate::GetUserDisplayName() const { - return UTF8ToUTF16("Über tray Über tray Über tray Über tray"); -} - -const std::string TestSystemTrayDelegate::GetUserEmail() const { - return "über@tray"; -} - -const gfx::ImageSkia& TestSystemTrayDelegate::GetUserImage() const { - return null_image_; -} - user::LoginStatus TestSystemTrayDelegate::GetUserLoginStatus() const { // At new user image screen manager->IsUserLoggedIn() would return true // but there's no browser session available yet so use SessionStarted(). @@ -105,12 +91,6 @@ bool TestSystemTrayDelegate::IsOobeCompleted() const { return true; } -void TestSystemTrayDelegate::GetLoggedInUsers(UserEmailList* users) { -} - -void TestSystemTrayDelegate::SwitchActiveUser(const std::string& email) { -} - void TestSystemTrayDelegate::ChangeProfilePicture() { } diff --git a/ash/system/tray/test_system_tray_delegate.h b/ash/system/tray/test_system_tray_delegate.h index 8dd1d34..4e44680 100644 --- a/ash/system/tray/test_system_tray_delegate.h +++ b/ash/system/tray/test_system_tray_delegate.h @@ -26,13 +26,8 @@ class TestSystemTrayDelegate : public SystemTrayDelegate { virtual bool GetTrayVisibilityOnStartup() OVERRIDE; // Overridden from SystemTrayDelegate: - virtual const base::string16 GetUserDisplayName() const OVERRIDE; - virtual const std::string GetUserEmail() const OVERRIDE; - virtual const gfx::ImageSkia& GetUserImage() const OVERRIDE; virtual user::LoginStatus GetUserLoginStatus() const OVERRIDE; virtual bool IsOobeCompleted() const OVERRIDE; - virtual void GetLoggedInUsers(UserEmailList* users) OVERRIDE; - virtual void SwitchActiveUser(const std::string& email) OVERRIDE; virtual void ChangeProfilePicture() OVERRIDE; virtual const std::string GetEnterpriseDomain() const OVERRIDE; virtual const base::string16 GetEnterpriseMessage() const OVERRIDE; @@ -124,7 +119,6 @@ class TestSystemTrayDelegate : public SystemTrayDelegate { bool cellular_enabled_; bool bluetooth_enabled_; bool caps_lock_enabled_; - gfx::ImageSkia null_image_; scoped_ptr<VolumeControlDelegate> volume_control_delegate_; DISALLOW_COPY_AND_ASSIGN(TestSystemTrayDelegate); diff --git a/ash/system/user/login_status.cc b/ash/system/user/login_status.cc index 77fc04a..acaaf08 100644 --- a/ash/system/user/login_status.cc +++ b/ash/system/user/login_status.cc @@ -4,6 +4,8 @@ #include "ash/system/user/login_status.h" +#include "ash/session_state_delegate.h" +#include "ash/shell.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "grit/ash_strings.h" @@ -26,7 +28,12 @@ base::string16 GetLocalizedSignOutStringForStatus(LoginStatus status, message_id = IDS_ASH_STATUS_TRAY_EXIT_PUBLIC; break; default: - message_id = IDS_ASH_STATUS_TRAY_SIGN_OUT; + if (ash::Shell::GetInstance()->session_state_delegate()-> + NumberOfLoggedInUsers() > 1) { + message_id = IDS_ASH_STATUS_TRAY_SIGN_OUT_ALL; + } else { + message_id = IDS_ASH_STATUS_TRAY_SIGN_OUT; + } break; } base::string16 message = diff --git a/ash/system/user/tray_user.cc b/ash/system/user/tray_user.cc index 3b4c877..1fb419d 100644 --- a/ash/system/user/tray_user.cc +++ b/ash/system/user/tray_user.cc @@ -8,6 +8,7 @@ #include <climits> #include <vector> +#include "ash/session_state_delegate.h" #include "ash/shell.h" #include "ash/shell_delegate.h" #include "ash/system/tray/system_tray.h" @@ -61,10 +62,18 @@ namespace { const int kUserDetailsVerticalPadding = 5; const int kUserCardVerticalPadding = 10; +const int kInactiveUserCardVerticalPadding = 4; const int kProfileRoundedCornerRadius = 2; const int kUserIconSize = 27; const int kUserLabelToIconPadding = 5; +// When a hover border is used, it is starting this many pixels before the icon +// position. +const int kTrayUserTileHoverBorderInset = 10; + +// The border color of the user button. +const SkColor kBorderColor = 0xffdcdcdc; + // The invisible word joiner character, used as a marker to indicate the start // and end of the user's display name in the public account user card's text. const char16 kDisplayNameMark[] = { 0x2060, 0 }; @@ -104,8 +113,9 @@ namespace tray { class RoundedImageView : public views::View { public: // Constructs a new rounded image view with rounded corners of radius - // |corner_radius|. - explicit RoundedImageView(int corner_radius); + // |corner_radius|. If |active_user| is set, the icon will be drawn in + // full colors - otherwise it will fade into the background. + RoundedImageView(int corner_radius, bool active_user); virtual ~RoundedImageView(); // Set the image that should be displayed. The image contents is copied to the @@ -122,17 +132,11 @@ class RoundedImageView : public views::View { gfx::Size image_size_; int corner_radius_; - DISALLOW_COPY_AND_ASSIGN(RoundedImageView); -}; - -class ClickableAvatar : public views::CustomButton { - public: - ClickableAvatar(views::ButtonListener* listener, - ash::user::LoginStatus login); - virtual ~ClickableAvatar(); + // True if the given user is the active user and the icon should get + // painted as active. + bool active_user_; - private: - DISALLOW_COPY_AND_ASSIGN(ClickableAvatar); + DISALLOW_COPY_AND_ASSIGN(RoundedImageView); }; // The user details shown in public account mode. This is essentially a label @@ -166,10 +170,31 @@ class PublicAccountUserDetails : public views::View, DISALLOW_COPY_AND_ASSIGN(PublicAccountUserDetails); }; +// The button which holds the user card in case of multi profile. +class UserCard : public views::CustomButton { + public: + UserCard(views::ButtonListener* listener, bool active_user); + virtual ~UserCard(); + + // Overridden from views::View + virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE; + virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE; + + private: + // Change the hover/active state of the "button". + void ShowActive(bool active); + + // True if this is the active user. + bool is_active_user_; + DISALLOW_COPY_AND_ASSIGN(UserCard); +}; + class UserView : public views::View, public views::ButtonListener { public: - explicit UserView(SystemTrayItem* owner, ash::user::LoginStatus login); + UserView(SystemTrayItem* owner, + ash::user::LoginStatus login, + MultiProfileIndex index); virtual ~UserView(); private: @@ -185,15 +210,25 @@ class UserView : public views::View, void AddLogoutButton(ash::user::LoginStatus login); void AddUserCard(SystemTrayItem* owner, ash::user::LoginStatus login); + // Create a user icon representation for the user card. + views::View* CreateIconForUserCard(ash::user::LoginStatus login); + + // Create the additional user card content for the retail logged in mode. + void AddLoggedInRetailModeUserCardContent(); + + // Create the additional user card content for the public mode. + void AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner); + + MultiProfileIndex multiprofile_index_; views::View* user_card_; views::View* logout_button_; - ClickableAvatar* profile_picture_; DISALLOW_COPY_AND_ASSIGN(UserView); }; -RoundedImageView::RoundedImageView(int corner_radius) - : corner_radius_(corner_radius) {} +RoundedImageView::RoundedImageView(int corner_radius, bool active_user) + : corner_radius_(corner_radius), + active_user_(active_user) {} RoundedImageView::~RoundedImageView() {} @@ -226,31 +261,12 @@ void RoundedImageView::OnPaint(gfx::Canvas* canvas) { path.addRoundRect(gfx::RectToSkRect(image_bounds), kRadius, kRadius); SkPaint paint; paint.setAntiAlias(true); - paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); + paint.setXfermodeMode(active_user_ ? SkXfermode::kSrcOver_Mode : + SkXfermode::kLuminosity_Mode); canvas->DrawImageInPath(resized_, image_bounds.x(), image_bounds.y(), path, paint); } -ClickableAvatar::ClickableAvatar(views::ButtonListener* listener, - ash::user::LoginStatus login) - : views::CustomButton(listener) { - SetLayoutManager(new views::FillLayout()); - RoundedImageView* user_picture = - new RoundedImageView(kProfileRoundedCornerRadius); - if (login == ash::user::LOGGED_IN_GUEST) { - user_picture->SetImage(*ui::ResourceBundle::GetSharedInstance(). - GetImageNamed(IDR_AURA_UBER_TRAY_GUEST_ICON).ToImageSkia(), - gfx::Size(kUserIconSize, kUserIconSize)); - } else { - user_picture->SetImage( - ash::Shell::GetInstance()->system_tray_delegate()->GetUserImage(), - gfx::Size(kUserIconSize, kUserIconSize)); - } - AddChildView(user_picture); -} - -ClickableAvatar::~ClickableAvatar() {} - PublicAccountUserDetails::PublicAccountUserDetails(SystemTrayItem* owner, int used_width) : learn_more_(NULL) { @@ -261,14 +277,17 @@ PublicAccountUserDetails::PublicAccountUserDetails(SystemTrayItem* owner, kUserDetailsVerticalPadding, rtl ? 0 : inner_padding, kUserDetailsVerticalPadding, rtl ? inner_padding : 0)); - ash::SystemTrayDelegate* delegate = - ash::Shell::GetInstance()->system_tray_delegate(); // Retrieve the user's display name and wrap it with markers. - base::string16 display_name = delegate->GetUserDisplayName(); + // Note that since this is a public account it always has to be the primary + // user. + base::string16 display_name = + ash::Shell::GetInstance()->session_state_delegate()-> + GetUserDisplayName(0); RemoveChars(display_name, kDisplayNameMark, &display_name); display_name = kDisplayNameMark[0] + display_name + kDisplayNameMark[0]; // Retrieve the domain managing the device and wrap it with markers. - base::string16 domain = UTF8ToUTF16(delegate->GetEnterpriseDomain()); + base::string16 domain = UTF8ToUTF16( + ash::Shell::GetInstance()->system_tray_delegate()->GetEnterpriseDomain()); RemoveChars(domain, kDisplayNameMark, &domain); base::i18n::WrapStringWithLTRFormatting(&domain); // Retrieve the label text, inserting the display name and domain. @@ -289,7 +308,7 @@ void PublicAccountUserDetails::Layout() { lines_.clear(); const gfx::Rect contents_area = GetContentsBounds(); if (contents_area.IsEmpty()) - return; + return; // Word-wrap the label text. const gfx::Font font; @@ -425,19 +444,60 @@ void PublicAccountUserDetails::CalculatePreferredSize(SystemTrayItem* owner, bubble_view->SetWidth(preferred_size_.width() + used_width); } -UserView::UserView(SystemTrayItem* owner, ash::user::LoginStatus login) - : user_card_(NULL), - logout_button_(NULL), - profile_picture_(NULL) { +UserCard::UserCard(views::ButtonListener* listener, bool active_user) + : CustomButton(listener), + is_active_user_(active_user) { + if (is_active_user_) { + set_background( + views::Background::CreateSolidBackground(kBackgroundColor)); + ShowActive(false); + } +} + +UserCard::~UserCard() {} + +void UserCard::OnMouseEntered(const ui::MouseEvent& event) { + if (is_active_user_) { + background()->SetNativeControlColor(kHoverBackgroundColor); + ShowActive(true); + SchedulePaint(); + } +} + +void UserCard::OnMouseExited(const ui::MouseEvent& event) { + if (is_active_user_) { + background()->SetNativeControlColor(kBackgroundColor); + ShowActive(false); + SchedulePaint(); + } +} + +void UserCard::ShowActive(bool active) { + int width = active ? 1 : 0; + set_border(views::Border::CreateSolidSidedBorder(width, width, width, 1, + kBorderColor)); +} + +UserView::UserView(SystemTrayItem* owner, + ash::user::LoginStatus login, + MultiProfileIndex index) + : multiprofile_index_(index), + user_card_(NULL), + logout_button_(NULL) { CHECK_NE(ash::user::LOGGED_IN_NONE, login); - set_background(views::Background::CreateSolidBackground( - login == ash::user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor : - kBackgroundColor)); + if (!index) { + // Only the logged in user will have a background. All other users will have + // to allow the TrayPopupContainer highlighting the menu line. + set_background(views::Background::CreateSolidBackground( + login == ash::user::LOGGED_IN_PUBLIC ? kPublicAccountBackgroundColor : + kBackgroundColor)); + } SetLayoutManager(new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, kTrayPopupPaddingBetweenItems)); // The logout button must be added before the user card so that the user card // can correctly calculate the remaining available width. - AddLogoutButton(login); + // Note that only the current multiprofile user gets a button. + AddLogoutButton(!multiprofile_index_ ? login : ash::user::LOGGED_IN_LOCKED); AddUserCard(owner, login); } @@ -445,10 +505,11 @@ UserView::~UserView() {} gfx::Size UserView::GetPreferredSize() { gfx::Size size = views::View::GetPreferredSize(); - // Make sure the default user view item is at least as tall as the other - // items. - size.set_height(std::max(size.height(), - kTrayPopupItemHeight + GetInsets().height())); + // Only the active user panel will be forced to a certain height. + if (!multiprofile_index_) { + size.set_height(std::max(size.height(), + kTrayPopupItemHeight + GetInsets().height())); + } return size; } @@ -463,14 +524,36 @@ void UserView::Layout() { gfx::Rect logout_area = contents_area; logout_area.ClampToCenteredSize(logout_button_->GetPreferredSize()); logout_area.set_x(contents_area.right() - logout_area.width()); - logout_button_->SetBoundsRect(logout_area); // Give the remaining space to the user card. gfx::Rect user_card_area = contents_area; - int remaining_width = contents_area.width() - - (logout_area.width() + kTrayPopupPaddingBetweenItems); - user_card_area.set_width(std::max(0, remaining_width)); + int remaining_width = contents_area.width() - logout_area.width(); + if (ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled()) { + // In multiprofile case |user_card_| and |logout_button_| have to have the + // same height. + int y = std::min(user_card_area.y(), logout_area.y()); + int height = std::max(user_card_area.height(), logout_area.height()); + logout_area.set_y(y); + logout_area.set_height(height); + user_card_area.set_y(y); + user_card_area.set_height(height); + + // In multiprofile mode we have also to increase the size of the card by + // the size of the border to make it overlap with the logout button. + user_card_area.set_width(std::max(0, remaining_width + 1)); + + // To make the logout button symmetrical with the user card we also make + // the button longer by the same size the hover area in front of the icon + // got inset. + logout_area.set_width(logout_area.width() + + kTrayUserTileHoverBorderInset); + } else { + // In all other modes we have to make sure that there is enough spacing + // between the two. + remaining_width -= kTrayPopupPaddingBetweenItems; + } user_card_->SetBoundsRect(user_card_area); + logout_button_->SetBoundsRect(logout_area); } else if (user_card_) { user_card_->SetBoundsRect(contents_area); } else if (logout_button_) { @@ -481,11 +564,29 @@ void UserView::Layout() { void UserView::ButtonPressed(views::Button* sender, const ui::Event& event) { if (sender == logout_button_) { ash::Shell::GetInstance()->system_tray_delegate()->SignOut(); - } else if (sender == profile_picture_) { - if (ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled()) - ash::Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); - else - ash::Shell::GetInstance()->system_tray_delegate()->ChangeProfilePicture(); + } else if (sender == user_card_ && + ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled()) { + if (!multiprofile_index_) { + // TODO(skuhne): Need to add the images & adding logic here. + // TODO(skuhne): Make sure that we do not offer an add when this mode is + // active. + // TODO(skuhne): Use IDS_ASH_STATUS_TRAY_SIGN_IN_ANOTHER_ACCOUNT as + // string. + const SessionStateDelegate* session_state_delegate = + ash::Shell::GetInstance()->session_state_delegate(); + if (session_state_delegate->NumberOfLoggedInUsers() >= + session_state_delegate->GetMaximumNumberOfLoggedInUsers()) { + // TODO(skuhne): Use IDS_ASH_STATUS_TRAY_CAPTION_CANNOT_ADD_USER and + // IDS_ASH_STATUS_TRAY_MESSAGE_CANNOT_ADD_USER when showing the error + // message that no more users can be added. + } else { + ash::Shell::GetInstance()->system_tray_delegate()->ShowUserLogin(); + } + } else { + ash::SessionStateDelegate* delegate = + ash::Shell::GetInstance()->session_state_delegate(); + delegate->SwitchActiveUser(delegate->GetUserEmail(multiprofile_index_)); + } } else { NOTREACHED(); } @@ -521,53 +622,74 @@ void UserView::AddLogoutButton(ash::user::LoginStatus login) { void UserView::AddUserCard(SystemTrayItem* owner, ash::user::LoginStatus login) { - set_border(views::Border::CreateEmptyBorder(0, kTrayPopupPaddingHorizontal, - 0, kTrayPopupPaddingHorizontal)); + // Add padding around the panel. + set_border(views::Border::CreateEmptyBorder( + kUserCardVerticalPadding, kTrayPopupPaddingHorizontal, + kUserCardVerticalPadding, kTrayPopupPaddingHorizontal)); + + if (ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled() && + login != ash::user::LOGGED_IN_RETAIL_MODE) { + user_card_ = new UserCard(this, multiprofile_index_ == 0); + } else { + user_card_ = new views::View(); + } - user_card_ = new views::View(); user_card_->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kHorizontal, 0, kUserCardVerticalPadding, - kTrayPopupPaddingBetweenItems)); + views::BoxLayout::kHorizontal, 0, 0 , kTrayPopupPaddingBetweenItems)); AddChildViewAt(user_card_, 0); if (login == ash::user::LOGGED_IN_RETAIL_MODE) { - views::Label* details = new views::Label; - ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - details->SetText( - bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL)); - details->set_border(views::Border::CreateEmptyBorder(0, 4, 0, 1)); - details->SetHorizontalAlignment(gfx::ALIGN_LEFT); - user_card_->AddChildView(details); + AddLoggedInRetailModeUserCardContent(); return; } - profile_picture_ = new ClickableAvatar(this, login); - user_card_->AddChildView(profile_picture_); + + // The entire user card should trigger hover (the inner items get disabled). + user_card_->SetEnabled(true); if (login == ash::user::LOGGED_IN_PUBLIC) { - user_card_->AddChildView(new PublicAccountUserDetails( - owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems)); + AddLoggedInPublicModeUserCardContent(owner); return; } - ash::SystemTrayDelegate* delegate = - ash::Shell::GetInstance()->system_tray_delegate(); + views::View* icon = CreateIconForUserCard(login); + user_card_->AddChildView(icon); + + // To allow the border to start before the icon, reduce the size before and + // add an inset to the icon to get the spacing. + if (multiprofile_index_ == 0 && + ash::Shell::GetInstance()->delegate()->IsMultiProfilesEnabled()) { + icon->set_border(views::Border::CreateEmptyBorder( + 0, kTrayUserTileHoverBorderInset, 0, 0)); + set_border(views::Border::CreateEmptyBorder( + kUserCardVerticalPadding, + kTrayPopupPaddingHorizontal - kTrayUserTileHoverBorderInset, + kUserCardVerticalPadding, + kTrayPopupPaddingHorizontal)); + } + ash::SessionStateDelegate* delegate = + ash::Shell::GetInstance()->session_state_delegate(); views::View* details = new views::View; + details->SetEnabled(false); details->SetLayoutManager(new views::BoxLayout( views::BoxLayout::kVertical, 0, kUserDetailsVerticalPadding, 0)); - + views::Label* username = NULL; ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - views::Label* username = new views::Label( - login == ash::user::LOGGED_IN_GUEST ? - bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_GUEST_LABEL) : - delegate->GetUserDisplayName()); - username->SetHorizontalAlignment(gfx::ALIGN_LEFT); - details->AddChildView(username); + if (!multiprofile_index_) { + views::Label* username = new views::Label( + login == ash::user::LOGGED_IN_GUEST ? + bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_GUEST_LABEL) : + delegate->GetUserDisplayName(multiprofile_index_)); + username->SetEnabled(false); + username->SetHorizontalAlignment(gfx::ALIGN_LEFT); + details->AddChildView(username); + } + views::Label* additional = NULL; if (login != ash::user::LOGGED_IN_GUEST) { - views::Label* additional = new views::Label(); + additional = new views::Label(); additional->SetText(login == ash::user::LOGGED_IN_LOCALLY_MANAGED ? bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_LOCALLY_MANAGED_LABEL) : - UTF8ToUTF16(delegate->GetUserEmail())); + UTF8ToUTF16(delegate->GetUserEmail(multiprofile_index_))); additional->SetFont(bundle.GetFont(ui::ResourceBundle::SmallFont)); additional->SetHorizontalAlignment(gfx::ALIGN_LEFT); @@ -575,13 +697,62 @@ void UserView::AddUserCard(SystemTrayItem* owner, details->AddChildView(additional); } + // Adjust text properties dependent on if it is an active or inactive user. + if (multiprofile_index_) { + // Fade the text of non active users to 50%. + SkColor text_color = additional->enabled_color(); + text_color = SkColorSetA(text_color, SkColorGetA(text_color) / 2); + if (additional) + additional->SetDisabledColor(text_color); + if (username) + username->SetDisabledColor(text_color); + } + + // Use a small font for email address if username exists as well. + if (username) + additional->SetFont(bundle.GetFont(ui::ResourceBundle::SmallFont)); + user_card_->AddChildView(details); } +views::View* UserView::CreateIconForUserCard(ash::user::LoginStatus login) { + RoundedImageView* icon = new RoundedImageView(kProfileRoundedCornerRadius, + multiprofile_index_ == 0); + icon->SetEnabled(false); + if (login == ash::user::LOGGED_IN_GUEST) { + icon->SetImage(*ui::ResourceBundle::GetSharedInstance(). + GetImageNamed(IDR_AURA_UBER_TRAY_GUEST_ICON).ToImageSkia(), + gfx::Size(kUserIconSize, kUserIconSize)); + } else { + icon->SetImage( + ash::Shell::GetInstance()->session_state_delegate()-> + GetUserImage(multiprofile_index_), + gfx::Size(kUserIconSize, kUserIconSize)); + } + return icon; +} + +void UserView::AddLoggedInRetailModeUserCardContent() { + views::Label* details = new views::Label; + ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); + details->SetText( + bundle.GetLocalizedString(IDS_ASH_STATUS_TRAY_KIOSK_LABEL)); + details->set_border(views::Border::CreateEmptyBorder(0, 4, 0, 1)); + details->SetHorizontalAlignment(gfx::ALIGN_LEFT); + user_card_->AddChildView(details); +} + +void UserView::AddLoggedInPublicModeUserCardContent(SystemTrayItem* owner) { + user_card_->AddChildView(CreateIconForUserCard(ash::user::LOGGED_IN_PUBLIC)); + user_card_->AddChildView(new PublicAccountUserDetails( + owner, GetPreferredSize().width() + kTrayPopupPaddingBetweenItems)); +} + } // namespace tray -TrayUser::TrayUser(SystemTray* system_tray) +TrayUser::TrayUser(SystemTray* system_tray, MultiProfileIndex index) : SystemTrayItem(system_tray), + multiprofile_index_(index), user_(NULL), layout_view_(NULL), avatar_(NULL), @@ -595,6 +766,11 @@ TrayUser::~TrayUser() { views::View* TrayUser::CreateTrayView(user::LoginStatus status) { CHECK(layout_view_ == NULL); + // Only the current user gets an icon. All other users will only be + // represented in the tray menu. + if (multiprofile_index_) + return NULL; + layout_view_ = new views::View(); layout_view_->SetLayoutManager( new views::BoxLayout(views::BoxLayout::kHorizontal, @@ -608,7 +784,24 @@ views::View* TrayUser::CreateDefaultView(user::LoginStatus status) { return NULL; CHECK(user_ == NULL); - user_ = new tray::UserView(this, status); + + const SessionStateDelegate* session_state_delegate = + ash::Shell::GetInstance()->session_state_delegate(); + int logged_in_users = session_state_delegate->NumberOfLoggedInUsers(); + + // If there are multiple users logged in, the users will be separated from the + // rest of the menu by a separator. + if (multiprofile_index_ == + session_state_delegate->GetMaximumNumberOfLoggedInUsers() && + logged_in_users > 1) { + return new views::View(); + } + + // Do not show more UserView's then there are logged in users. + if (multiprofile_index_ >= logged_in_users) + return NULL;; + + user_ = new tray::UserView(this, status, multiprofile_index_); return user_; } @@ -630,7 +823,9 @@ void TrayUser::DestroyDetailedView() { } void TrayUser::UpdateAfterLoginStatusChange(user::LoginStatus status) { - CHECK(layout_view_); + // Only the active user is represented in the tray. + if (!layout_view_) + return; bool need_label = false; bool need_avatar = false; switch (status) { @@ -664,7 +859,7 @@ void TrayUser::UpdateAfterLoginStatusChange(user::LoginStatus status) { label_ = NULL; } if (need_avatar) { - avatar_ = new tray::RoundedImageView(kProfileRoundedCornerRadius); + avatar_ = new tray::RoundedImageView(kProfileRoundedCornerRadius, true); layout_view_->AddChildView(avatar_); } else { avatar_ = NULL; @@ -684,14 +879,17 @@ void TrayUser::UpdateAfterLoginStatusChange(user::LoginStatus status) { gfx::Size(kUserIconSize, kUserIconSize)); } else { avatar_->SetImage( - ash::Shell::GetInstance()->system_tray_delegate()->GetUserImage(), + ash::Shell::GetInstance()->session_state_delegate()->GetUserImage( + multiprofile_index_), gfx::Size(kUserIconSize, kUserIconSize)); } } } void TrayUser::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) { - CHECK(layout_view_); + // Inactive users won't have a layout. + if (!layout_view_) + return; if (alignment == SHELF_ALIGNMENT_BOTTOM || alignment == SHELF_ALIGNMENT_TOP) { if (avatar_) { @@ -728,7 +926,8 @@ void TrayUser::OnUserUpdate() { // Check for null to avoid crbug.com/150944. if (avatar_) { avatar_->SetImage( - ash::Shell::GetInstance()->system_tray_delegate()->GetUserImage(), + ash::Shell::GetInstance()->session_state_delegate()->GetUserImage( + multiprofile_index_), gfx::Size(kUserIconSize, kUserIconSize)); } } diff --git a/ash/system/user/tray_user.h b/ash/system/user/tray_user.h index 340ab2d..69ad224 100644 --- a/ash/system/user/tray_user.h +++ b/ash/system/user/tray_user.h @@ -5,6 +5,7 @@ #ifndef ASH_SYSTEM_USER_TRAY_USER_H_ #define ASH_SYSTEM_USER_TRAY_USER_H_ +#include "ash/session_state_delegate.h" #include "ash/system/tray/system_tray_item.h" #include "ash/system/user/user_observer.h" #include "base/compiler_specific.h" @@ -25,7 +26,11 @@ class RoundedImageView; class TrayUser : public SystemTrayItem, public UserObserver { public: - explicit TrayUser(SystemTray* system_tray); + // The given |multiprofile_index| is the number of the user in a multi profile + // scenario. Index #0 is the running user, the other indices are other + // logged in users (if there are any). Only index #0 will add an icon to + // the system tray. + TrayUser(SystemTray* system_tray, MultiProfileIndex index); virtual ~TrayUser(); private: @@ -43,6 +48,9 @@ class TrayUser : public SystemTrayItem, // Overridden from UserObserver. virtual void OnUserUpdate() OVERRIDE; + // The user index to use. + MultiProfileIndex multiprofile_index_; + tray::UserView* user_; // View that contains label and/or avatar. diff --git a/ash/test/test_session_state_delegate.cc b/ash/test/test_session_state_delegate.cc index 881f4982..2cff17e 100644 --- a/ash/test/test_session_state_delegate.cc +++ b/ash/test/test_session_state_delegate.cc @@ -4,6 +4,9 @@ #include "ash/test/test_session_state_delegate.h" +#include "base/string16.h" +#include "base/utf_string_conversions.h" + namespace ash { namespace test { @@ -17,8 +20,13 @@ TestSessionStateDelegate::TestSessionStateDelegate() TestSessionStateDelegate::~TestSessionStateDelegate() { } -bool TestSessionStateDelegate::HasActiveUser() const { - return has_active_user_; +int TestSessionStateDelegate::GetMaximumNumberOfLoggedInUsers() const { + return 3; +} + +int TestSessionStateDelegate::NumberOfLoggedInUsers() const { + // TODO(skuhne): Add better test framework to test multiple profiles. + return has_active_user_ ? 1 : 0; } bool TestSessionStateDelegate::IsActiveUserSessionStarted() const { @@ -59,5 +67,27 @@ void TestSessionStateDelegate::SetCanLockScreen(bool can_lock_screen) { can_lock_screen_ = can_lock_screen; } +const base::string16 TestSessionStateDelegate::GetUserDisplayName( + ash::MultiProfileIndex index) const { + return UTF8ToUTF16("Über tray Über tray Über tray Über tray"); +} + +const std::string TestSessionStateDelegate::GetUserEmail( + ash::MultiProfileIndex index) const { + return "über@tray"; +} + +const gfx::ImageSkia& TestSessionStateDelegate::GetUserImage( + ash::MultiProfileIndex index) const { + return null_image_; +} + +void TestSessionStateDelegate::GetLoggedInUsers(UserEmailList* users) { +} + +void TestSessionStateDelegate::SwitchActiveUser(const std::string& email) { +} + + } // namespace test } // namespace ash diff --git a/ash/test/test_session_state_delegate.h b/ash/test/test_session_state_delegate.h index 807e335..d91bd94 100644 --- a/ash/test/test_session_state_delegate.h +++ b/ash/test/test_session_state_delegate.h @@ -8,6 +8,7 @@ #include "ash/session_state_delegate.h" #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "ui/gfx/image/image_skia.h" namespace ash { namespace test { @@ -18,12 +19,21 @@ class TestSessionStateDelegate : public SessionStateDelegate { virtual ~TestSessionStateDelegate(); // SessionStateDelegate: - virtual bool HasActiveUser() const OVERRIDE; + virtual int GetMaximumNumberOfLoggedInUsers() const OVERRIDE; + virtual int NumberOfLoggedInUsers() const OVERRIDE; virtual bool IsActiveUserSessionStarted() const OVERRIDE; virtual bool CanLockScreen() const OVERRIDE; virtual bool IsScreenLocked() const OVERRIDE; virtual void LockScreen() OVERRIDE; virtual void UnlockScreen() OVERRIDE; + virtual const base::string16 GetUserDisplayName( + ash::MultiProfileIndex index) const OVERRIDE; + virtual const std::string GetUserEmail( + ash::MultiProfileIndex index) const OVERRIDE; + virtual const gfx::ImageSkia& GetUserImage( + ash::MultiProfileIndex index) const OVERRIDE; + virtual void GetLoggedInUsers(UserEmailList* users) OVERRIDE; + virtual void SwitchActiveUser(const std::string& email) OVERRIDE; // Updates the internal state that indicates whether a session is in progress // and there is an active user. If |has_active_user| is |false|, @@ -58,6 +68,9 @@ class TestSessionStateDelegate : public SessionStateDelegate { // Whether the screen is currently locked. bool screen_locked_; + // A test user image. + gfx::ImageSkia null_image_; + DISALLOW_COPY_AND_ASSIGN(TestSessionStateDelegate); }; diff --git a/ash/wm/gestures/shelf_gesture_handler.cc b/ash/wm/gestures/shelf_gesture_handler.cc index 847820d..aba69fd 100644 --- a/ash/wm/gestures/shelf_gesture_handler.cc +++ b/ash/wm/gestures/shelf_gesture_handler.cc @@ -31,7 +31,7 @@ ShelfGestureHandler::~ShelfGestureHandler() { bool ShelfGestureHandler::ProcessGestureEvent(const ui::GestureEvent& event) { Shell* shell = Shell::GetInstance(); - if (!shell->session_state_delegate()->HasActiveUser() || + if (!shell->session_state_delegate()->NumberOfLoggedInUsers() || shell->session_state_delegate()->IsScreenLocked()) { // The gestures are disabled in the lock/login screen. return false; |