Home | History | Annotate | Download | only in display
      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_DISPLAY_DISPLAY_MANAGER_H_
      6 #define ASH_DISPLAY_DISPLAY_MANAGER_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "ash/ash_export.h"
     12 #include "ash/display/display_info.h"
     13 #include "ash/display/display_layout.h"
     14 #include "base/compiler_specific.h"
     15 #include "base/gtest_prod_util.h"
     16 #include "base/memory/scoped_ptr.h"
     17 #include "ui/gfx/display.h"
     18 
     19 #if defined(OS_CHROMEOS)
     20 #include "chromeos/display/output_configurator.h"
     21 #endif
     22 
     23 namespace gfx {
     24 class Display;
     25 class Insets;
     26 class Rect;
     27 }
     28 
     29 namespace ash {
     30 class AcceleratorControllerTest;
     31 class DisplayController;
     32 
     33 namespace test {
     34 class DisplayManagerTestApi;
     35 class SystemGestureEventFilterTest;
     36 }
     37 namespace internal {
     38 class DisplayLayoutStore;
     39 
     40 // DisplayManager maintains the current display configurations,
     41 // and notifies observers when configuration changes.
     42 //
     43 // TODO(oshima): Make this non internal.
     44 class ASH_EXPORT DisplayManager
     45 #if defined(OS_CHROMEOS)
     46     : public chromeos::OutputConfigurator::SoftwareMirroringController
     47 #endif
     48       {
     49  public:
     50   class ASH_EXPORT Delegate {
     51    public:
     52     virtual ~Delegate() {}
     53 
     54     // Create or updates the non desktop window with |display_info|.
     55     virtual void CreateOrUpdateNonDesktopDisplay(
     56         const DisplayInfo& display_info) = 0;
     57 
     58     // Closes the mirror window if exists.
     59     virtual void CloseNonDesktopDisplay() = 0;
     60 
     61     // Called before and after the display configuration changes.
     62     // When |clear_focus| is true, the implementation should
     63     // deactivate the active window and set the focus window to NULL.
     64     virtual void PreDisplayConfigurationChange(bool clear_focus) = 0;
     65     virtual void PostDisplayConfigurationChange() = 0;
     66   };
     67 
     68   // How the second display will be used.
     69   // 1) EXTENDED mode extends the desktop to the second dislpay.
     70   // 2) MIRRORING mode copies the content of the primary display to
     71   //    the 2nd display. (Software Mirroring).
     72   // 3) In VIRTUAL_KEYBOARD mode, the 2nd display is used as a
     73   //    dedicated display for virtual keyboard, and it is not
     74   //    recognized as a part of desktop.
     75   enum SecondDisplayMode {
     76     EXTENDED,
     77     MIRRORING,
     78     VIRTUAL_KEYBOARD
     79   };
     80 
     81   // Returns the list of possible UI scales for the display.
     82   static std::vector<float> GetScalesForDisplay(const DisplayInfo& info);
     83 
     84   // Returns next valid UI scale.
     85   static float GetNextUIScale(const DisplayInfo& info, bool up);
     86 
     87   // Updates the bounds of the display given by |secondary_display_id|
     88   // according to |layout|.
     89   static void UpdateDisplayBoundsForLayoutById(
     90       const DisplayLayout& layout,
     91       const gfx::Display& primary_display,
     92       int64 secondary_display_id);
     93 
     94   DisplayManager();
     95   virtual ~DisplayManager();
     96 
     97   DisplayLayoutStore* layout_store() {
     98     return layout_store_.get();
     99   }
    100 
    101   void set_delegate(Delegate* delegate) { delegate_ = delegate; }
    102 
    103   // When set to true, the MonitorManager calls OnDisplayBoundsChanged
    104   // even if the display's bounds didn't change. Used to swap primary
    105   // display.
    106   void set_force_bounds_changed(bool force_bounds_changed) {
    107     force_bounds_changed_ = force_bounds_changed;
    108   }
    109 
    110   // Returns the display id of the first display in the outupt list.
    111   int64 first_display_id() const { return first_display_id_; }
    112 
    113   // Initializes displays using command line flag. Returns false
    114   // if no command line flag was provided.
    115   bool InitFromCommandLine();
    116 
    117   // Initialize default display.
    118   void InitDefaultDisplay();
    119 
    120   // True if the given |display| is currently connected.
    121   bool IsActiveDisplay(const gfx::Display& display) const;
    122 
    123   // True if there is an internal display.
    124   bool HasInternalDisplay() const;
    125 
    126   bool IsInternalDisplayId(int64 id) const;
    127 
    128   // Returns the display layout used for current displays.
    129   DisplayLayout GetCurrentDisplayLayout();
    130 
    131   // Returns the current display pair.
    132   DisplayIdPair GetCurrentDisplayIdPair() const;
    133 
    134   // Sets the layout for the current display pair. The |layout| specifies
    135   // the locaion of the secondary display relative to the primary.
    136   void SetLayoutForCurrentDisplays(
    137       const DisplayLayout& layout_relative_to_primary);
    138 
    139   // Returns display for given |id|;
    140   const gfx::Display& GetDisplayForId(int64 id) const;
    141 
    142   // Finds the display that contains |point| in screeen coordinates.
    143   // Returns invalid display if there is no display that can satisfy
    144   // the condition.
    145   const gfx::Display& FindDisplayContainingPoint(
    146       const gfx::Point& point_in_screen) const;
    147 
    148   // Sets the work area's |insets| to the display given by |display_id|.
    149   bool UpdateWorkAreaOfDisplay(int64 display_id, const gfx::Insets& insets);
    150 
    151   // Registers the overscan insets for the display of the specified ID. Note
    152   // that the insets size should be specified in DIP size. It also triggers the
    153   // display's bounds change.
    154   void SetOverscanInsets(int64 display_id, const gfx::Insets& insets_in_dip);
    155 
    156   // Sets the display's rotation.
    157   void SetDisplayRotation(int64 display_id, gfx::Display::Rotation rotation);
    158 
    159   // Sets the display's ui scale.
    160   void SetDisplayUIScale(int64 display_id, float ui_scale);
    161 
    162   // Sets the display's resolution.
    163   void SetDisplayResolution(int64 display_id, const gfx::Size& resolution);
    164 
    165   // Register per display properties. |overscan_insets| is NULL if
    166   // the display has no custom overscan insets.
    167   void RegisterDisplayProperty(int64 display_id,
    168                                gfx::Display::Rotation rotation,
    169                                float ui_scale,
    170                                const gfx::Insets* overscan_insets,
    171                                const gfx::Size& resolution_in_pixels);
    172 
    173   // Returns the display's selected resolution.
    174   bool GetSelectedResolutionForDisplayId(int64 display_id,
    175                                          gfx::Size* resolution_out) const;
    176 
    177   // Tells if the virtual resolution feature is enabled.
    178   bool IsDisplayUIScalingEnabled() const;
    179 
    180   // Returns the current overscan insets for the specified |display_id|.
    181   // Returns an empty insets (0, 0, 0, 0) if no insets are specified for
    182   // the display.
    183   gfx::Insets GetOverscanInsets(int64 display_id) const;
    184 
    185   // Called when display configuration has changed. The new display
    186   // configurations is passed as a vector of Display object, which
    187   // contains each display's new infomration.
    188   void OnNativeDisplaysChanged(
    189       const std::vector<DisplayInfo>& display_info_list);
    190 
    191   // Updates the internal display data and notifies observers about the changes.
    192   void UpdateDisplays(const std::vector<DisplayInfo>& display_info_list);
    193 
    194   // Updates current displays using current |display_info_|.
    195   void UpdateDisplays();
    196 
    197   // Returns the display at |index|. The display at 0 is
    198   // no longer considered "primary".
    199   const gfx::Display& GetDisplayAt(size_t index) const;
    200 
    201   const gfx::Display& GetPrimaryDisplayCandidate() const;
    202 
    203   // Returns the logical number of displays. This returns 1
    204   // when displays are mirrored.
    205   size_t GetNumDisplays() const;
    206 
    207   const std::vector<gfx::Display>& displays() const { return displays_; }
    208 
    209   // Returns the number of connected displays. This returns 2
    210   // when displays are mirrored.
    211   size_t num_connected_displays() const { return num_connected_displays_; }
    212 
    213   // Returns the mirroring status.
    214   bool IsMirrored() const;
    215   int64 mirrored_display_id() const { return mirrored_display_id_; }
    216 
    217   // Returns the display object that is not a part of desktop.
    218   const gfx::Display& non_desktop_display() const {
    219     return non_desktop_display_;
    220   }
    221 
    222   // Retuns the display info associated with |display_id|.
    223   const DisplayInfo& GetDisplayInfo(int64 display_id) const;
    224 
    225   // Returns the human-readable name for the display |id|.
    226   std::string GetDisplayNameForId(int64 id);
    227 
    228   // Returns the display id that is capable of UI scaling. On device,
    229   // this returns internal display's ID if its device scale factor is 2,
    230   // or invalid ID if such internal display doesn't exist. On linux
    231   // desktop, this returns the first display ID.
    232   int64 GetDisplayIdForUIScaling() const;
    233 
    234   // Change the mirror mode.
    235   void SetMirrorMode(bool mirrored);
    236 
    237   // Used to emulate display change when run in a desktop environment instead
    238   // of on a device.
    239   void AddRemoveDisplay();
    240   void ToggleDisplayScaleFactor();
    241 
    242   // SoftwareMirroringController override:
    243 #if defined(OS_CHROMEOS)
    244   virtual void SetSoftwareMirroring(bool enabled) OVERRIDE;
    245 #endif
    246   bool software_mirroring_enabled() const {
    247     return second_display_mode_ == MIRRORING;
    248   };
    249 
    250   bool virtual_keyboard_root_window_enabled() const {
    251     return second_display_mode_ == VIRTUAL_KEYBOARD;
    252   };
    253 
    254   // Sets/gets second display mode.
    255   void SetSecondDisplayMode(SecondDisplayMode mode);
    256   SecondDisplayMode second_display_mode() const {
    257     return second_display_mode_;
    258   }
    259 
    260   // Update the bounds of the display given by |display_id|.
    261   bool UpdateDisplayBounds(int64 display_id,
    262                            const gfx::Rect& new_bounds);
    263 
    264   // Creates mirror window if the software mirror mode is enabled.
    265   // This is used only for bootstrap.
    266   void CreateMirrorWindowIfAny();
    267 
    268 private:
    269   FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint);
    270   FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged);
    271   FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest,
    272                            NativeDisplaysChangedAfterPrimaryChange);
    273   FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, AutomaticOverscanInsets);
    274   friend class ash::AcceleratorControllerTest;
    275   friend class test::DisplayManagerTestApi;
    276   friend class test::SystemGestureEventFilterTest;
    277   friend class DisplayManagerTest;
    278 
    279   typedef std::vector<gfx::Display> DisplayList;
    280 
    281   void set_change_display_upon_host_resize(bool value) {
    282     change_display_upon_host_resize_ = value;
    283   }
    284 
    285   gfx::Display* FindDisplayForId(int64 id);
    286 
    287   // Add the mirror display's display info if the software based
    288   // mirroring is in use.
    289   void AddMirrorDisplayInfoIfAny(std::vector<DisplayInfo>* display_info_list);
    290 
    291   // Inserts and update the DisplayInfo according to the overscan
    292   // state. Note that The DisplayInfo stored in the |internal_display_info_|
    293   // can be different from |new_info| (due to overscan state), so
    294   // you must use |GetDisplayInfo| to get the correct DisplayInfo for
    295   // a display.
    296   void InsertAndUpdateDisplayInfo(const DisplayInfo& new_info);
    297 
    298   // Creates a display object from the DisplayInfo for |display_id|.
    299   gfx::Display CreateDisplayFromDisplayInfoById(int64 display_id);
    300 
    301   // Updates the bounds of the secondary display in |display_list|
    302   // using the layout registered for the display pair and set the
    303   // index of display updated to |updated_index|. Returns true
    304   // if the secondary display's bounds has been changed from current
    305   // value, or false otherwise.
    306   bool UpdateSecondaryDisplayBoundsForLayout(DisplayList* display_list,
    307                                              size_t* updated_index) const;
    308 
    309   static void UpdateDisplayBoundsForLayout(
    310       const DisplayLayout& layout,
    311       const gfx::Display& primary_display,
    312       gfx::Display* secondary_display);
    313 
    314   Delegate* delegate_;  // not owned.
    315 
    316   scoped_ptr<DisplayLayoutStore> layout_store_;
    317 
    318   int64 first_display_id_;
    319 
    320   // List of current active displays.
    321   DisplayList displays_;
    322 
    323   int num_connected_displays_;
    324 
    325   bool force_bounds_changed_;
    326 
    327   // The mapping from the display ID to its internal data.
    328   std::map<int64, DisplayInfo> display_info_;
    329 
    330   // Selected resolutions for displays. Key is the displays' ID.
    331   std::map<int64, gfx::Size> resolutions_;
    332 
    333   // When set to true, the host window's resize event updates
    334   // the display's size. This is set to true when running on
    335   // desktop environment (for debugging) so that resizing the host
    336   // window will update the display properly. This is set to false
    337   // on device as well as during the unit tests.
    338   bool change_display_upon_host_resize_;
    339 
    340   SecondDisplayMode second_display_mode_;
    341   int64 mirrored_display_id_;
    342   gfx::Display non_desktop_display_;
    343 
    344   DISALLOW_COPY_AND_ASSIGN(DisplayManager);
    345 };
    346 
    347 }  // namespace internal
    348 }  // namespace ash
    349 
    350 #endif  // ASH_DISPLAY_DISPLAY_MANAGER_H_
    351