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