1 // Copyright (c) 2012 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 #ifndef ASH_TEST_ASH_TEST_BASE_H_
6 #define ASH_TEST_ASH_TEST_BASE_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <utility>
13 
14 #include "ash/public/cpp/app_types.h"
15 #include "ash/public/cpp/shell_window_ids.h"
16 #include "ash/session/test_session_controller_client.h"
17 #include "ash/wm/desks/desks_util.h"
18 #include "base/compiler_specific.h"
19 #include "base/macros.h"
20 #include "base/test/task_environment.h"
21 #include "base/threading/thread.h"
22 #include "base/traits_bag.h"
23 #include "components/prefs/testing_pref_service.h"
24 #include "components/user_manager/user_type.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "third_party/skia/include/core/SkColor.h"
27 #include "ui/aura/client/window_types.h"
28 #include "ui/aura/env.h"
29 #include "ui/display/display.h"
30 #include "ui/events/test/event_generator.h"
31 
32 namespace aura {
33 class Window;
34 class WindowDelegate;
35 }  // namespace aura
36 
37 namespace base {
38 namespace test {
39 class TaskEnvironment;
40 }
41 }  // namespace base
42 
43 namespace chromeos {
44 class FakePowerManagerClient;
45 }
46 
47 namespace display {
48 class Display;
49 class DisplayManager;
50 
51 namespace test {
52 class DisplayManagerTestApi;
53 }  // namespace test
54 }  // namespace display
55 
56 namespace gfx {
57 class Rect;
58 }
59 
60 namespace views {
61 class View;
62 class Widget;
63 class WidgetDelegate;
64 }  // namespace views
65 
66 namespace ash {
67 
68 class AmbientAshTestHelper;
69 class AppListTestHelper;
70 class AshTestHelper;
71 class Shelf;
72 class TestScreenshotDelegate;
73 class TestShellDelegate;
74 class TestSystemTrayClient;
75 class UnifiedSystemTray;
76 class WorkAreaInsets;
77 
78 class AshTestBase : public testing::Test {
79  public:
80   // Constructs an AshTestBase with |traits| being forwarded to its
81   // TaskEnvironment. MainThreadType always defaults to UI and must not be
82   // specified.
83   template <typename... TaskEnvironmentTraits>
AshTestBase(TaskEnvironmentTraits &&...traits)84   NOINLINE explicit AshTestBase(TaskEnvironmentTraits&&... traits)
85       : AshTestBase(std::make_unique<base::test::TaskEnvironment>(
86             base::test::TaskEnvironment::MainThreadType::UI,
87             std::forward<TaskEnvironmentTraits>(traits)...)) {}
88 
89   // Alternatively a subclass may pass a TaskEnvironment directly.
90   explicit AshTestBase(
91       std::unique_ptr<base::test::TaskEnvironment> task_environment);
92 
93   ~AshTestBase() override;
94 
95   // testing::Test:
96   void SetUp() override;
97   void SetUp(std::unique_ptr<TestShellDelegate> delegate);
98   void TearDown() override;
99 
100   // Returns the Shelf for the primary display.
101   static Shelf* GetPrimaryShelf();
102 
103   // Returns the unified system tray on the primary display.
104   static UnifiedSystemTray* GetPrimaryUnifiedSystemTray();
105 
106   // Returns WorkAreaInsets for the primary display.
107   static WorkAreaInsets* GetPrimaryWorkAreaInsets();
108 
109   // Update the display configuration as given in |display_specs|.
110   // See ash::DisplayManagerTestApi::UpdateDisplay for more details.
111   void UpdateDisplay(const std::string& display_specs);
112 
113   // Returns a root Window. Usually this is the active root Window, but that
114   // method can return NULL sometimes, and in those cases, we fall back on the
115   // primary root Window.
116   aura::Window* GetContext();
117 
118   // Creates and shows a widget. See ash/public/cpp/shell_window_ids.h for
119   // values for |container_id|.
120   static std::unique_ptr<views::Widget> CreateTestWidget(
121       views::WidgetDelegate* delegate = nullptr,
122       int container_id = desks_util::GetActiveDeskContainerId(),
123       const gfx::Rect& bounds = gfx::Rect(),
124       bool show = true);
125 
126   // Creates a widget with a visible WINDOW_TYPE_NORMAL window with the given
127   // |app_type|. If |app_type| is AppType::NON_APP, this window is considered a
128   // non-app window.
129   // If |bounds_in_screen| is empty the window is added to the primary root
130   // window, otherwise the window is added to the display matching
131   // |bounds_in_screen|. |shell_window_id| is the shell window id to give to
132   // the new window.
133   std::unique_ptr<aura::Window> CreateAppWindow(
134       const gfx::Rect& bounds_in_screen = gfx::Rect(),
135       AppType app_type = AppType::SYSTEM_APP,
136       int shell_window_id = kShellWindowId_Invalid);
137 
138   // Creates a visible window in the appropriate container. If
139   // |bounds_in_screen| is empty the window is added to the primary root
140   // window, otherwise the window is added to the display matching
141   // |bounds_in_screen|. |shell_window_id| is the shell window id to give to
142   // the new window.
143   // If |type| is WINDOW_TYPE_NORMAL this creates a views::Widget, otherwise
144   // this creates an aura::Window.
145   std::unique_ptr<aura::Window> CreateTestWindow(
146       const gfx::Rect& bounds_in_screen = gfx::Rect(),
147       aura::client::WindowType type = aura::client::WINDOW_TYPE_NORMAL,
148       int shell_window_id = kShellWindowId_Invalid);
149 
150   // Creates a visible top-level window with a delegate.
151   std::unique_ptr<aura::Window> CreateToplevelTestWindow(
152       const gfx::Rect& bounds_in_screen = gfx::Rect(),
153       int shell_window_id = kShellWindowId_Invalid);
154 
155   // Versions of the functions in aura::test:: that go through our shell
156   // StackingController instead of taking a parent.
157   aura::Window* CreateTestWindowInShellWithId(int id);
158   aura::Window* CreateTestWindowInShellWithBounds(const gfx::Rect& bounds);
159   aura::Window* CreateTestWindowInShell(SkColor color,
160                                         int id,
161                                         const gfx::Rect& bounds);
162 
163   // Creates a visible window parented to |parent| with the specified bounds and
164   // id.
165   std::unique_ptr<aura::Window> CreateChildWindow(
166       aura::Window* parent,
167       const gfx::Rect& bounds = gfx::Rect(),
168       int shell_window_id = kShellWindowId_Invalid);
169 
170   aura::Window* CreateTestWindowInShellWithDelegate(
171       aura::WindowDelegate* delegate,
172       int id,
173       const gfx::Rect& bounds);
174   aura::Window* CreateTestWindowInShellWithDelegateAndType(
175       aura::WindowDelegate* delegate,
176       aura::client::WindowType type,
177       int id,
178       const gfx::Rect& bounds);
179 
180   // Attach |window| to the current shell's root window.
181   void ParentWindowInPrimaryRootWindow(aura::Window* window);
182 
183   // Returns the EventGenerator that uses screen coordinates and works
184   // across multiple displays. It creates a new generator if it
185   // hasn't been created yet.
186   ui::test::EventGenerator* GetEventGenerator();
187 
188   // Convenience method to return the DisplayManager.
189   display::DisplayManager* display_manager();
190 
191   // Convenience method to return the FakePowerManagerClient.
192   chromeos::FakePowerManagerClient* power_manager_client() const;
193 
194   // Test if moving a mouse to |point_in_screen| warps it to another
195   // display.
196   bool TestIfMouseWarpsAt(ui::test::EventGenerator* event_generator,
197                           const gfx::Point& point_in_screen);
198 
199   // Moves the mouse to the center of the view and generates a left button click
200   // event.
201   void SimulateMouseClickAt(ui::test::EventGenerator* event_generator,
202                             const views::View* target_view);
203 
204  protected:
205   enum UserSessionBlockReason {
206     FIRST_BLOCK_REASON,
207     BLOCKED_BY_LOCK_SCREEN = FIRST_BLOCK_REASON,
208     BLOCKED_BY_LOGIN_SCREEN,
209     BLOCKED_BY_USER_ADDING_SCREEN,
210     NUMBER_OF_BLOCK_REASONS
211   };
212 
213   // Returns the rotation currentl active for the display |id|.
214   static display::Display::Rotation GetActiveDisplayRotation(int64_t id);
215 
216   // Returns the rotation currently active for the internal display.
217   static display::Display::Rotation GetCurrentInternalDisplayRotation();
218 
set_start_session(bool start_session)219   void set_start_session(bool start_session) { start_session_ = start_session; }
220 
task_environment()221   base::test::TaskEnvironment* task_environment() {
222     return task_environment_.get();
223   }
local_state()224   TestingPrefServiceSimple* local_state() { return &local_state_; }
ash_test_helper()225   AshTestHelper* ash_test_helper() { return ash_test_helper_.get(); }
226 
227   void SetUserPref(const std::string& user_email,
228                    const std::string& path,
229                    const base::Value& value);
230 
231   TestScreenshotDelegate* GetScreenshotDelegate();
232 
233   TestSessionControllerClient* GetSessionControllerClient();
234 
235   TestSystemTrayClient* GetSystemTrayClient();
236 
237   AppListTestHelper* GetAppListTestHelper();
238 
239   AmbientAshTestHelper* GetAmbientAshTestHelper();
240 
241   // Emulates an ash session that have |session_count| user sessions running.
242   // Note that existing user sessions will be cleared.
243   void CreateUserSessions(int session_count);
244 
245   // Simulates a user sign-in. It creates a new user session, adds it to
246   // existing user sessions and makes it the active user session.
247   void SimulateUserLogin(
248       const std::string& user_email,
249       user_manager::UserType user_type = user_manager::USER_TYPE_REGULAR);
250 
251   // Simular to SimulateUserLogin but for a newly created user first ever login.
252   void SimulateNewUserFirstLogin(const std::string& user_email);
253 
254   // Similar to SimulateUserLogin but for a guest user.
255   void SimulateGuestLogin();
256 
257   // Simulates kiosk mode. |user_type| must correlate to a kiosk type user.
258   void SimulateKioskMode(user_manager::UserType user_type);
259 
260   // Simulates setting height of the accessibility panel.
261   // Note: Accessibility panel widget needs to be setup first.
262   void SetAccessibilityPanelHeight(int panel_height);
263 
264   // Clears all user sessions and resets to the primary login screen state.
265   void ClearLogin();
266 
267   // Emulates whether the active user can lock screen.
268   void SetCanLockScreen(bool can_lock);
269 
270   // Emulates whether the screen should be locked automatically.
271   void SetShouldLockScreenAutomatically(bool should_lock);
272 
273   // Emulates whether the user adding screen is running.
274   void SetUserAddingScreenRunning(bool user_adding_screen_running);
275 
276   // Methods to emulate blocking and unblocking user session with given
277   // |block_reason|.
278   void BlockUserSession(UserSessionBlockReason block_reason);
279   void UnblockUserSession();
280 
281   // Enable or disable the virtual on-screen keyboard and run the message loop
282   // to allow observer operations to complete.
283   void SetVirtualKeyboardEnabled(bool enabled);
284 
285   void DisableIME();
286 
287   // Swap the primary display with the secondary.
288   void SwapPrimaryDisplay();
289 
290   display::Display GetPrimaryDisplay() const;
291   display::Display GetSecondaryDisplay() const;
292 
293  private:
294   void CreateWindowTreeIfNecessary();
295 
296   bool setup_called_ = false;
297   bool teardown_called_ = false;
298 
299   // SetUp() doesn't activate session if this is set to false.
300   bool start_session_ = true;
301 
302   // |task_environment_| is initialized-once at construction time but
303   // subclasses may elect to provide their own.
304   std::unique_ptr<base::test::TaskEnvironment> task_environment_;
305 
306   // A pref service used for local state.
307   TestingPrefServiceSimple local_state_;
308 
309   // Must be constructed after |task_environment_|.
310   std::unique_ptr<AshTestHelper> ash_test_helper_;
311 
312   std::unique_ptr<ui::test::EventGenerator> event_generator_;
313 
314   DISALLOW_COPY_AND_ASSIGN(AshTestBase);
315 };
316 
317 class NoSessionAshTestBase : public AshTestBase {
318  public:
NoSessionAshTestBase()319   NoSessionAshTestBase() { set_start_session(false); }
~NoSessionAshTestBase()320   ~NoSessionAshTestBase() override {}
321 
322  private:
323   DISALLOW_COPY_AND_ASSIGN(NoSessionAshTestBase);
324 };
325 
326 }  // namespace ash
327 
328 #endif  // ASH_TEST_ASH_TEST_BASE_H_
329