1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_DISPLAY_DISPLAY_MANAGER_H_
#define ASH_DISPLAY_DISPLAY_MANAGER_H_
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "ash/ash_export.h"
#include "ash/display/display_info.h"
#include "ash/display/display_layout.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/gfx/display.h"
#if defined(OS_CHROMEOS)
#include "ui/display/chromeos/display_configurator.h"
#endif
namespace aura {
class Window;
}
namespace chromeos {
class DisplayNotificationsTest;
}
namespace gfx {
class Display;
class Insets;
class Rect;
class Screen;
}
namespace ash {
class AcceleratorControllerTest;
class DisplayLayoutStore;
class MouseWarpController;
class ScreenAsh;
typedef std::vector<DisplayInfo> DisplayInfoList;
namespace test {
class AshTestBase;
class DisplayManagerTestApi;
class SystemGestureEventFilterTest;
}
// DisplayManager maintains the current display configurations,
// and notifies observers when configuration changes.
//
// TODO(oshima): Make this non internal.
class ASH_EXPORT DisplayManager
#if defined(OS_CHROMEOS)
: public ui::DisplayConfigurator::SoftwareMirroringController
#endif
{
public:
class ASH_EXPORT Delegate {
public:
virtual ~Delegate() {}
// Create or updates the mirroring window with |display_info_list|.
virtual void CreateOrUpdateMirroringDisplay(
const DisplayInfoList& display_info_list) = 0;
// Closes the mirror window if not necessary.
virtual void CloseMirroringDisplayIfNotNecessary() = 0;
// Called before and after the display configuration changes.
// When |clear_focus| is true, the implementation should
// deactivate the active window and set the focus window to NULL.
virtual void PreDisplayConfigurationChange(bool clear_focus) = 0;
virtual void PostDisplayConfigurationChange() = 0;
};
// How the second display will be used.
// 1) EXTENDED mode extends the desktop to the second dislpay.
// 2) MIRRORING mode copies the content of the primary display to
// the 2nd display. (Software Mirroring).
// 3) UNIFIED mode creates single desktop across multiple displays.
enum MultiDisplayMode {
EXTENDED = 0,
MIRRORING,
UNIFIED,
};
// The display ID for a virtual display assigned to a unified desktop.
static int64_t kUnifiedDisplayId;
DisplayManager();
#if defined(OS_CHROMEOS)
~DisplayManager() override;
#else
virtual ~DisplayManager();
#endif
DisplayLayoutStore* layout_store() {
return layout_store_.get();
}
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
// When set to true, the DisplayManager calls OnDisplayMetricsChanged
// even if the display's bounds didn't change. Used to swap primary
// display.
void set_force_bounds_changed(bool force_bounds_changed) {
force_bounds_changed_ = force_bounds_changed;
}
// Returns the display id of the first display in the outupt list.
int64_t first_display_id() const { return first_display_id_; }
// Initializes displays using command line flag. Returns false
// if no command line flag was provided.
bool InitFromCommandLine();
// Initialize default display.
void InitDefaultDisplay();
// Initializes font related params that depends on display
// configuration.
void RefreshFontParams();
// Returns the display layout used for current displays.
const DisplayLayout& GetCurrentDisplayLayout() const;
// Returns the current display list.
DisplayIdList GetCurrentDisplayIdList() const;
// Sets the layout for the current display pair. The |layout| specifies
// the locaion of the displays relative to their parents.
void SetLayoutForCurrentDisplays(scoped_ptr<DisplayLayout> layout);
// Returns display for given |id|;
const gfx::Display& GetDisplayForId(int64_t id) const;
// Finds the display that contains |point| in screeen coordinates.
// Returns invalid display if there is no display that can satisfy
// the condition.
const gfx::Display& FindDisplayContainingPoint(
const gfx::Point& point_in_screen) const;
// Sets the work area's |insets| to the display given by |display_id|.
bool UpdateWorkAreaOfDisplay(int64_t display_id, const gfx::Insets& insets);
// Registers the overscan insets for the display of the specified ID. Note
// that the insets size should be specified in DIP size. It also triggers the
// display's bounds change.
void SetOverscanInsets(int64_t display_id, const gfx::Insets& insets_in_dip);
// Sets the display's rotation for the given |source|. The new |rotation| will
// also become active.
void SetDisplayRotation(int64_t display_id,
gfx::Display::Rotation rotation,
gfx::Display::RotationSource source);
// Sets the external display's configuration, including resolution change,
// ui-scale change, and device scale factor change. Returns true if it changes
// the display resolution so that the caller needs to show a notification in
// case the new resolution actually doesn't work.
bool SetDisplayMode(int64_t display_id, const DisplayMode& display_mode);
// Register per display properties. |overscan_insets| is NULL if
// the display has no custom overscan insets.
void RegisterDisplayProperty(int64_t display_id,
gfx::Display::Rotation rotation,
float ui_scale,
const gfx::Insets* overscan_insets,
const gfx::Size& resolution_in_pixels,
float device_scale_factor,
ui::ColorCalibrationProfile color_profile);
// Register stored rotation properties for the internal display.
void RegisterDisplayRotationProperties(bool rotation_lock,
gfx::Display::Rotation rotation);
// Returns the stored rotation lock preference if it has been loaded,
// otherwise false.
bool registered_internal_display_rotation_lock() const {
return registered_internal_display_rotation_lock_;
}
// Returns the stored rotation preference for the internal display if it has
// been loaded, otherwise |gfx::Display::Rotate_0|.
gfx::Display::Rotation registered_internal_display_rotation() const {
return registered_internal_display_rotation_;
}
// Returns the display mode of |display_id| which is currently used.
DisplayMode GetActiveModeForDisplayId(int64_t display_id) const;
// Returns the display's selected mode. This returns false and doesn't
// set |mode_out| if the display mode is in default.
bool GetSelectedModeForDisplayId(int64_t display_id,
DisplayMode* mode_out) const;
// Tells if the virtual resolution feature is enabled.
bool IsDisplayUIScalingEnabled() const;
// Returns the current overscan insets for the specified |display_id|.
// Returns an empty insets (0, 0, 0, 0) if no insets are specified for
// the display.
gfx::Insets GetOverscanInsets(int64_t display_id) const;
// Sets the color calibration of the display to |profile|.
void SetColorCalibrationProfile(int64_t display_id,
ui::ColorCalibrationProfile profile);
// Called when display configuration has changed. The new display
// configurations is passed as a vector of Display object, which
// contains each display's new infomration.
void OnNativeDisplaysChanged(
const std::vector<DisplayInfo>& display_info_list);
// Updates the internal display data and notifies observers about the changes.
void UpdateDisplaysWith(const std::vector<DisplayInfo>& display_info_list);
// Updates current displays using current |display_info_|.
void UpdateDisplays();
// Returns the display at |index|. The display at 0 is
// no longer considered "primary".
const gfx::Display& GetDisplayAt(size_t index) const;
const gfx::Display& GetPrimaryDisplayCandidate() const;
// Returns the logical number of displays. This returns 1
// when displays are mirrored.
size_t GetNumDisplays() const;
const DisplayList& active_display_list() const {
return active_display_list_;
}
// Returns true if the display specified by |display_id| is currently
// connected and active. (mirroring display isn't active, for example).
bool IsActiveDisplayId(int64_t display_id) const;
// Returns the number of connected displays. This returns 2
// when displays are mirrored.
size_t num_connected_displays() const { return num_connected_displays_; }
// Returns the mirroring status.
bool IsInMirrorMode() const;
int64_t mirroring_display_id() const { return mirroring_display_id_; }
const DisplayList& software_mirroring_display_list() const {
return software_mirroring_display_list_;
}
// Sets/gets if the unified desktop feature is enabled.
void SetUnifiedDesktopEnabled(bool enabled);
bool unified_desktop_enabled() const { return unified_desktop_enabled_; }
// Returns true if it's in unified desktop mode.
bool IsInUnifiedMode() const;
// Returns the display used for software mirrroring. Returns invalid
// display if not found.
const gfx::Display GetMirroringDisplayById(int64_t id) const;
// Retuns the display info associated with |display_id|.
const DisplayInfo& GetDisplayInfo(int64_t display_id) const;
// Returns the human-readable name for the display |id|.
std::string GetDisplayNameForId(int64_t id);
// Returns the display id that is capable of UI scaling. On device,
// this returns internal display's ID if its device scale factor is 2,
// or invalid ID if such internal display doesn't exist. On linux
// desktop, this returns the first display ID.
int64_t GetDisplayIdForUIScaling() const;
// Change the mirror mode.
void SetMirrorMode(bool mirrored);
// Used to emulate display change when run in a desktop environment instead
// of on a device.
void AddRemoveDisplay();
void ToggleDisplayScaleFactor();
// SoftwareMirroringController override:
#if defined(OS_CHROMEOS)
void SetSoftwareMirroring(bool enabled) override;
bool SoftwareMirroringEnabled() const override;
#endif
// Sets/gets default multi display mode.
void SetDefaultMultiDisplayModeForCurrentDisplays(MultiDisplayMode mode);
MultiDisplayMode current_default_multi_display_mode() const {
return current_default_multi_display_mode_;
}
// Sets multi display mode.
void SetMultiDisplayMode(MultiDisplayMode mode);
// Reconfigure display configuration using the same
// physical display. TODO(oshima): Refactor and move this
// impl to |SetDefaultMultiDisplayMode|.
void ReconfigureDisplays();
// Update the bounds of the display given by |display_id|.
bool UpdateDisplayBounds(int64_t display_id, const gfx::Rect& new_bounds);
// Creates mirror window asynchronously if the software mirror mode
// is enabled.
void CreateMirrorWindowAsyncIfAny();
// Creates a MouseWarpController for the current display
// configuration. |drag_source| is the window where dragging
// started, or nullptr otherwise.
scoped_ptr<MouseWarpController> CreateMouseWarpController(
aura::Window* drag_source) const;
// Create a screen instance to be used during shutdown.
void CreateScreenForShutdown() const;
// A unit test may change the internal display id (which never happens on
// a real device). This will update the mode list for internal display
// for this test scenario.
void UpdateInternalDisplayModeListForTest();
private:
FRIEND_TEST_ALL_PREFIXES(ExtendedDesktopTest, ConvertPoint);
FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, TestNativeDisplaysChanged);
FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest,
NativeDisplaysChangedAfterPrimaryChange);
FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, AutomaticOverscanInsets);
FRIEND_TEST_ALL_PREFIXES(DisplayManagerTest, Rotate);
friend class AcceleratorControllerTest;
friend class DisplayManagerTest;
friend class chromeos::DisplayNotificationsTest;
friend class test::AshTestBase;
friend class test::DisplayManagerTestApi;
friend class test::SystemGestureEventFilterTest;
typedef std::vector<DisplayInfo> DisplayInfoList;
bool software_mirroring_enabled() const {
return multi_display_mode_ == MIRRORING;
};
void set_change_display_upon_host_resize(bool value) {
change_display_upon_host_resize_ = value;
}
// Creates software mirroring display related information. The display
// used to mirror the content is removed from the |display_info_list|.
void CreateSoftwareMirroringDisplayInfo(DisplayInfoList* display_info_list);
gfx::Display* FindDisplayForId(int64_t id);
// Add the mirror display's display info if the software based
// mirroring is in use.
void AddMirrorDisplayInfoIfAny(DisplayInfoList* display_info_list);
// Inserts and update the DisplayInfo according to the overscan
// state. Note that The DisplayInfo stored in the |internal_display_info_|
// can be different from |new_info| (due to overscan state), so
// you must use |GetDisplayInfo| to get the correct DisplayInfo for
// a display.
void InsertAndUpdateDisplayInfo(const DisplayInfo& new_info);
// Called when the display info is updated through InsertAndUpdateDisplayInfo.
void OnDisplayInfoUpdated(const DisplayInfo& display_info);
// Creates a display object from the DisplayInfo for |display_id|.
gfx::Display CreateDisplayFromDisplayInfoById(int64_t display_id);
// Creates a display object from the DisplayInfo for |display_id| for
// mirroring. The size of the display will be scaled using |scale|
// with the offset using |origin|.
gfx::Display CreateMirroringDisplayFromDisplayInfoById(
int64_t display_id,
const gfx::Point& origin,
float scale);
// Updates the bounds of all non-primary displays in |display_list| and
// append the indices of displays updated to |updated_indices|.
// When the size of |display_list| equals 2, the bounds are updated using
// the layout registered for the display pair. For more than 2 displays,
// the bounds are updated using horizontal layout.
void UpdateNonPrimaryDisplayBoundsForLayout(
DisplayList* display_list,
std::vector<size_t>* updated_indices);
void CreateMirrorWindowIfAny();
void RunPendingTasksForTest();
// Applies the |layout| and updates the bounds of displays in |display_list|.
// |updated_ids| contains the ids for displays whose bounds have changed.
void ApplyDisplayLayout(const DisplayLayout& layout,
DisplayList* display_list,
std::vector<int64_t>* updated_ids);
// Apply the display placement to the display layout.
// Returns true if the display bounds has been updated.
bool ApplyDisplayPlacement(const DisplayPlacement& placement,
DisplayList* display_list);
Delegate* delegate_; // not owned.
scoped_ptr<ScreenAsh> screen_;
scoped_ptr<DisplayLayoutStore> layout_store_;
int64_t first_display_id_;
// List of current active displays.
DisplayList active_display_list_;
int num_connected_displays_;
bool force_bounds_changed_;
// The mapping from the display ID to its internal data.
std::map<int64_t, DisplayInfo> display_info_;
// Selected display modes for displays. Key is the displays' ID.
std::map<int64_t, DisplayMode> display_modes_;
// When set to true, the host window's resize event updates
// the display's size. This is set to true when running on
// desktop environment (for debugging) so that resizing the host
// window will update the display properly. This is set to false
// on device as well as during the unit tests.
bool change_display_upon_host_resize_;
MultiDisplayMode multi_display_mode_;
MultiDisplayMode current_default_multi_display_mode_;
int64_t mirroring_display_id_;
DisplayList software_mirroring_display_list_;
// User preference for rotation lock of the internal display.
bool registered_internal_display_rotation_lock_;
// User preference for the rotation of the internal display.
gfx::Display::Rotation registered_internal_display_rotation_;
bool unified_desktop_enabled_;
base::WeakPtrFactory<DisplayManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DisplayManager);
};
} // namespace ash
#endif // ASH_DISPLAY_DISPLAY_MANAGER_H_
|