Home | History | Annotate | Download | only in fullscreen
      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,         // ToggleFullscreenMode()
     36     TOGGLE_FULLSCREEN_CHROME,  // ToggleFullscreenWithChrome()
     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.
    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 {
    155     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.
    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