diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.cc b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.cc new file mode 100644 index 00000000000000..4b39f9385a9357 --- /dev/null +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.cc @@ -0,0 +1,96 @@ +// Copyright 2015 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 "chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.h" + +#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" +#include "chrome/browser/ui/browser_window.h" +#include "ui/aura/window.h" + +TestMultiUserWindowManager::TestMultiUserWindowManager( + Browser* visiting_browser, + const std::string& desktop_owner) + : browser_window_(visiting_browser->window()->GetNativeWindow()), + browser_owner_( + multi_user_util::GetUserIDFromProfile(visiting_browser->profile())), + desktop_owner_(desktop_owner), + created_window_(NULL), + created_window_shown_for_(browser_owner_), + current_user_id_(desktop_owner) { + // Register this object with the system (which will take ownership). It will + // be deleted by ChromeLauncherController::~ChromeLauncherController(). + chrome::MultiUserWindowManager::SetInstanceForTest( + this, chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED); +} + +TestMultiUserWindowManager::~TestMultiUserWindowManager() { + // This object is owned by the MultiUserWindowManager since the + // SetInstanceForTest call. As such no uninstall is required. +} + +void TestMultiUserWindowManager::SetWindowOwner(aura::Window* window, + const std::string& user_id) { + NOTREACHED(); +} + +const std::string& TestMultiUserWindowManager::GetWindowOwner( + aura::Window* window) const { + // No matter which window will get queried - all browsers belong to the + // original browser's user. + return browser_owner_; +} + +void TestMultiUserWindowManager::ShowWindowForUser(aura::Window* window, + const std::string& user_id) { + // This class is only able to handle one additional window <-> user + // association beside the creation parameters. + // If no association has yet been requested remember it now. + DCHECK(!created_window_); + created_window_ = window; + created_window_shown_for_ = user_id; + + if (browser_window_ == window) + desktop_owner_ = user_id; + + if (user_id == current_user_id_) + return; + + // Change the visibility of the window to update the view recursively. + window->Hide(); + window->Show(); + current_user_id_ = user_id; +} + +bool TestMultiUserWindowManager::AreWindowsSharedAmongUsers() const { + return browser_owner_ != desktop_owner_; +} + +void TestMultiUserWindowManager::GetOwnersOfVisibleWindows( + std::set* user_ids) const { +} + +bool TestMultiUserWindowManager::IsWindowOnDesktopOfUser( + aura::Window* window, + const std::string& user_id) const { + return GetUserPresentingWindow(window) == user_id; +} + +const std::string& TestMultiUserWindowManager::GetUserPresentingWindow( + aura::Window* window) const { + if (window == browser_window_) + return desktop_owner_; + if (created_window_ && window == created_window_) + return created_window_shown_for_; + // We can come here before the window gets registered. + return browser_owner_; +} + +void TestMultiUserWindowManager::AddUser(content::BrowserContext* profile) { +} + +void TestMultiUserWindowManager::AddObserver(Observer* observer) { +} + +void TestMultiUserWindowManager::RemoveObserver(Observer* observer) { +} diff --git a/chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.h b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.h new file mode 100644 index 00000000000000..c0f89fffa5a3f5 --- /dev/null +++ b/chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.h @@ -0,0 +1,58 @@ +// Copyright 2015 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 CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_TEST_H_ +#define CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_TEST_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" + +// This is a test implementation of a MultiUserWindowManager which allows to +// test a visiting window on another desktop. It will install and remove itself +// from the system upon creation / destruction. +// The creation function gets a |browser| which is shown on |desktop_owner|'s +// desktop. +class TestMultiUserWindowManager : public chrome::MultiUserWindowManager { + public: + TestMultiUserWindowManager(Browser* visiting_browser, + const std::string& desktop_owner); + ~TestMultiUserWindowManager() override; + + aura::Window* created_window() { return created_window_; } + + // MultiUserWindowManager overrides: + void SetWindowOwner(aura::Window* window, + const std::string& user_id) override; + const std::string& GetWindowOwner(aura::Window* window) const override; + void ShowWindowForUser(aura::Window* window, + const std::string& user_id) override; + bool AreWindowsSharedAmongUsers() const override; + void GetOwnersOfVisibleWindows( + std::set* user_ids) const override; + bool IsWindowOnDesktopOfUser(aura::Window* window, + const std::string& user_id) const override; + const std::string& GetUserPresentingWindow( + aura::Window* window) const override; + void AddUser(content::BrowserContext* profile) override; + void AddObserver(Observer* observer) override; + void RemoveObserver(Observer* observer) override; + + private: + // The window of the visiting browser. + aura::Window* browser_window_; + // The owner of the visiting browser. + std::string browser_owner_; + // The owner of the currently shown desktop. + std::string desktop_owner_; + // The created window. + aura::Window* created_window_; + // The location of the window. + std::string created_window_shown_for_; + // The current selected active user. + std::string current_user_id_; + + DISALLOW_COPY_AND_ASSIGN(TestMultiUserWindowManager); +}; + +#endif // CHROME_BROWSER_UI_ASH_MULTI_USER_MULTI_USER_WINDOW_MANAGER_TEST_H_ diff --git a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc index 80f7a17d8bef5b..025f9ead3893c4 100644 --- a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc +++ b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc @@ -1,19 +1,16 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 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 "chrome/browser/ui/browser_navigator_browsertest.h" -#include - #include "base/command_line.h" #include "chrome/browser/chromeos/login/chrome_restart_request.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator.h" -#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chromeos/chromeos_switches.h" @@ -21,131 +18,6 @@ namespace { -// This is a test implementation of a MultiUserWindowManager which allows to -// test a visiting window on another desktop. It will install and remove itself -// from the system upon creation / destruction. -// The creation function gets a |browser| which is shown on |desktop_owner|'s -// desktop. -class TestMultiUserWindowManager : public chrome::MultiUserWindowManager { - public: - TestMultiUserWindowManager( - Browser* visiting_browser, - const std::string& desktop_owner); - virtual ~TestMultiUserWindowManager(); - - aura::Window* created_window() { return created_window_; } - - // MultiUserWindowManager overrides: - virtual void SetWindowOwner( - aura::Window* window, const std::string& user_id) override; - virtual const std::string& GetWindowOwner( - aura::Window* window) const override; - virtual void ShowWindowForUser( - aura::Window* window, const std::string& user_id) override; - virtual bool AreWindowsSharedAmongUsers() const override; - virtual void GetOwnersOfVisibleWindows( - std::set* user_ids) const override; - virtual bool IsWindowOnDesktopOfUser( - aura::Window* window, - const std::string& user_id) const override; - virtual const std::string& GetUserPresentingWindow( - aura::Window* window) const override; - virtual void AddUser(content::BrowserContext* profile) override; - virtual void AddObserver(Observer* observer) override; - virtual void RemoveObserver(Observer* observer) override; - - private: - // The window of the visiting browser. - aura::Window* browser_window_; - // The owner of the visiting browser. - std::string browser_owner_; - // The owner of the currently shown desktop. - std::string desktop_owner_; - // The created window. - aura::Window* created_window_; - // The location of the window. - std::string created_window_shown_for_; - - DISALLOW_COPY_AND_ASSIGN(TestMultiUserWindowManager); -}; - -TestMultiUserWindowManager::TestMultiUserWindowManager( - Browser* visiting_browser, - const std::string& desktop_owner) - : browser_window_(visiting_browser->window()->GetNativeWindow()), - browser_owner_(multi_user_util::GetUserIDFromProfile( - visiting_browser->profile())), - desktop_owner_(desktop_owner), - created_window_(NULL), - created_window_shown_for_(browser_owner_) { - // Create a window manager for a visiting user. - chrome::MultiUserWindowManager::SetInstanceForTest( - this, - chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED); -} - -TestMultiUserWindowManager::~TestMultiUserWindowManager() { - // This object is owned by the MultiUserWindowManager since the - // SetInstanceForTest call. As such no uninstall is required. -} - -// MultiUserWindowManager overrides: -void TestMultiUserWindowManager::SetWindowOwner( - aura::Window* window, const std::string& user_id) { - NOTREACHED(); -} - -const std::string& TestMultiUserWindowManager::GetWindowOwner( - aura::Window* window) const { - // No matter which window will get queried - all browsers belong to the - // original browser's user. - return browser_owner_; -} - -void TestMultiUserWindowManager::ShowWindowForUser( - aura::Window* window, - const std::string& user_id) { - // This class is only able to handle one additional window <-> user - // association beside the creation parameters. - // If no association has yet been requested remember it now. - DCHECK(!created_window_); - created_window_ = window; - created_window_shown_for_ = user_id; -} - -bool TestMultiUserWindowManager::AreWindowsSharedAmongUsers() const { - return browser_owner_ != desktop_owner_; -} - -void TestMultiUserWindowManager::GetOwnersOfVisibleWindows( - std::set* user_ids) const { -} - -bool TestMultiUserWindowManager::IsWindowOnDesktopOfUser( - aura::Window* window, - const std::string& user_id) const { - return GetUserPresentingWindow(window) == user_id; -} - -const std::string& TestMultiUserWindowManager::GetUserPresentingWindow( - aura::Window* window) const { - if (window == browser_window_) - return desktop_owner_; - if (created_window_ && window == created_window_) - return created_window_shown_for_; - // We can come here before the window gets registered. - return browser_owner_; -} - -void TestMultiUserWindowManager::AddUser(content::BrowserContext* profile) { -} - -void TestMultiUserWindowManager::AddObserver(Observer* observer) { -} - -void TestMultiUserWindowManager::RemoveObserver(Observer* observer) { -} - GURL GetGoogleURL() { return GURL("http://www.google.com/"); } diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc index e0cca4f37ed1b2..98d7efff722c49 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 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. @@ -13,6 +13,7 @@ #include "ash/shell.h" #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/extensions/extension_util.h" +#include "chrome/browser/profiles/profiles_state.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -246,7 +247,15 @@ int BrowserNonClientFrameViewAsh::NonClientHitTest(const gfx::Point& point) { // See if the point is actually within either of the avatar menu buttons. if (hit_test == HTCAPTION && avatar_button() && ConvertedHitTest(this, avatar_button(), point)) { +#if defined(OS_CHROMEOS) + // In ChromeOS, a browser window which has an avatar badging on the top + // left corner means it's a teleported browser window. We should treat the + // avatar as part of the browser non client frame (e.g., clicking on it + // allows the user to drag the browser window around.) + return HTCAPTION; +#else return HTCLIENT; +#endif } if (hit_test == HTCAPTION && new_avatar_button() && diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc index e862fc4a37df73..6b8e35dc720f67 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash_browsertest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright 2012 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. @@ -23,6 +23,13 @@ #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/views/widget/widget.h" +#if defined(OS_CHROMEOS) +#include "chrome/browser/profiles/profile_avatar_icon_util.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" +#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_test.h" +#include "chrome/browser/ui/views/profiles/avatar_menu_button.h" +#endif // defined(OS_CHROMEOS) + using views::Widget; typedef InProcessBrowserTest BrowserNonClientFrameViewAshTest; @@ -197,6 +204,62 @@ IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, ImmersiveFullscreen) { EXPECT_LT(Tab::GetImmersiveHeight(), frame_view->header_painter_->GetHeaderHeightForPainting()); } + +// Tests that Avatar icon should show on the top left corner of the teleported +// browser window on ChromeOS. +IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, + AvatarDisplayOnTeleportedWindow) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + Widget* widget = browser_view->GetWidget(); + // We know we're using Ash, so static cast. + BrowserNonClientFrameViewAsh* frame_view = + static_cast( + widget->non_client_view()->frame_view()); + aura::Window* window = browser()->window()->GetNativeWindow(); + + EXPECT_FALSE(chrome::MultiUserWindowManager::ShouldShowAvatar(window)); + + const std::string current_user = + multi_user_util::GetUserIDFromProfile(browser()->profile()); + TestMultiUserWindowManager* manager = + new TestMultiUserWindowManager(browser(), current_user); + + // Teleport the window to another desktop. + const std::string user2 = "user2"; + manager->ShowWindowForUser(window, user2); + EXPECT_TRUE(chrome::MultiUserWindowManager::ShouldShowAvatar(window)); + + // Avatar should show on the top left corner of the teleported browser window. + EXPECT_TRUE(frame_view->avatar_button()); +} + +// Hit Test for Avatar Menu Button on ChromeOS. +IN_PROC_BROWSER_TEST_F(BrowserNonClientFrameViewAshTest, + AvatarMenuButtonHitTestOnChromeOS) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); + Widget* widget = browser_view->GetWidget(); + // We know we're using Ash, so static cast. + BrowserNonClientFrameViewAsh* frame_view = + static_cast( + widget->non_client_view()->frame_view()); + + gfx::Point avatar_center(profiles::kAvatarIconWidth / 2, + profiles::kAvatarIconHeight / 2); + EXPECT_EQ(HTCLIENT, frame_view->NonClientHitTest(avatar_center)); + + const std::string current_user = + multi_user_util::GetUserIDFromProfile(browser()->profile()); + TestMultiUserWindowManager* manager = + new TestMultiUserWindowManager(browser(), current_user); + + // Teleport the window to another desktop. + const std::string user2 = "user2"; + manager->ShowWindowForUser(browser()->window()->GetNativeWindow(), user2); + // Clicking on the avatar icon should have same behaviour like clicking on + // the caption area, i.e., allow the user to drag the browser window around. + EXPECT_EQ(HTCAPTION, frame_view->NonClientHitTest(avatar_center)); +} + #endif // defined(OS_CHROMEOS) // Tests that FrameCaptionButtonContainer has been relaid out in response to diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 020c19c5f22904..5390ccd1f64fac 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -420,6 +420,8 @@ 'browser/ui/ash/launcher/chrome_launcher_controller_browsertest.cc', 'browser/ui/ash/launcher/launcher_favicon_loader_browsertest.cc', 'browser/ui/ash/keyboard_controller_browsertest.cc', + 'browser/ui/ash/multi_user/multi_user_window_manager_test.cc', + 'browser/ui/ash/multi_user/multi_user_window_manager_test.h', 'browser/ui/ash/system_tray_delegate_chromeos_browsertest_chromeos.cc', 'browser/ui/ash/shelf_browsertest.cc', 'browser/ui/ash/volume_controller_browsertest_chromeos.cc',