Roll Clang 206824:209387
[chromium-blink-merge.git] / ash / display / display_change_observer_chromeos.cc
blob40a1a37500d9495a437946b634b291cc80ee4921
1 // Copyright 2013 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.
5 #include "ash/display/display_change_observer_chromeos.h"
7 #include <algorithm>
8 #include <map>
9 #include <set>
10 #include <vector>
12 #include "ash/ash_switches.h"
13 #include "ash/display/display_info.h"
14 #include "ash/display/display_layout_store.h"
15 #include "ash/display/display_manager.h"
16 #include "ash/shell.h"
17 #include "base/command_line.h"
18 #include "base/logging.h"
19 #include "grit/ash_strings.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "ui/compositor/dip_util.h"
22 #include "ui/display/types/chromeos/display_mode.h"
23 #include "ui/display/types/chromeos/display_snapshot.h"
24 #include "ui/display/util/display_util.h"
25 #include "ui/gfx/display.h"
27 namespace ash {
29 using ui::DisplayConfigurator;
31 namespace {
33 // Display mode list is sorted by (in descending priority):
34 // * the area in pixels.
35 // * refresh rate.
36 struct DisplayModeSorter {
37 bool operator()(const DisplayMode& a, const DisplayMode& b) {
38 if (a.size.GetArea() == b.size.GetArea())
39 return (a.refresh_rate > b.refresh_rate);
40 return (a.size.GetArea() > b.size.GetArea());
44 } // namespace
46 // static
47 std::vector<DisplayMode> DisplayChangeObserver::GetDisplayModeList(
48 const DisplayConfigurator::DisplayState& output) {
49 typedef std::map<std::pair<int, int>, DisplayMode> DisplayModeMap;
50 DisplayModeMap display_mode_map;
52 for (std::vector<const ui::DisplayMode*>::const_iterator it =
53 output.display->modes().begin();
54 it != output.display->modes().end();
55 ++it) {
56 const ui::DisplayMode& mode_info = **it;
57 const std::pair<int, int> size(mode_info.size().width(),
58 mode_info.size().height());
59 const DisplayMode display_mode(mode_info.size(),
60 mode_info.refresh_rate(),
61 mode_info.is_interlaced(),
62 output.display->native_mode() == *it);
64 // Add the display mode if it isn't already present and override interlaced
65 // display modes with non-interlaced ones.
66 DisplayModeMap::iterator display_mode_it = display_mode_map.find(size);
67 if (display_mode_it == display_mode_map.end())
68 display_mode_map.insert(std::make_pair(size, display_mode));
69 else if (display_mode_it->second.interlaced && !display_mode.interlaced)
70 display_mode_it->second = display_mode;
73 std::vector<DisplayMode> display_mode_list;
74 for (DisplayModeMap::const_iterator iter = display_mode_map.begin();
75 iter != display_mode_map.end();
76 ++iter) {
77 display_mode_list.push_back(iter->second);
79 std::sort(
80 display_mode_list.begin(), display_mode_list.end(), DisplayModeSorter());
81 return display_mode_list;
84 DisplayChangeObserver::DisplayChangeObserver() {
85 Shell::GetInstance()->AddShellObserver(this);
88 DisplayChangeObserver::~DisplayChangeObserver() {
89 Shell::GetInstance()->RemoveShellObserver(this);
92 ui::MultipleDisplayState DisplayChangeObserver::GetStateForDisplayIds(
93 const std::vector<int64>& display_ids) const {
94 CHECK_EQ(2U, display_ids.size());
95 DisplayIdPair pair = std::make_pair(display_ids[0], display_ids[1]);
96 DisplayLayout layout = Shell::GetInstance()->display_manager()->
97 layout_store()->GetRegisteredDisplayLayout(pair);
98 return layout.mirrored ? ui::MULTIPLE_DISPLAY_STATE_DUAL_MIRROR :
99 ui::MULTIPLE_DISPLAY_STATE_DUAL_EXTENDED;
102 bool DisplayChangeObserver::GetResolutionForDisplayId(int64 display_id,
103 gfx::Size* size) const {
104 DisplayMode mode;
105 if (!Shell::GetInstance()->display_manager()->GetSelectedModeForDisplayId(
106 display_id, &mode))
107 return false;
109 *size = mode.size;
110 return true;
113 void DisplayChangeObserver::OnDisplayModeChanged(
114 const std::vector<DisplayConfigurator::DisplayState>& display_states) {
115 std::vector<DisplayInfo> displays;
116 std::set<int64> ids;
117 for (size_t i = 0; i < display_states.size(); ++i) {
118 const DisplayConfigurator::DisplayState& state = display_states[i];
120 if (state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL &&
121 gfx::Display::InternalDisplayId() == gfx::Display::kInvalidDisplayID) {
122 gfx::Display::SetInternalDisplayId(state.display->display_id());
125 const ui::DisplayMode* mode_info = state.display->current_mode();
126 if (!mode_info)
127 continue;
129 float device_scale_factor = ui::GetScaleFactor(
130 state.display->physical_size(), mode_info->size());
131 gfx::Rect display_bounds(state.display->origin(), mode_info->size());
133 std::vector<DisplayMode> display_modes = GetDisplayModeList(state);
135 std::string name =
136 state.display->type() == ui::DISPLAY_CONNECTION_TYPE_INTERNAL ?
137 l10n_util::GetStringUTF8(IDS_ASH_INTERNAL_DISPLAY_NAME) :
138 state.display->display_name();
139 if (name.empty())
140 name = l10n_util::GetStringUTF8(IDS_ASH_STATUS_TRAY_UNKNOWN_DISPLAY_NAME);
142 bool has_overscan = state.display->has_overscan();
143 int64 id = state.display->display_id();
144 ids.insert(id);
146 displays.push_back(DisplayInfo(id, name, has_overscan));
147 DisplayInfo& new_info = displays.back();
148 new_info.set_device_scale_factor(device_scale_factor);
149 new_info.SetBounds(display_bounds);
150 new_info.set_native(true);
151 new_info.set_display_modes(display_modes);
152 new_info.set_touch_support(state.touch_device_id == 0 ?
153 gfx::Display::TOUCH_SUPPORT_UNAVAILABLE :
154 gfx::Display::TOUCH_SUPPORT_AVAILABLE);
155 new_info.set_touch_device_id(state.touch_device_id);
156 new_info.set_available_color_profiles(
157 Shell::GetInstance()
158 ->display_configurator()
159 ->GetAvailableColorCalibrationProfiles(id));
162 // DisplayManager can be null during the boot.
163 Shell::GetInstance()->display_manager()->OnNativeDisplaysChanged(displays);
166 void DisplayChangeObserver::OnAppTerminating() {
167 #if defined(USE_ASH)
168 // Stop handling display configuration events once the shutdown
169 // process starts. crbug.com/177014.
170 Shell::GetInstance()->display_configurator()->PrepareForExit();
171 #endif
174 } // namespace ash