• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_STATE_TEST_H_
6 #define CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_STATE_TEST_H_
7 
8 #include <sstream>
9 
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "build/build_config.h"
14 
15 class Browser;
16 class FullscreenController;
17 class FullscreenNotificationObserver;
18 
19 // Utility definition for mapping enum values to strings in switch statements.
20 #define ENUM_TO_STRING(enum) case enum: return #enum
21 
22 // Test fixture used to test Fullscreen Controller through exhaustive sequences
23 // of events in unit and interactive tests.
24 //
25 // Because operating system window managers are too unreliable (they result in
26 // flakiness at around 1 out of 1000 runs) this fixture is designed to be run
27 // on testing infrastructure in unit tests mocking out the platforms' behavior.
28 // To verify that behavior interactive tests exist but are left disabled and
29 // only run manually when verifying the consistency of the
30 // FullscreenControllerTestWindow.
31 class FullscreenControllerStateTest {
32  public:
33   // Events names for FullscreenController methods.
34   enum Event {
35     TOGGLE_FULLSCREEN,         // ToggleBrowserFullscreenMode()
36     TOGGLE_FULLSCREEN_CHROME,  // ToggleBrowserFullscreenWithChrome()
37     TAB_FULLSCREEN_TRUE,       // ToggleFullscreenModeForTab(, true)
38     TAB_FULLSCREEN_FALSE,      // ToggleFullscreenModeForTab(, false)
39     METRO_SNAP_TRUE,           // SetMetroSnapMode(true)
40     METRO_SNAP_FALSE,          // SetMetroSnapMode(false)
41     BUBBLE_EXIT_LINK,          // ExitTabOrBrowserFullscreenToPreviousState()
42     BUBBLE_ALLOW,              // OnAcceptFullscreenPermission()
43     BUBBLE_DENY,               // OnDenyFullscreenPermission()
44     WINDOW_CHANGE,             // ChangeWindowFullscreenState()
45     NUM_EVENTS,
46     EVENT_INVALID,
47   };
48 
49   // Conceptual states of the Fullscreen Controller, these do not correspond
50   // to particular implemenation details.
51   enum State {
52     // The window is not in fullscreen.
53     STATE_NORMAL,
54     // User-initiated fullscreen.
55     STATE_BROWSER_FULLSCREEN_NO_CHROME,
56     // Mac User-initiated 'Lion Fullscreen' with browser chrome. OSX 10.7+ only.
57     STATE_BROWSER_FULLSCREEN_WITH_CHROME,
58     // Windows 8 Metro Snap mode, which puts the window at 20% screen-width.
59     // No TO_ state for Metro, as the windows implementation is only reentrant.
60     STATE_METRO_SNAP,
61     // HTML5 tab-initiated fullscreen.
62     STATE_TAB_FULLSCREEN,
63     // Both tab and browser fullscreen.
64     STATE_TAB_BROWSER_FULLSCREEN,
65     // Both tab and browser fullscreen, displayed without chrome, but exits tab
66     // fullscreen to STATE_BROWSER_FULLSCREEN_WITH_CHROME.
67     STATE_TAB_BROWSER_FULLSCREEN_CHROME,
68     // TO_ states are asynchronous states waiting for window state change
69     // before transitioning to their named state.
70     STATE_TO_NORMAL,
71     STATE_TO_BROWSER_FULLSCREEN_NO_CHROME,
72     STATE_TO_BROWSER_FULLSCREEN_WITH_CHROME,
73     STATE_TO_TAB_FULLSCREEN,
74     NUM_STATES,
75     STATE_INVALID,
76   };
77 
78   static const int kMaxStateNameLength = 39;
79   static const int kMaxEventNameLength = 24;
80 
81   FullscreenControllerStateTest();
82   virtual ~FullscreenControllerStateTest();
83 
84   static const char* GetStateString(State state);
85   static const char* GetEventString(Event event);
86 
87   // Returns true if FullscreenController::WindowFullscreenStateChanged()
88   // will be called and re-enter FullscreenController before
89   // FullscreenController methods complete.
90   static bool IsWindowFullscreenStateChangedReentrant();
91 
92   // Returns true if |state| can be persistent. This is true for all of the
93   // states without "_TO_" in their name.
94   static bool IsPersistentState(State state);
95 
96   // Causes Fullscreen Controller to transition to an arbitrary state.
97   void TransitionToState(State state);
98 
99   // Makes one state change to approach |destination_state| via shortest path.
100   // Returns true if a state change is made.
101   // Repeated calls are needed to reach the destination.
102   bool TransitionAStepTowardState(State destination_state);
103 
104   // Calls FullscreenController::ChangeWindowFullscreenState if needed because
105   // a mock BrowserWindow is being used.
ChangeWindowFullscreenState()106   virtual void ChangeWindowFullscreenState() {}
107 
108   // Returns a description of the window's state, may return NULL.
109   // FullscreenControllerStateTest owns the returned pointer.
110   virtual const char* GetWindowStateString();
111 
112   // Causes the |event| to occur and return true on success.
113   virtual bool InvokeEvent(Event event);
114 
115   // Checks that window state matches the expected controller state.
116   virtual void VerifyWindowState();
117 
118   // Wait for NOTIFICATION_FULLSCREEN_CHANGED if a notification should have been
119   // sent in transitioning to |state_| from the previous persistent state.
120   void MaybeWaitForNotification();
121 
122   // Tests all states with all permutations of multiple events to detect
123   // lingering state issues that would bleed over to other states.
124   // I.E. for each state test all combinations of events E1, E2, E3.
125   //
126   // This produces coverage for event sequences that may happen normally but
127   // would not be exposed by traversing to each state via TransitionToState().
128   // TransitionToState() always takes the same path even when multiple paths
129   // exist.
130   void TestTransitionsForEachState();
131 
132   // Log transition_table_ to a string for debugging.
133   std::string GetTransitionTableAsString() const;
134   // Log state_transitions_ to a string for debugging.
135   std::string GetStateTransitionsAsString() const;
136 
137  protected:
138   // Set of enumerations (created with a helper macro) for _FALSE, _TRUE, and
139   // _NO_EXPECTATION values to be passed to VerifyWindowStateExpectations().
140   #define EXPECTATION_ENUM(enum_name, enum_prefix) \
141       enum enum_name { \
142         enum_prefix##_FALSE, \
143         enum_prefix##_TRUE, \
144         enum_prefix##_NO_EXPECTATION \
145       }
146   EXPECTATION_ENUM(FullscreenWithChromeExpectation, FULLSCREEN_WITH_CHROME);
147   EXPECTATION_ENUM(FullscreenWithoutChromeExpectation,
148                    FULLSCREEN_WITHOUT_CHROME);
149   EXPECTATION_ENUM(FullscreenForBrowserExpectation, FULLSCREEN_FOR_BROWSER);
150   EXPECTATION_ENUM(FullscreenForTabExpectation, FULLSCREEN_FOR_TAB);
151   EXPECTATION_ENUM(InMetroSnapExpectation, IN_METRO_SNAP);
152 
153   // Generated information about the transitions between states.
154   struct StateTransitionInfo {
StateTransitionInfoStateTransitionInfo155     StateTransitionInfo()
156         : event(EVENT_INVALID),
157           state(STATE_INVALID),
158           distance(NUM_STATES) {}
159     Event event;  // The |Event| that will cause the state transition.
160     State state;  // The adjacent |State| transitioned to; not the final state.
161     int distance;  // Steps to final state. NUM_STATES represents unknown.
162   };
163 
164   // Returns next transition info for shortest path from source to destination.
165   StateTransitionInfo NextTransitionInShortestPath(State source,
166                                                    State destination,
167                                                    int search_limit);
168 
169   // Returns a detailed log of what FullscreenControllerStateTest has done
170   // up to this point, to be reported when tests fail.
171   std::string GetAndClearDebugLog();
172 
173   // Returns true if the |state| & |event| pair should be skipped.
174   virtual bool ShouldSkipStateAndEventPair(State state, Event event);
175 
176   // Returns true if a test should be skipped entirely, e.g. due to platform.
177   virtual bool ShouldSkipTest(State state, Event event);
178 
179   // Runs one test of transitioning to a state and invoking an event.
180   virtual void TestStateAndEvent(State state, Event event);
181 
182   // Checks that window state matches the expected controller state.
183   virtual void VerifyWindowStateExpectations(
184       FullscreenWithChromeExpectation fullscreen_with_chrome,
185       FullscreenWithoutChromeExpectation fullscreen_without_chrome,
186       FullscreenForBrowserExpectation fullscreen_for_browser,
187       FullscreenForTabExpectation fullscreen_for_tab,
188       InMetroSnapExpectation in_metro_snap);
189 
190 
191   virtual Browser* GetBrowser() = 0;
192   FullscreenController* GetFullscreenController();
193 
194   // The state the FullscreenController is expected to be in.
state()195   State state() const { return state_; }
196 
197  private:
198   // The state the FullscreenController is expected to be in.
199   State state_;
200 
201   // The state when the previous NOTIFICATION_FULLSCREEN_CHANGED notification
202   // was received.
203   State last_notification_received_state_;
204 
205   // Listens for the NOTIFICATION_FULLSCREEN_CHANGED notification.
206   scoped_ptr<FullscreenNotificationObserver> fullscreen_notification_observer_;
207 
208   // Human defined |State| that results given each [state][event] pair.
209   State transition_table_[NUM_STATES][NUM_EVENTS];
210 
211   // Generated information about the transitions between states [from][to].
212   // View generated data with: out/Release/unit_tests
213   //     --gtest_filter="FullscreenController*DebugLogStateTables"
214   //     --gtest_also_run_disabled_tests
215   StateTransitionInfo state_transitions_[NUM_STATES][NUM_STATES];
216 
217   // Log of operations reported on errors via GetAndClearDebugLog().
218   std::ostringstream debugging_log_;
219 
220   DISALLOW_COPY_AND_ASSIGN(FullscreenControllerStateTest);
221 };
222 
223 #endif  // CHROME_BROWSER_UI_FULLSCREEN_FULLSCREEN_CONTROLLER_STATE_TEST_H_
224